Skip to content

Commit 5b04acc

Browse files
authored
popUpContextMenu() does not automatically foreground app, but leaves the option for that behavior - working on Windows (#58)
1 parent 6c4935b commit 5b04acc

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

packages/tray_manager/example/lib/pages/home.dart

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class HomePage extends StatefulWidget {
1717
}
1818

1919
class _HomePageState extends State<HomePage> with TrayListener {
20+
ValueNotifier<bool> shouldForegroundOnContextMenu = ValueNotifier(false);
2021
String _iconType = _kIconTypeOriginal;
2122
Menu? _menu;
2223

@@ -251,10 +252,28 @@ class _HomePageState extends State<HomePage> with TrayListener {
251252
},
252253
),
253254
const Divider(height: 0),
254-
ListTile(
255-
title: const Text('popUpContextMenu'),
256-
onTap: () async {
257-
await trayManager.popUpContextMenu();
255+
ValueListenableBuilder(
256+
valueListenable: shouldForegroundOnContextMenu,
257+
builder: (context, bool bringToForeground, Widget? child) {
258+
return ListTile(
259+
title: const Text('popUpContextMenu'),
260+
trailing: Row(
261+
mainAxisSize: MainAxisSize.min,
262+
children: [
263+
Text('Should bring app to foreground'),
264+
Switch(
265+
value: bringToForeground,
266+
onChanged: (value) {
267+
shouldForegroundOnContextMenu.value = !bringToForeground;
268+
},
269+
),
270+
],
271+
),
272+
onTap: () async {
273+
await trayManager
274+
.popUpContextMenu(shouldForegroundOnContextMenu.value);
275+
},
276+
);
258277
},
259278
),
260279
const Divider(height: 0),
@@ -290,7 +309,7 @@ class _HomePageState extends State<HomePage> with TrayListener {
290309
if (kDebugMode) {
291310
print('onTrayIconMouseDown');
292311
}
293-
trayManager.popUpContextMenu();
312+
trayManager.popUpContextMenu(shouldForegroundOnContextMenu.value);
294313
}
295314

296315
@override

packages/tray_manager/lib/src/tray_manager.dart

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,23 @@ class TrayManager {
183183
await _channel.invokeMethod('setContextMenu', arguments);
184184
}
185185

186-
/// Pops up the context menu of the tray icon.
187-
Future<void> popUpContextMenu() async {
188-
await _channel.invokeMethod('popUpContextMenu');
186+
/// Pops up the context menu of the tray icon and can foreground the app if `true` is passed as an argument.
187+
Future<void> popUpContextMenu([bool bringAppToForeground = false]) async {
188+
if (bringAppToForeground) {
189+
_popUpContextMenuAndForegroundApp();
190+
} else {
191+
_popUpContextMenuAndNotForegroundApp();
192+
}
193+
}
194+
195+
// Pops up the context menu of the tray icon and do not bring app to the foreground.
196+
Future<void> _popUpContextMenuAndNotForegroundApp() async {
197+
await _channel.invokeMethod('popUpContextMenuAndNotForegroundApp');
198+
}
199+
200+
// Pops up the context menu of the tray icon and bring the app to the foreground.
201+
Future<void> _popUpContextMenuAndForegroundApp() async {
202+
await _channel.invokeMethod('popUpContextMenuAndForegroundApp');
189203
}
190204

191205
/// The bounds of this tray icon.

packages/tray_manager/windows/tray_manager_plugin.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class TrayManagerPlugin : public flutter::Plugin {
7676
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
7777
void TrayManagerPlugin::PopUpContextMenu(
7878
const flutter::MethodCall<flutter::EncodableValue>& method_call,
79-
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
79+
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
80+
bool bringAppToFront);
8081
void TrayManagerPlugin::GetBounds(
8182
const flutter::MethodCall<flutter::EncodableValue>& method_call,
8283
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
@@ -185,14 +186,12 @@ std::optional<LRESULT> TrayManagerPlugin::HandleWindowProc(HWND hWnd,
185186
} else if (message == WM_MYMESSAGE) {
186187
switch (lParam) {
187188
case WM_LBUTTONUP:
188-
channel->InvokeMethod(
189-
"onTrayIconMouseDown",
190-
std::make_unique<flutter::EncodableValue>());
189+
channel->InvokeMethod("onTrayIconMouseDown",
190+
std::make_unique<flutter::EncodableValue>());
191191
break;
192192
case WM_RBUTTONUP:
193-
channel->InvokeMethod(
194-
"onTrayIconRightMouseDown",
195-
std::make_unique<flutter::EncodableValue>());
193+
channel->InvokeMethod("onTrayIconRightMouseDown",
194+
std::make_unique<flutter::EncodableValue>());
196195
break;
197196
default:
198197
return DefWindowProc(hWnd, message, wParam, lParam);
@@ -287,7 +286,8 @@ void TrayManagerPlugin::SetContextMenu(
287286

288287
void TrayManagerPlugin::PopUpContextMenu(
289288
const flutter::MethodCall<flutter::EncodableValue>& method_call,
290-
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
289+
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
290+
bool bringAppToFront) {
291291
HWND hWnd = GetMainWindow();
292292

293293
double x, y;
@@ -303,7 +303,9 @@ void TrayManagerPlugin::PopUpContextMenu(
303303
x = cursorPos.x;
304304
y = cursorPos.y;
305305

306-
SetForegroundWindow(hWnd);
306+
if (bringAppToFront) {
307+
SetForegroundWindow(hWnd);
308+
}
307309
TrackPopupMenu(hMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, static_cast<int>(x),
308310
static_cast<int>(y), 0, hWnd, NULL);
309311
result->Success(flutter::EncodableValue(true));
@@ -352,8 +354,12 @@ void TrayManagerPlugin::HandleMethodCall(
352354
SetToolTip(method_call, std::move(result));
353355
} else if (method_call.method_name().compare("setContextMenu") == 0) {
354356
SetContextMenu(method_call, std::move(result));
355-
} else if (method_call.method_name().compare("popUpContextMenu") == 0) {
356-
PopUpContextMenu(method_call, std::move(result));
357+
} else if (method_call.method_name().compare(
358+
"popUpContextMenuAndNotForegroundApp") == 0) {
359+
PopUpContextMenu(method_call, std::move(result), false);
360+
} else if (method_call.method_name().compare(
361+
"popUpContextMenuAndForegroundApp") == 0) {
362+
PopUpContextMenu(method_call, std::move(result), true);
357363
} else if (method_call.method_name().compare("getBounds") == 0) {
358364
GetBounds(method_call, std::move(result));
359365
} else {

0 commit comments

Comments
 (0)