Skip to content

Commit

Permalink
TBTray 2.0: Makes use of Thunderbird's built-in tray icon. The only f…
Browse files Browse the repository at this point in the history
…unctionality left is turning window close events into window minimize events.
  • Loading branch information
sagamusix committed Nov 1, 2021
1 parent c3a3122 commit 943ccb7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 101 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TBTray - Native Win32 Thunderbird tray icon
===========================================
TBTray 2 - Native Win32 Thunderbird tray icon
=============================================

After the x-th reincarnation of the MinimizeToTray add-on for Thunderbird broke
in Thunderbird 68, it seems like it becomes more and more difficult, if not
Expand All @@ -10,9 +10,13 @@ I know that [BirdTray](https://github.com/gyunaev/birdtray) exists, and it's
even cross-platform. However, it tries to solve way more problems than I have
and uses Qt (no offense, I really like the framework), so it's not quite as
light-weight as I think a background process should be.

Thunderbird 78 also finally comes with its own tray icon, but it
[only works when minimizing the window](https://bugzilla.mozilla.org/show_bug.cgi?id=1666638),
not when closing it.
not when closing it. TBTray 0.10 used to provide its own tray icon, but TBTray
2.0 instead makes use of Thunderbird's own tray icon, and merely intercepts the
requests to close the window and turns them into requests to minimize the window
instead.

So I decided to fork a program a friend of mine wrote - [traktouch](https://github.com/dop3j0e/traktouch),
as it solves a very similar problem. I could have written it from scratch, but
Expand All @@ -25,6 +29,7 @@ Note: Requires _Microsoft Visual C++ 2015-2019 Redistributable_, with same bitne
([x86](https://aka.ms/vs/16/release/VC_redist.x86.exe), [x64](https://aka.ms/vs/16/release/VC_redist.x64.exe))
as your Thunderbird.

0. Make sure that you are using Thunderbird 78 or later.
1. Download the [latest TBTray release](https://github.com/sagamusix/TBTray/releases).
2. Extract the archive anywhere you want, `%localappdata%\TBTray` would be a
good place for instance.
Expand All @@ -48,7 +53,8 @@ How does it work?
-----------------

TBTray intercepts some window messages sent to Thunderbird, rejecting window
minimize and close events and instead hiding the window and creating a tray icon.
close events and instead minimizing the window, causing Thunderbird to make use
of its tray icon.

To do this, TBTray checks for the presence of the Thunderbird main window, and if
it finds the window, injects a library into the Thunderbird process to hook into
Expand All @@ -69,16 +75,10 @@ shortcut to send Thunderbird to the notification area if you are used it.
Note: If you want to get this fixed, consider submitting a pull request - I do
not have the time required to debug and fix a feature I am not using.

There is also a second reason why the tool may sometimes not work correctly even
if `mail.tabs.drawInTitlebar` is set to `false`: If Thunderbird shows a password
prompt before the main window is even loaded, the tool may not work correctly.
You should be able to work around that by restarting Thunderbird and then restart
TBTray once Thunderbird's main window is visible.

Halp, how do I quit Thunderbird?
--------------------------------

Through the File menu, or the context menu of the tray icon.
Through the File menu.

Is there any sort of configuration?
-----------------------------------
Expand Down
91 changes: 4 additions & 87 deletions dll/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

#include <windows.h>
#include <tchar.h>
#include <shellapi.h>

#include "guicon.h"
#include <stdlib.h>
Expand All @@ -42,46 +41,12 @@
HHOOK hMessageHook;

static HWND mainHwnd = nullptr;
static NOTIFYICONDATA nid = { 0 };

enum CommandID
{
ID_RESTORE = 1000,
ID_CLOSE
};

static LRESULT CALLBACK TrayIconProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if((uMsg == WM_USER + 1337 && LOWORD(lParam) == NIN_SELECT) || uMsg == WM_COMMAND)
{
// Restore main window
ShowWindow(mainHwnd, SW_SHOW);
Shell_NotifyIcon(NIM_DELETE, &nid);
if (uMsg == WM_COMMAND && wParam == ID_CLOSE)
SendMessage(mainHwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
else
SetForegroundWindow(mainHwnd);
}
else if (uMsg == WM_USER + 1337 && LOWORD(lParam) == WM_CONTEXTMENU)
{
SetForegroundWindow(hwnd);
POINT pt;
GetCursorPos(&pt);
HMENU hMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING, ID_RESTORE, _T("&Restore Thunderbird"));
AppendMenu(hMenu, MF_STRING, ID_CLOSE, _T("&Close Thunderbird"));
TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, nullptr);
DestroyMenu(hMenu);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK MessageHook(int nCode, WPARAM wParam, LPARAM lParam)
{
static HWND trayHwnd = nullptr;
MSG &msg = *(MSG *)lParam;

if(mainHwnd == nullptr)
if(mainHwnd == nullptr && (GetWindowLong(msg.hwnd, GWL_STYLE) & WS_SIZEBOX))
{
/*
* The main UI thread handles several windows and we need to subclass the right one,
Expand All @@ -90,65 +55,17 @@ LRESULT CALLBACK MessageHook(int nCode, WPARAM wParam, LPARAM lParam)
static TCHAR winTitle[256];
GetWindowText(msg.hwnd, winTitle, _countof(winTitle));
if(_tcsstr(winTitle, L"- Mozilla Thunderbird"))
{
mainHwnd = msg.hwnd;

static const TCHAR windowClassName[] = _T("ThunderbirdMinToTrayIcon");
WNDCLASSEX wndClass;
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = 0;
wndClass.lpfnWndProc = TrayIconProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = GetModuleHandle(nullptr);
wndClass.hIcon = nullptr;
wndClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
wndClass.hbrBackground = nullptr;
wndClass.lpszMenuName = nullptr;
wndClass.lpszClassName = windowClassName;
wndClass.hIconSm = nullptr;
RegisterClassEx(&wndClass);

trayHwnd = CreateWindow(
windowClassName,
_T("Thunderbird Tray Icon"),
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
1, 1,
HWND_MESSAGE,
nullptr,
GetModuleHandle(nullptr),
nullptr);
}

}

if(msg.hwnd == mainHwnd &&
(
(msg.message == WM_NCLBUTTONDOWN && (msg.wParam == HTCLOSE || msg.wParam == HTMINBUTTON))
(msg.message == WM_NCLBUTTONDOWN && msg.wParam == HTCLOSE)
||
(msg.message == WM_SYSCOMMAND && (msg.wParam == SC_CLOSE || msg.wParam == SC_MINIMIZE))
(msg.message == WM_SYSCOMMAND && msg.wParam == SC_CLOSE)
))
{
ShowWindow(msg.hwnd, SW_HIDE);
// Show tray icon
nid.cbSize = sizeof(nid);
nid.hWnd = trayHwnd;
nid.uID = 1337;
nid.uFlags = NIF_ICON | NIF_TIP | NIF_SHOWTIP | NIF_MESSAGE;
nid.uCallbackMessage = WM_USER + 1337;
nid.hIcon = (HICON)GetClassLongPtr(mainHwnd, GCLP_HICON);
lstrcpy(nid.szTip, _T("Mozilla Thunderbird"));
nid.dwState = 0;
nid.dwStateMask = 0;
lstrcpy(nid.szInfo, _T(""));
nid.uVersion = NOTIFYICON_VERSION_4;
lstrcpy(nid.szInfoTitle, _T(""));
nid.dwInfoFlags = 0;
nid.guidItem = {};
nid.hBalloonIcon = nid.hIcon;
Shell_NotifyIcon(NIM_ADD, &nid);
Shell_NotifyIcon(NIM_SETVERSION, &nid);
PostMessage(msg.hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
// Ignore this message
msg.message = WM_NULL;
}
Expand Down
6 changes: 3 additions & 3 deletions version.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#define MAJORVER 0
#define MINORVER 10
#define FIXVER 4
#define MAJORVER 2
#define MINORVER 0
#define FIXVER 0

#define PRODUCTVER MAJORVER,MINORVER,FIXVER,0
#define _STR(x) #x
Expand Down

0 comments on commit 943ccb7

Please sign in to comment.