From 3673689e326d78c10d346f8619f22fab73d50be5 Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Wed, 10 Jan 2024 17:28:08 +0330 Subject: [PATCH] Fix windows deep link --- .../window/notifier/window_notifier.dart | 16 ++----- pubspec.lock | 8 ---- pubspec.yaml | 1 - .../flutter/generated_plugin_registrant.cc | 3 -- windows/flutter/generated_plugins.cmake | 1 - windows/runner/main.cpp | 23 +++++++--- windows/runner/win32_window.cpp | 44 +++++++++++++++++++ windows/runner/win32_window.h | 2 + 8 files changed, 67 insertions(+), 31 deletions(-) diff --git a/lib/features/window/notifier/window_notifier.dart b/lib/features/window/notifier/window_notifier.dart index f16810a6..e7fbbda7 100644 --- a/lib/features/window/notifier/window_notifier.dart +++ b/lib/features/window/notifier/window_notifier.dart @@ -1,14 +1,10 @@ -import 'dart:io'; import 'dart:ui'; -import 'package:hiddify/core/app_info/app_info_provider.dart'; -import 'package:hiddify/core/model/constants.dart'; import 'package:hiddify/features/connection/notifier/connection_notifier.dart'; import 'package:hiddify/utils/utils.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:tray_manager/tray_manager.dart'; import 'package:window_manager/window_manager.dart'; -import 'package:windows_single_instance/windows_single_instance.dart'; part 'window_notifier.g.dart'; @@ -21,18 +17,14 @@ class WindowNotifier extends _$WindowNotifier with AppLogger { Future build() async { if (!PlatformUtils.isDesktop) return; - if (Platform.isWindows) { - loggy.debug("ensuring single instance"); - await WindowsSingleInstance.ensureSingleInstance([], "app.hiddify.com"); - } + // if (Platform.isWindows) { + // loggy.debug("ensuring single instance"); + // await WindowsSingleInstance.ensureSingleInstance([], "HiddifyNext"); + // } await windowManager.ensureInitialized(); await windowManager.setMinimumSize(minimumWindowSize); await windowManager.setSize(defaultWindowSize); - - final appInfo = await ref.watch(appInfoProvider.future); - await windowManager - .setTitle("${Constants.appName} v${appInfo.presentVersion}"); } Future open({bool focus = true}) async { diff --git a/pubspec.lock b/pubspec.lock index 8fd0d4b3..4ab5c388 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1674,14 +1674,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.7" - windows_single_instance: - dependency: "direct main" - description: - name: windows_single_instance - sha256: "50d5dcd6bec90b4a5ed588b1822b1aad21b39fc96da843e61c734b3caccfd2fc" - url: "https://pub.dev" - source: hosted - version: "1.0.1" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index abcbea38..e03f4474 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -67,7 +67,6 @@ dependencies: win32: ^5.2.0 qr_flutter: ^4.1.0 flutter_displaymode: ^0.6.0 - windows_single_instance: ^1.0.1 flutter_loggy_dio: ^3.0.1 dio_smart_retry: ^6.0.0 cupertino_http: ^1.2.0 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index b417ac3c..01d8a783 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -15,7 +15,6 @@ #include #include #include -#include void RegisterPlugins(flutter::PluginRegistry* registry) { ProtocolHandlerPluginRegisterWithRegistrar( @@ -36,6 +35,4 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("VclibsPlugin")); WindowManagerPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("WindowManagerPlugin")); - WindowsSingleInstancePluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("WindowsSingleInstancePlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 92391def..0bd3c28a 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST url_launcher_windows vclibs window_manager - windows_single_instance ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index cafed4ec..9866ffc5 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -9,14 +9,24 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, _In_ wchar_t *command_line, _In_ int show_command) { - HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"Hiddify Next"); - if (hwnd != NULL) { - DispatchToProtocolHandler(hwnd); + HANDLE hMutexInstance = CreateMutex(NULL, TRUE, L"HiddifyMutex"); + HWND handle = FindWindowA(NULL, "Hiddify Next"); - ::ShowWindow(hwnd, SW_NORMAL); - ::SetForegroundWindow(hwnd); - return EXIT_FAILURE; + if (GetLastError() == ERROR_ALREADY_EXISTS) { + flutter::DartProject project(L"data"); + std::vector command_line_arguments = GetCommandLineArguments(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + FlutterWindow window(project); + if (window.SendAppLinkToInstance(L"Hiddify Next")) { + return false; + } + + WINDOWPLACEMENT place = {sizeof(WINDOWPLACEMENT)}; + GetWindowPlacement(handle, &place); + ShowWindow(handle, SW_NORMAL); + return 0; } + // Attach to console when present (e.g., 'flutter run') or create a // new console when running with a debugger. if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { @@ -49,5 +59,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, } ::CoUninitialize(); + ReleaseMutex(hMutexInstance); return EXIT_SUCCESS; } diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp index b2faebd7..cd416b9b 100644 --- a/windows/runner/win32_window.cpp +++ b/windows/runner/win32_window.cpp @@ -4,6 +4,7 @@ #include #include "resource.h" +#include namespace { @@ -123,6 +124,11 @@ Win32Window::~Win32Window() { bool Win32Window::Create(const std::wstring& title, const Point& origin, const Size& size) { + if (SendAppLinkToInstance(title)) + { + return false; + } + Destroy(); const wchar_t* window_class = @@ -155,6 +161,44 @@ bool Win32Window::Show() { return ShowWindow(window_handle_, SW_SHOWNORMAL); } + +bool Win32Window::SendAppLinkToInstance(const std::wstring &title) +{ + // Find our exact window + HWND hwnd = ::FindWindow(kWindowClassName, title.c_str()); + + if (hwnd) + { + // Dispatch new link to current window + DispatchToProtocolHandler(hwnd); + + // (Optional) Restore our window to front in same state + WINDOWPLACEMENT place = {sizeof(WINDOWPLACEMENT)}; + GetWindowPlacement(hwnd, &place); + + switch (place.showCmd) + { + case SW_SHOWMAXIMIZED: + ShowWindow(hwnd, SW_SHOWMAXIMIZED); + break; + case SW_SHOWMINIMIZED: + ShowWindow(hwnd, SW_RESTORE); + break; + default: + ShowWindow(hwnd, SW_NORMAL); + break; + } + + SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); + SetForegroundWindow(hwnd); + + // Window has been found, don't create another one. + return true; + } + + return false; +} + // static LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message, diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h index e901dde6..e07579bb 100644 --- a/windows/runner/win32_window.h +++ b/windows/runner/win32_window.h @@ -36,6 +36,8 @@ class Win32Window { // |Show| is called. Returns true if the window was created successfully. bool Create(const std::wstring& title, const Point& origin, const Size& size); + bool SendAppLinkToInstance(const std::wstring &title); + // Show the current window. Returns true if the window was successfully shown. bool Show();