From 3008060ebb563a26f1d310bb0f1409d9d25ebc28 Mon Sep 17 00:00:00 2001 From: Betterbird Date: Mon, 16 Jan 2023 12:01:51 +0100 Subject: [PATCH] Feature: Minimise to tray for Linux. WIP. (Issue #111). --- .../12-feature-linux-minimise-to-tray.patch | 415 ++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 102/features/12-feature-linux-minimise-to-tray.patch diff --git a/102/features/12-feature-linux-minimise-to-tray.patch b/102/features/12-feature-linux-minimise-to-tray.patch new file mode 100644 index 00000000..9bcdbab0 --- /dev/null +++ b/102/features/12-feature-linux-minimise-to-tray.patch @@ -0,0 +1,415 @@ +# HG changeset patch +# User Betterbird +# Date 1673864379 -3600 +# Parent f951dbd93c25caa87d19124c3a6cd40111f47aab +Feature: Minimise to tray for Linux. + +Adapted from +https://hg.mozilla.org/comm-central/rev/d9c8e04388eb +and +https://hg.mozilla.org/comm-central/rev/0bc379dfb518 + +diff --git a/mail/app/profile/all-thunderbird.js b/mail/app/profile/all-thunderbird.js +--- a/mail/app/profile/all-thunderbird.js ++++ b/mail/app/profile/all-thunderbird.js +@@ -1285,17 +1285,17 @@ pref("toolkit.telemetry.updatePing.enabl + pref("toolkit.telemetry.bhrPing.enabled", true); + // Whether to enable Ecosystem Telemetry, requires a restart. + #ifdef NIGHTLY_BUILD + pref("toolkit.telemetry.ecosystemtelemetry.enabled", true); + #else + pref("toolkit.telemetry.ecosystemtelemetry.enabled", false); + #endif + +-#ifdef XP_WIN ++#if defined(XP_WIN) || defined(XP_UNIX) + pref("mail.minimizeToTray", false); + #endif + + pref("prompts.defaultModalType", 3); + pref("prompts.contentPromptSubDialog", false); + + // The URL for the privacy policy related to recommended extensions. + pref("extensions.recommendations.privacyPolicyUrl", "https://www.mozilla.org/en-US/privacy/thunderbird/#addons"); +diff --git a/mail/base/content/messenger.xhtml b/mail/base/content/messenger.xhtml +--- a/mail/base/content/messenger.xhtml ++++ b/mail/base/content/messenger.xhtml +@@ -157,17 +157,17 @@ + + + + + #ifdef XP_MACOSX + + + #endif +-#ifdef XP_WIN ++#if defined(XP_WIN) || defined(XP_UNIX) + + #endif + + + + + + +diff --git a/mail/base/content/minimizeToTray.js b/mail/base/content/minimizeToTray.js +--- a/mail/base/content/minimizeToTray.js ++++ b/mail/base/content/minimizeToTray.js +@@ -1,19 +1,23 @@ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at http://mozilla.org/MPL/2.0/. */ + + /* globals docShell, Services, windowState */ + ++var { AppConstants } = ChromeUtils.import( ++ "resource://gre/modules/AppConstants.jsm" ++); ++ + addEventListener("sizemodechange", () => { + if ( + windowState == window.STATE_MINIMIZED && + Services.prefs.getBoolPref("mail.minimizeToTray", false) + ) { + setTimeout(() => { + var bw = docShell.treeOwner.QueryInterface(Ci.nsIBaseWindow); + Cc["@mozilla.org/messenger/osintegration;1"] +- .getService(Ci.nsIMessengerWindowsIntegration) ++ .getService(AppConstants.platform == "win" ? Ci.nsIMessengerWindowsIntegration : Ci.nsIMessengerUnixIntegration) + .hideWindow(bw); + }); + } + }); +diff --git a/mail/base/jar.mn b/mail/base/jar.mn +--- a/mail/base/jar.mn ++++ b/mail/base/jar.mn +@@ -53,17 +53,17 @@ messenger.jar: + content/messenger/mailWindow.js (content/mailWindow.js) + content/messenger/mailWindowOverlay.js (content/mailWindowOverlay.js) + content/messenger/messageDisplay.js (content/messageDisplay.js) + content/messenger/messageWindow.js (content/messageWindow.js) + * content/messenger/messageWindow.xhtml (content/messageWindow.xhtml) + content/messenger/messenger-customization.js (content/messenger-customization.js) + * content/messenger/messenger.xhtml (content/messenger.xhtml) + content/messenger/webextensions.css (content/webextensions.css) +-#ifdef XP_WIN ++#if defined(XP_WIN) || defined(XP_UNIX) + content/messenger/minimizeToTray.js (content/minimizeToTray.js) + #endif + content/messenger/migrationProgress.js (content/migrationProgress.js) + content/messenger/migrationProgress.xhtml (content/migrationProgress.xhtml) + content/messenger/msgHdrView.js (content/msgHdrView.js) + content/messenger/msgMail3PaneWindow.js (content/msgMail3PaneWindow.js) + content/messenger/msgSecurityPane.js (content/msgSecurityPane.js) + content/messenger/msgViewNavigation.js (content/msgViewNavigation.js) +diff --git a/mail/components/preferences/general.inc.xhtml b/mail/components/preferences/general.inc.xhtml +--- a/mail/components/preferences/general.inc.xhtml ++++ b/mail/components/preferences/general.inc.xhtml +@@ -99,17 +99,17 @@ + unset-default-tooltip, + checkbox-email-label.label, + checkbox-newsgroups-label.label, + checkbox-feeds-label.label, + system-search-integration-label.label, + check-on-startup-label.label"/> + + +-#ifdef XP_WIN ++#if defined(XP_WIN) || defined(XP_UNIX) + + + + #endif + + sHiddenWindows; ++static uint32_t sLastUnreadCount; ++static nsAutoString sLastUnreadTooltip; ++static AppIndicator *ci = NULL; ++ ++using namespace mozilla; + + nsMessengerUnixIntegration::nsMessengerUnixIntegration() {} + +-NS_IMPL_ISUPPORTS(nsMessengerUnixIntegration, nsIMessengerOSIntegration) ++NS_IMPL_ADDREF(nsMessengerUnixIntegration) ++NS_IMPL_RELEASE(nsMessengerUnixIntegration) ++ ++NS_INTERFACE_MAP_BEGIN(nsMessengerUnixIntegration) ++ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMessengerOSIntegration) ++ NS_INTERFACE_MAP_ENTRY(nsIMessengerUnixIntegration) ++ NS_INTERFACE_MAP_ENTRY(nsIMessengerOSIntegration) ++NS_INTERFACE_MAP_END ++ ++static void activateWindow(mozIDOMWindowProxy* win) { ++ nsCOMPtr privateWindow = nsPIDOMWindowOuter::From(win); ++ privateWindow->Focus(mozilla::dom::CallerType::System); ++} ++ ++static void activated(void) { ++ // TODO: Somehow get this called when the user clicks the app indicator icon. ++ fprintf(stderr, "=== nsMessengerUnixIntegration static activated\n"); ++ nsresult rv; ++ nsCOMPtr prefBranch = ++ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); ++ NS_ENSURE_SUCCESS_VOID(rv); ++ bool showTrayIcon; ++ rv = prefBranch->GetBoolPref(SHOW_TRAY_ICON_PREF, &showTrayIcon); ++ NS_ENSURE_SUCCESS_VOID(rv); ++ bool showTrayIconAlways; ++ if (NS_FAILED(prefBranch->GetBoolPref(SHOW_TRAY_ICON_ALWAYS_PREF, ++ &showTrayIconAlways))) { ++ showTrayIconAlways = false; ++ } ++ if ((!showTrayIcon || !sLastUnreadCount) && !showTrayIconAlways) { ++ if (ci) { ++ app_indicator_set_status(ci, APP_INDICATOR_STATUS_PASSIVE); ++ } ++ } ++ ++ // No minimized window, bring the most recent 3pane window to the front. ++ if (sHiddenWindows.Length() == 0) { ++ nsCOMPtr windowMediator = ++ do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv); ++ NS_ENSURE_SUCCESS_VOID(rv); ++ ++ nsCOMPtr domWindow; ++ rv = windowMediator->GetMostRecentBrowserWindow( ++ getter_AddRefs(domWindow)); ++ NS_ENSURE_SUCCESS_VOID(rv); ++ if (domWindow) { ++ activateWindow(domWindow); ++ return; ++ } ++ } ++ ++ // Bring the minimized windows to the front. ++ for (uint32_t i = 0; i < sHiddenWindows.Length(); i++) { ++ auto window = sHiddenWindows.SafeElementAt(i); ++ if (!window) { ++ continue; ++ } ++ window->SetVisibility(true); ++ ++ nsCOMPtr widget; ++ window->GetMainWidget(getter_AddRefs(widget)); ++ if (!widget) { ++ continue; ++ } ++ // TODO: Do something with the `widget` or remove code above. ++ } ++ ++ sHiddenWindows.Clear(); ++} + + NS_IMETHODIMP + nsMessengerUnixIntegration::UpdateUnreadCount(uint32_t unreadCount, + const nsAString& unreadTooltip) { +- if (!mozilla::Preferences::GetBool("mail.biff.show_tray_icon", false)) return NS_OK; ++ sLastUnreadCount = unreadCount; ++ sLastUnreadTooltip = unreadTooltip; + +- static AppIndicator *ci = NULL; ++ if (!mozilla::Preferences::GetBool("mail.biff.show_tray_icon", false) && ++ sHiddenWindows.Length() == 0) return NS_OK; ++ + static char icon_path0[PATH_MAX + 100]; + static char icon_pathN[PATH_MAX + 100]; + + if (!ci) { + // Find icon absolute path. + size_t len = readlink("/proc/self/exe", icon_path0, PATH_MAX); + char* q = icon_path0 + len - 1; + while (*q != '/') q--; +@@ -42,25 +132,40 @@ nsMessengerUnixIntegration::UpdateUnread + // one but not the other. + app_indicator_set_title(ci, tooltip.get()); + app_indicator_set_tooltip_full(ci, + NULL /* icon */, tooltip.get() /* title */, NULL /* body */ + ); + app_indicator_set_icon_full(ci, icon_pathN, NULL); + app_indicator_set_status(ci, APP_INDICATOR_STATUS_ACTIVE); + } else { +- if (mozilla::Preferences::GetBool("mail.biff.show_tray_icon_always", false)) { ++ if (mozilla::Preferences::GetBool("mail.biff.show_tray_icon_always", false) || ++ sHiddenWindows.Length() > 0) { + app_indicator_set_title(ci, "Betterbird"); + app_indicator_set_tooltip_full(ci, + NULL /* icon */, "Betterbird" /* title */, NULL /* body */ + ); + app_indicator_set_icon_full(ci, icon_path0, NULL); + app_indicator_set_status(ci, APP_INDICATOR_STATUS_ACTIVE); + } else { + app_indicator_set_status(ci, APP_INDICATOR_STATUS_PASSIVE); + } + } + + return NS_OK; + } + + NS_IMETHODIMP + nsMessengerUnixIntegration::OnExit() { return NS_OK; } ++ ++nsresult nsMessengerUnixIntegration::HideWindow(nsIBaseWindow* aWindow) { ++ NS_ENSURE_ARG(aWindow); ++ aWindow->SetVisibility(false); ++ sHiddenWindows.AppendElement(aWindow); ++ UpdateUnreadCount(sLastUnreadCount, sLastUnreadTooltip); ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsMessengerUnixIntegration::ShowWindow(mozIDOMWindowProxy* aWindow) { ++ activateWindow(aWindow); ++ return NS_OK; ++} +diff --git a/mailnews/base/src/nsMessengerUnixIntegration.h b/mailnews/base/src/nsMessengerUnixIntegration.h +--- a/mailnews/base/src/nsMessengerUnixIntegration.h ++++ b/mailnews/base/src/nsMessengerUnixIntegration.h +@@ -1,22 +1,23 @@ + /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + #ifndef __nsMessengerUnixIntegration_h + #define __nsMessengerUnixIntegration_h + +-#include "nsIMessengerOSIntegration.h" ++#include "nsIMessengerUnixIntegration.h" + +-class nsMessengerUnixIntegration : public nsIMessengerOSIntegration { ++class nsMessengerUnixIntegration : public nsIMessengerUnixIntegration { + public: + nsMessengerUnixIntegration(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMESSENGEROSINTEGRATION ++ NS_DECL_NSIMESSENGERUNIXINTEGRATION + + private: + virtual ~nsMessengerUnixIntegration() {} + }; + + #endif // __nsMessengerUnixIntegration_h