-
Notifications
You must be signed in to change notification settings - Fork 462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial support for 'com.canonical.Unity.LauncherEntry' APIs #590
Changes from 10 commits
23d293d
93358fa
b67154f
0027f74
11113a2
b79ce26
52fa8b3
4f628f5
2bed1e1
b273d8c
5a370bb
8932f87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,14 @@ const GdkPixbuf = imports.gi.GdkPixbuf | |
const Gio = imports.gi.Gio; | ||
const GLib = imports.gi.GLib; | ||
const Gtk = imports.gi.Gtk; | ||
const Pango = imports.gi.Pango; | ||
const Signals = imports.signals; | ||
const Lang = imports.lang; | ||
const Meta = imports.gi.Meta; | ||
const Shell = imports.gi.Shell; | ||
const St = imports.gi.St; | ||
const Mainloop = imports.mainloop; | ||
const Cairo = imports.cairo; | ||
|
||
// Use __ () and N__() for the extension gettext domain, and reuse | ||
// the shell domain with the default _() and N_() | ||
|
@@ -99,6 +101,7 @@ var MyAppIcon = new Lang.Class({ | |
this.monitorIndex = monitorIndex; | ||
this._signalsHandler = new Utils.GlobalSignalsHandler(); | ||
this._nWindows = 0; | ||
this._remoteEntries = []; | ||
|
||
this.parent(app, iconParams); | ||
|
||
|
@@ -132,6 +135,8 @@ var MyAppIcon = new Lang.Class({ | |
} | ||
|
||
this._dots = null; | ||
this._progressOverlayArea = null; | ||
this._progress = 0; | ||
|
||
let keys = ['apply-custom-theme', | ||
'custom-theme-running-dots', | ||
|
@@ -156,6 +161,7 @@ var MyAppIcon = new Lang.Class({ | |
})); | ||
this._optionalScrollCycleWindows(); | ||
|
||
this._notificationBadge(); | ||
this._numberOverlay(); | ||
|
||
this._previewMenuManager = null; | ||
|
@@ -951,6 +957,169 @@ var MyAppIcon = new Lang.Class({ | |
cr.$dispose(); | ||
}, | ||
|
||
_notificationBadge: function() { | ||
this._notificationBadgeLabel = new St.Label(); | ||
this._notificationBadgeBin = new St.Bin({ | ||
child: this._notificationBadgeLabel, | ||
x_align: St.Align.END, y_align: St.Align.START, | ||
x_expand: true, y_expand: true | ||
}); | ||
this._notificationBadgeLabel.add_style_class_name('notification-badge'); | ||
this._notificationBadgeCount = 0; | ||
this._notificationBadgeBin.hide(); | ||
|
||
this._iconContainer.add_child(this._notificationBadgeBin); | ||
this._iconContainer.connect('allocation-changed', Lang.bind(this, this.updateNotificationBadge)); | ||
}, | ||
|
||
updateNotificationBadge: function() { | ||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||
let [minWidth, natWidth] = this._iconContainer.get_preferred_width(-1); | ||
let logicalNatWidth = natWidth / scaleFactor; | ||
let font_size = Math.max(10, Math.round(logicalNatWidth / 5)); | ||
let margin_left = Math.round(logicalNatWidth / 4); | ||
|
||
this._notificationBadgeLabel.set_style( | ||
'font-size: ' + font_size + 'px;' + | ||
'margin-left: ' + margin_left + 'px;' | ||
); | ||
|
||
this._notificationBadgeBin.width = Math.round(logicalNatWidth - margin_left); | ||
this._notificationBadgeLabel.clutter_text.ellipsize = Pango.EllipsizeMode.MIDDLE; | ||
}, | ||
|
||
_notificationBadgeCountToText: function(count) { | ||
if (count <= 9999) { | ||
return count.toString(); | ||
} else if (count < 1e5) { | ||
let thousands = count / 1e3; | ||
return thousands.toFixed(1).toString() + "k"; | ||
} else if (count < 1e6) { | ||
let thousands = count / 1e3; | ||
return thousands.toFixed(0).toString() + "k"; | ||
} else if (count < 1e8) { | ||
let millions = count / 1e6; | ||
return millions.toFixed(1).toString() + "M"; | ||
} else if (count < 1e9) { | ||
let millions = count / 1e6; | ||
return millions.toFixed(0).toString() + "M"; | ||
} else { | ||
let billions = count / 1e9; | ||
return billions.toFixed(1).toString() + "B"; | ||
} | ||
}, | ||
|
||
setNotificationBadge: function(count) { | ||
this._notificationBadgeCount = count; | ||
let text = this._notificationBadgeCountToText(count); | ||
this._notificationBadgeLabel.set_text(text); | ||
}, | ||
|
||
toggleNotificationBadge: function(activate) { | ||
if (activate && this._notificationBadgeCount > 0) { | ||
this.updateNotificationBadge(); | ||
this._notificationBadgeBin.show(); | ||
} | ||
else | ||
this._notificationBadgeBin.hide(); | ||
}, | ||
|
||
_showProgressOverlay: function() { | ||
if (this._progressOverlayArea) { | ||
this._updateProgressOverlay(); | ||
return; | ||
} | ||
|
||
this._progressOverlayArea = new St.DrawingArea({x_expand: true, y_expand: true}); | ||
this._progressOverlayArea.connect('repaint', Lang.bind(this, function() { | ||
this._drawProgressOverlay(this._progressOverlayArea); | ||
})); | ||
|
||
this._iconContainer.add_child(this._progressOverlayArea); | ||
this._updateProgressOverlay(); | ||
}, | ||
|
||
_hideProgressOverlay: function() { | ||
if (this._progressOverlayArea) | ||
this._progressOverlayArea.destroy(); | ||
this._progressOverlayArea = null; | ||
}, | ||
|
||
_updateProgressOverlay: function() { | ||
if (this._progressOverlayArea) | ||
this._progressOverlayArea.queue_repaint(); | ||
}, | ||
|
||
_drawProgressOverlay: function(area) { | ||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||
let [surfaceWidth, surfaceHeight] = area.get_surface_size(); | ||
let cr = area.get_context(); | ||
|
||
iconSize = this.icon.iconSize * scaleFactor; | ||
|
||
let x = Math.floor((surfaceWidth - iconSize) / 2); | ||
let y = Math.floor((surfaceHeight - iconSize) / 2); | ||
|
||
let lineWidth = Math.floor(1.0 * scaleFactor); | ||
let padding = Math.floor(iconSize * 0.05); | ||
let width = iconSize - 2.0*padding; | ||
let height = Math.floor(Math.min(18.0*scaleFactor, 0.20*iconSize)); | ||
x += padding; | ||
y += iconSize - height - padding; | ||
|
||
cr.setLineWidth(lineWidth); | ||
|
||
// Draw the outer stroke | ||
let stroke = new Cairo.LinearGradient(0, y, 0, y + height); | ||
let fill = null; | ||
stroke.addColorStopRGBA(0.5, 0.5, 0.5, 0.5, 0.1); | ||
stroke.addColorStopRGBA(0.9, 0.8, 0.8, 0.8, 0.4); | ||
Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, width, height, true, true, stroke, fill); | ||
|
||
// Draw the background | ||
x += lineWidth; | ||
y += lineWidth; | ||
width -= 2.0*lineWidth; | ||
height -= 2.0*lineWidth; | ||
|
||
stroke = Cairo.SolidPattern.createRGBA(0.20, 0.20, 0.20, 0.9); | ||
fill = new Cairo.LinearGradient(0, y, 0, y + height); | ||
fill.addColorStopRGBA(0.4, 0.25, 0.25, 0.25, 1.0); | ||
fill.addColorStopRGBA(0.9, 0.35, 0.35, 0.35, 1.0); | ||
Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, width, height, true, true, stroke, fill); | ||
|
||
// Draw the finished bar | ||
x += lineWidth; | ||
y += lineWidth; | ||
width -= 2.0*lineWidth; | ||
height -= 2.0*lineWidth; | ||
|
||
let finishedWidth = Math.ceil(this._progress * width); | ||
stroke = Cairo.SolidPattern.createRGBA(0.8, 0.8, 0.8, 1.0); | ||
fill = Cairo.SolidPattern.createRGBA(0.9, 0.9, 0.9, 1.0); | ||
|
||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) | ||
Utils.drawRoundedLine(cr, x + lineWidth/2.0 + width - finishedWidth, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill); | ||
else | ||
Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill); | ||
|
||
cr.$dispose(); | ||
}, | ||
|
||
setProgress: function(progress) { | ||
this._progress = Math.min(Math.max(progress, 0.0), 1.0); | ||
this._updateProgressOverlay(); | ||
}, | ||
|
||
toggleProgressOverlay: function(activate) { | ||
if (activate) { | ||
this._showProgressOverlay(); | ||
} | ||
else { | ||
this._hideProgressOverlay(); | ||
} | ||
}, | ||
|
||
_numberOverlay: function() { | ||
// Add label for a Hot-Key visual aid | ||
this._numberOverlayLabel = new St.Label(); | ||
|
@@ -1102,7 +1271,68 @@ var MyAppIcon = new Lang.Class({ | |
// nautilus desktop window. | ||
getInterestingWindows: function() { | ||
return getInterestingWindows(this.app, this._dtdSettings, this.monitorIndex); | ||
} | ||
}, | ||
|
||
insertEntryRemote: function(remote) { | ||
if (!remote || this._remoteEntries.includes(remote)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @azzar1 I used your new script (thanks!), and got this running on Gnome 3.22. This line is throwing an error for me, since Debian is still on mozJS 24. Perhaps we can change
|
||
return; | ||
|
||
this._remoteEntries.push(remote); | ||
this._selectEntryRemote(remote); | ||
}, | ||
|
||
removeEntryRemote: function(remote) { | ||
if (!remote || !this._remoteEntries.includes(remote)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. |
||
return; | ||
|
||
this._remoteEntries.splice(this._remoteEntries.indexOf(remote), 1); | ||
|
||
if (this._remoteEntries.length > 0) { | ||
this._selectEntryRemote(this._remoteEntries[this._remoteEntries.length-1]); | ||
} else { | ||
this.setNotificationBadge(0); | ||
this.toggleNotificationBadge(false); | ||
this.setProgress(0); | ||
this.toggleProgressOverlay(false); | ||
} | ||
}, | ||
|
||
_selectEntryRemote: function(remote) { | ||
if (!remote) | ||
return; | ||
|
||
this._signalsHandler.removeWithLabel('entry-remotes'); | ||
|
||
this._signalsHandler.addWithLabel('entry-remotes', [ | ||
remote, | ||
'count-changed', | ||
Lang.bind(this, (remote, value) => { | ||
this.setNotificationBadge(value); | ||
}) | ||
], [ | ||
remote, | ||
'count-visible-changed', | ||
Lang.bind(this, (remote, value) => { | ||
this.toggleNotificationBadge(value); | ||
}) | ||
], [remote, | ||
'progress-changed', | ||
Lang.bind(this, (remote, value) => { | ||
this.setProgress(value); | ||
}) | ||
], [ | ||
remote, | ||
'progress-visible-changed', | ||
Lang.bind(this, (remote, value) => { | ||
this.toggleProgressOverlay(value); | ||
}) | ||
]); | ||
|
||
this.setNotificationBadge(remote.count()); | ||
this.toggleNotificationBadge(remote.countVisible()); | ||
this.setProgress(remote.progress()); | ||
this.toggleProgressOverlay(remote.progressVisible()); | ||
}, | ||
}); | ||
/** | ||
* Extend AppIconMenu | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing
let
.