Bug 1591776 - Add downloads taskbar progress support for gtk3 to SeaMonkey. r=IanN a=IanN
authorFrank-Rainer Grahl <frgrahl@gmx.net>
Wed, 30 Oct 2019 19:28:00 +0100
changeset 32348 8c7fdc016b74e79aeba1369264ea09f4f955ab12
parent 32347 796708756db3d8c1779b88059a14340af1fa73f6
child 32349 657fd8bb6fac578f356626d4ffb25344e86c6bf6
push id225
push userfrgrahl@gmx.net
push dateWed, 30 Oct 2019 18:44:45 +0000
treeherdercomm-esr60@4f5c19b9a6b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersIanN, IanN
bugs1591776
Bug 1591776 - Add downloads taskbar progress support for gtk3 to SeaMonkey. r=IanN a=IanN
suite/components/downloads/DownloadsTaskbar.jsm
--- a/suite/components/downloads/DownloadsTaskbar.jsm
+++ b/suite/components/downloads/DownloadsTaskbar.jsm
@@ -25,16 +25,22 @@ XPCOMUtils.defineLazyGetter(this, "gWinT
 });
 
 XPCOMUtils.defineLazyGetter(this, "gMacTaskbarProgress", function() {
   return ("@mozilla.org/widget/macdocksupport;1" in Cc) &&
          Cc["@mozilla.org/widget/macdocksupport;1"]
            .getService(Ci.nsITaskbarProgress);
 });
 
+XPCOMUtils.defineLazyGetter(this, "gGtkTaskbarProgress", function() {
+  return ("@mozilla.org/widget/taskbarprogress/gtk;1" in Cc) &&
+         Cc["@mozilla.org/widget/taskbarprogress/gtk;1"]
+           .getService(Ci.nsIGtkTaskbarProgress);
+});
+
 // DownloadsTaskbar
 
 /**
  * Handles the download progress indicator in the taskbar.
  */
 var DownloadsTaskbar = {
   /**
    * Underlying DownloadSummary providing the aggregate download information, or
@@ -70,23 +76,21 @@ var DownloadsTaskbar = {
       if (gMacTaskbarProgress) {
         // On Mac OS X, we have to register the global indicator only once.
         this._taskbarProgress = gMacTaskbarProgress;
         // Free the XPCOM reference on shutdown, to prevent detecting a leak.
         Services.obs.addObserver(() => {
           this._taskbarProgress = null;
           gMacTaskbarProgress = null;
         }, "quit-application-granted");
-      } else if (gWinTaskbar) {
+      } else {
         // On Windows, the indicator is currently hidden because we have no
         // previous window, thus we should attach the indicator now.
+        // In gtk3, the window itself implements the progress interface.
         this.attachIndicator(aWindow);
-      } else {
-        // The taskbar indicator is not available on this platform.
-        return;
       }
     }
 
     // Ensure that the DownloadSummary object will be created asynchronously.
     if (!this._summary) {
       Downloads.getSummary(Downloads.ALL).then(summary => {
         // In case the method is re-entered, we simply ignore redundant
         // invocations of the callback, instead of keeping separate state.
@@ -95,60 +99,72 @@ var DownloadsTaskbar = {
         }
         this._summary = summary;
         return this._summary.addView(this);
       }).catch(Cu.reportError);
     }
   },
 
   /**
-   * On Windows, attaches the taskbar indicator to the specified window.
+   * On Windows and linux attach the taskbar indicator to the specified window.
    */
   attachIndicator(aWindow) {
     // If there is already a taskbarProgress this usually means the download
     //  manager became active. So clear the taskbar state first.
     if (this._taskbarProgress) {
       this._taskbarProgress.setProgressState(Ci.nsITaskbarProgress.STATE_NO_PROGRESS);
     }
 
-    // Activate the indicator on the specified window.
-    let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIWebNavigation)
-                          .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
-                          .QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIXULWindow).docShell;
-    this._taskbarProgress = gWinTaskbar.getTaskbarProgress(docShell);
+    if (gWinTaskbar) {
+      // Activate the indicator on the specified window.
+      let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                            .getInterface(Ci.nsIWebNavigation)
+                            .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
+                            .QueryInterface(Ci.nsIInterfaceRequestor)
+                            .getInterface(Ci.nsIXULWindow).docShell;
+      this._taskbarProgress = gWinTaskbar.getTaskbarProgress(docShell);
+    } else if (gGtkTaskbarProgress) {
+      // In gtk3, the window itself implements the progress interface.
+      if (!this._taskbarProgress) {
+        this._taskbarProgress = gGtkTaskbarProgress;
+      }
+
+      this._taskbarProgress.setPrimaryWindow(aWindow);
+    } else {
+      // macOS, not gtk3 or unsupported OS.
+      return;
+    }
 
     // If the DownloadSummary object has already been created, we should update
     // the state of the new indicator, otherwise it will be updated as soon as
     // the DownloadSummary view is registered.
     if (this._summary) {
       this.onSummaryChanged();
     }
 
     aWindow.addEventListener("unload", () => {
       let windows = Services.wm.getEnumerator(null);
       let newActiveWindow = null;
       if (windows.hasMoreElements()) {
         newActiveWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
       }
       if (newActiveWindow) {
-        // Move the progress indicator to the other browser window.
-        this.attachIndicator(newActiveWindow, false);
+        // Move the progress indicator to the other window.
+        this.attachIndicator(newActiveWindow);
       } else {
         // The last window has been closed. We remove the reference to
         // the taskbar progress object.
         this._taskbarProgress = null;
       }
     });
   },
 
   // DownloadSummary view
   onSummaryChanged() {
-    // If the last browser window has been closed, we have no indicator any more.
+    // If the last window has been closed, we have no indicator any more.
     if (!this._taskbarProgress) {
       return;
     }
 
     if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) {
       this._taskbarProgress.setProgressState(
                                Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0);
     } else {