~jbicha/ubuntu/oneiric/gnome-shell/oneiric-3.2.2.1

« back to all changes in this revision

Viewing changes to js/ui/notificationDaemon.js

  • Committer: Jeremy Bicha
  • Date: 2012-01-23 20:36:27 UTC
  • mfrom: (1.1.35)
  • Revision ID: jbicha@ubuntu.com-20120123203627-6m4m2cvzf9d2y7nd
* New upstream release
  - Fix broken gnome-shell-extension-tool (LP: #853882)
  - Fixes lots of crashes and some memory leaks
  - extensions.gnome.org should now work with Webkit-based browsers
* Split common files and translations to gnome-shell-common. Add
  appropriate Breaks/Replaces.
* 02_rpath-bluetooth-applet.patch:
  - Add an RPATH so that the compilation doesn't fail when g-ir-scanner
    tries to analyze libgnome-shell.so linked against
* 04_remove-glx-dependency-on-armel.patch: Refactored
* 07-NetworkMenu-fix-logic-for-updating-wifi-icon.patch
  - Fix the logic for connecting to the current wifi strength,
    prevents the network icon from becoming stale (from upstream git)
* 08-polkit-Find-the-best-user-to-authenticate-as.patch:
  - When picking a user to authenticate with, try the current user
    first, then root and if all else fails the first user that is allowed to
    authenticate. (from upstream git)
* 09-respect-NoDisplay-semantics-for-app-menu.patch:
  - Respect NoDisplay semantics for applications menu. This avoids duplicate
    menu entries when menu-xdg is installed. Closes: #649559
* 10-bluetooth-fix-connection-from-gs-menu.patch:
  - Fix bluetooth panel switch moving independently from actual
    connection status (LP: #918208)

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
    _init: function() {
93
93
        DBus.session.exportObject('/org/freedesktop/Notifications', this);
94
94
 
95
 
        this._sources = {};
 
95
        this._sources = [];
96
96
        this._senderToPid = {};
97
97
        this._notifications = {};
98
98
        this._busProxy = new Bus();
150
150
        }
151
151
    },
152
152
 
 
153
    _lookupSource: function(title, pid, trayIcon) {
 
154
        for (let i = 0; i < this._sources.length; i++) {
 
155
            let source = this._sources[i];
 
156
            if (source.pid == pid &&
 
157
                (source.initialTitle == title || source.trayIcon || trayIcon))
 
158
                return source;
 
159
        }
 
160
        return null;
 
161
    },
 
162
 
153
163
    // Returns the source associated with ndata.notification if it is set.
154
 
    // Otherwise, returns the source associated with the pid if one is
155
 
    // stored in this._sources and the notification is not transient.
156
 
    // Otherwise, creates a new source as long as pid is provided.
 
164
    // Otherwise, returns the source associated with the title and pid if
 
165
    // such source is stored in this._sources and the notification is not
 
166
    // transient. If the existing or requested source is associated with
 
167
    // a tray icon and passed in pid matches a pid of an existing source,
 
168
    // the title match is ignored to enable representing a tray icon and
 
169
    // notifications from the same application with a single source.
 
170
    //
 
171
    // If no existing source is found, a new source is created as long as
 
172
    // pid is provided.
157
173
    //
158
174
    // Either a pid or ndata.notification is needed to retrieve or
159
175
    // create a source.
160
 
    _getSource: function(title, pid, ndata, sender) {
 
176
    _getSource: function(title, pid, ndata, sender, trayIcon) {
161
177
        if (!pid && !(ndata && ndata.notification))
162
178
            return null;
163
179
 
174
190
        // with a transient one from the same sender, so we
175
191
        // always create a new source object for new transient notifications
176
192
        // and never add it to this._sources .
177
 
        if (!isForTransientNotification && this._sources[pid]) {
178
 
            let source = this._sources[pid];
179
 
            source.setTitle(title);
180
 
            return source;
 
193
        if (!isForTransientNotification) {
 
194
            let source = this._lookupSource(title, pid, trayIcon);
 
195
            if (source) {
 
196
                source.setTitle(title);
 
197
                return source;
 
198
            }
181
199
        }
182
200
 
183
 
        let source = new Source(title, pid, sender);
 
201
        let source = new Source(title, pid, sender, trayIcon);
184
202
        source.setTransient(isForTransientNotification);
185
203
 
186
204
        if (!isForTransientNotification) {
187
 
            this._sources[pid] = source;
 
205
            this._sources.push(source);
188
206
            source.connect('destroy', Lang.bind(this,
189
207
                function() {
190
 
                    delete this._sources[pid];
 
208
                    let index = this._sources.indexOf(source);
 
209
                    if (index >= 0)
 
210
                        this._sources.splice(index, 1);
191
211
                }));
192
212
        }
193
213
 
261
281
        let sender = DBus.getCurrentMessageContext().sender;
262
282
        let pid = this._senderToPid[sender];
263
283
 
264
 
        let source = this._getSource(appName, pid, ndata, sender);
 
284
        let source = this._getSource(appName, pid, ndata, sender, null);
265
285
 
266
286
        if (source) {
267
287
            this._notifyForSource(source, ndata);
282
302
                if (!ndata)
283
303
                    return;
284
304
 
285
 
                source = this._getSource(appName, pid, ndata, sender);
 
305
                source = this._getSource(appName, pid, ndata, sender, null);
286
306
 
287
307
                // We only store sender-pid entries for persistent sources.
288
308
                // Removing the entries once the source is destroyed
432
452
        if (!tracker.focus_app)
433
453
            return;
434
454
 
435
 
        for (let id in this._sources) {
436
 
            let source = this._sources[id];
 
455
        for (let i = 0; i < this._sources.length; i++) {
 
456
            let source = this._sources[i];
437
457
            if (source.app == tracker.focus_app) {
438
458
                source.destroyNonResidentNotifications();
439
459
                return;
456
476
    },
457
477
 
458
478
    _onTrayIconAdded: function(o, icon) {
459
 
        let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null, null);
460
 
        source.setTrayIcon(icon);
 
479
        let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null, null, icon);
461
480
    },
462
481
 
463
482
    _onTrayIconRemoved: function(o, icon) {
464
 
        let source = this._sources[icon.pid];
 
483
        let source = this._lookupSource(null, icon.pid, true);
465
484
        if (source)
466
485
            source.destroy();
467
486
    }
469
488
 
470
489
DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
471
490
 
472
 
function Source(title, pid, sender) {
473
 
    this._init(title, pid, sender);
 
491
function Source(title, pid, sender, trayIcon) {
 
492
    this._init(title, pid, sender, trayIcon);
474
493
}
475
494
 
476
495
Source.prototype = {
477
496
    __proto__:  MessageTray.Source.prototype,
478
497
 
479
 
    _init: function(title, pid, sender) {
 
498
    _init: function(title, pid, sender, trayIcon) {
480
499
        MessageTray.Source.prototype._init.call(this, title);
481
500
 
482
 
        this._pid = pid;
 
501
        this.initialTitle = title;
 
502
 
 
503
        this.pid = pid;
483
504
        if (sender)
484
505
            // TODO: dbus-glib implementation of watch_name() doesn’t return an id to be used for
485
506
            // unwatch_name() or implement unwatch_name(), however when we move to using GDBus implementation,
496
517
            this.title = this.app.get_name();
497
518
        else
498
519
            this.useNotificationIcon = true;
499
 
        this._trayIcon = null;
 
520
 
 
521
        this.trayIcon = trayIcon;
 
522
        if (this.trayIcon) {
 
523
           this._setSummaryIcon(this.trayIcon);
 
524
           this.useNotificationIcon = false;
 
525
        }
500
526
    },
501
527
 
502
528
    _onNameVanished: function() {
523
549
    },
524
550
 
525
551
    handleSummaryClick: function() {
526
 
        if (!this._trayIcon)
 
552
        if (!this.trayIcon)
527
553
            return false;
528
554
 
529
555
        let event = Clutter.get_current_event();
544
570
            let id = global.connect('notify::stage-input-mode', Lang.bind(this,
545
571
                function () {
546
572
                    global.disconnect(id);
547
 
                    this._trayIcon.click(event);
 
573
                    this.trayIcon.click(event);
548
574
                }));
549
575
            Main.overview.hide();
550
576
        } else {
551
 
            this._trayIcon.click(event);
 
577
            this.trayIcon.click(event);
552
578
        }
553
579
        return true;
554
580
    },
557
583
        if (this.app)
558
584
            return;
559
585
 
560
 
        this.app = Shell.WindowTracker.get_default().get_app_from_pid(this._pid);
 
586
        this.app = Shell.WindowTracker.get_default().get_app_from_pid(this.pid);
561
587
        if (!this.app)
562
588
            return;
563
589
 
564
590
        // Only override the icon if we were previously using
565
591
        // notification-based icons (ie, not a trayicon) or if it was unset before
566
 
        if (!this._trayIcon) {
 
592
        if (!this.trayIcon) {
567
593
            this.useNotificationIcon = false;
568
594
            this._setSummaryIcon(this.app.create_icon_texture (this.ICON_SIZE));
569
595
        }
570
596
    },
571
597
 
572
 
    setTrayIcon: function(icon) {
573
 
        this._setSummaryIcon(icon);
574
 
        this.useNotificationIcon = false;
575
 
        this._trayIcon = icon;
576
 
    },
577
 
 
578
598
    open: function(notification) {
579
599
        this.destroyNonResidentNotifications();
580
600
        this.openApp();
581
601
    },
582
602
 
583
603
    _lastNotificationRemoved: function() {
584
 
        if (!this._trayIcon)
 
604
        if (!this.trayIcon)
585
605
            this.destroy();
586
606
    },
587
607