diff --git a/packages/tray_manager/example/lib/pages/home.dart b/packages/tray_manager/example/lib/pages/home.dart index 35c25cb..16b3441 100644 --- a/packages/tray_manager/example/lib/pages/home.dart +++ b/packages/tray_manager/example/lib/pages/home.dart @@ -17,6 +17,7 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State with TrayListener { + ValueNotifier shouldForegroundOnContextMenu = ValueNotifier(false); String _iconType = _kIconTypeOriginal; Menu? _menu; @@ -251,10 +252,28 @@ class _HomePageState extends State with TrayListener { }, ), const Divider(height: 0), - ListTile( - title: const Text('popUpContextMenu'), - onTap: () async { - await trayManager.popUpContextMenu(); + ValueListenableBuilder( + valueListenable: shouldForegroundOnContextMenu, + builder: (context, bool bringToForeground, Widget? child) { + return ListTile( + title: const Text('popUpContextMenu'), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text('Should bring app to foreground'), + Switch( + value: bringToForeground, + onChanged: (value) { + shouldForegroundOnContextMenu.value = !bringToForeground; + }, + ), + ], + ), + onTap: () async { + await trayManager + .popUpContextMenu(shouldForegroundOnContextMenu.value); + }, + ); }, ), const Divider(height: 0), @@ -290,7 +309,7 @@ class _HomePageState extends State with TrayListener { if (kDebugMode) { print('onTrayIconMouseDown'); } - trayManager.popUpContextMenu(); + trayManager.popUpContextMenu(shouldForegroundOnContextMenu.value); } @override diff --git a/packages/tray_manager/lib/src/tray_manager.dart b/packages/tray_manager/lib/src/tray_manager.dart index 7d457dd..d9f9e38 100644 --- a/packages/tray_manager/lib/src/tray_manager.dart +++ b/packages/tray_manager/lib/src/tray_manager.dart @@ -183,9 +183,23 @@ class TrayManager { await _channel.invokeMethod('setContextMenu', arguments); } - /// Pops up the context menu of the tray icon. - Future popUpContextMenu() async { - await _channel.invokeMethod('popUpContextMenu'); + /// Pops up the context menu of the tray icon and can foreground the app if `true` is passed as an argument. + Future popUpContextMenu([bool bringAppToForeground = false]) async { + if (bringAppToForeground) { + _popUpContextMenuAndForegroundApp(); + } else { + _popUpContextMenuAndNotForegroundApp(); + } + } + + // Pops up the context menu of the tray icon and do not bring app to the foreground. + Future _popUpContextMenuAndNotForegroundApp() async { + await _channel.invokeMethod('popUpContextMenuAndNotForegroundApp'); + } + + // Pops up the context menu of the tray icon and bring the app to the foreground. + Future _popUpContextMenuAndForegroundApp() async { + await _channel.invokeMethod('popUpContextMenuAndForegroundApp'); } /// The bounds of this tray icon. diff --git a/packages/tray_manager/windows/tray_manager_plugin.cpp b/packages/tray_manager/windows/tray_manager_plugin.cpp index 05e928d..a2e14db 100644 --- a/packages/tray_manager/windows/tray_manager_plugin.cpp +++ b/packages/tray_manager/windows/tray_manager_plugin.cpp @@ -76,7 +76,8 @@ class TrayManagerPlugin : public flutter::Plugin { std::unique_ptr> result); void TrayManagerPlugin::PopUpContextMenu( const flutter::MethodCall& method_call, - std::unique_ptr> result); + std::unique_ptr> result, + bool bringAppToFront); void TrayManagerPlugin::GetBounds( const flutter::MethodCall& method_call, std::unique_ptr> result); @@ -185,14 +186,12 @@ std::optional TrayManagerPlugin::HandleWindowProc(HWND hWnd, } else if (message == WM_MYMESSAGE) { switch (lParam) { case WM_LBUTTONUP: - channel->InvokeMethod( - "onTrayIconMouseDown", - std::make_unique()); + channel->InvokeMethod("onTrayIconMouseDown", + std::make_unique()); break; case WM_RBUTTONUP: - channel->InvokeMethod( - "onTrayIconRightMouseDown", - std::make_unique()); + channel->InvokeMethod("onTrayIconRightMouseDown", + std::make_unique()); break; default: return DefWindowProc(hWnd, message, wParam, lParam); @@ -287,7 +286,8 @@ void TrayManagerPlugin::SetContextMenu( void TrayManagerPlugin::PopUpContextMenu( const flutter::MethodCall& method_call, - std::unique_ptr> result) { + std::unique_ptr> result, + bool bringAppToFront) { HWND hWnd = GetMainWindow(); double x, y; @@ -303,7 +303,9 @@ void TrayManagerPlugin::PopUpContextMenu( x = cursorPos.x; y = cursorPos.y; - SetForegroundWindow(hWnd); + if (bringAppToFront) { + SetForegroundWindow(hWnd); + } TrackPopupMenu(hMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, static_cast(x), static_cast(y), 0, hWnd, NULL); result->Success(flutter::EncodableValue(true)); @@ -352,8 +354,12 @@ void TrayManagerPlugin::HandleMethodCall( SetToolTip(method_call, std::move(result)); } else if (method_call.method_name().compare("setContextMenu") == 0) { SetContextMenu(method_call, std::move(result)); - } else if (method_call.method_name().compare("popUpContextMenu") == 0) { - PopUpContextMenu(method_call, std::move(result)); + } else if (method_call.method_name().compare( + "popUpContextMenuAndNotForegroundApp") == 0) { + PopUpContextMenu(method_call, std::move(result), false); + } else if (method_call.method_name().compare( + "popUpContextMenuAndForegroundApp") == 0) { + PopUpContextMenu(method_call, std::move(result), true); } else if (method_call.method_name().compare("getBounds") == 0) { GetBounds(method_call, std::move(result)); } else {