Fix windows deep link

This commit is contained in:
problematicconsumer
2024-01-10 17:28:08 +03:30
parent 6dcae6cff1
commit 3673689e32
8 changed files with 67 additions and 31 deletions

View File

@@ -1,14 +1,10 @@
import 'dart:io';
import 'dart:ui'; 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/features/connection/notifier/connection_notifier.dart';
import 'package:hiddify/utils/utils.dart'; import 'package:hiddify/utils/utils.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:tray_manager/tray_manager.dart'; import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
import 'package:windows_single_instance/windows_single_instance.dart';
part 'window_notifier.g.dart'; part 'window_notifier.g.dart';
@@ -21,18 +17,14 @@ class WindowNotifier extends _$WindowNotifier with AppLogger {
Future<void> build() async { Future<void> build() async {
if (!PlatformUtils.isDesktop) return; if (!PlatformUtils.isDesktop) return;
if (Platform.isWindows) { // if (Platform.isWindows) {
loggy.debug("ensuring single instance"); // loggy.debug("ensuring single instance");
await WindowsSingleInstance.ensureSingleInstance([], "app.hiddify.com"); // await WindowsSingleInstance.ensureSingleInstance([], "HiddifyNext");
} // }
await windowManager.ensureInitialized(); await windowManager.ensureInitialized();
await windowManager.setMinimumSize(minimumWindowSize); await windowManager.setMinimumSize(minimumWindowSize);
await windowManager.setSize(defaultWindowSize); await windowManager.setSize(defaultWindowSize);
final appInfo = await ref.watch(appInfoProvider.future);
await windowManager
.setTitle("${Constants.appName} v${appInfo.presentVersion}");
} }
Future<void> open({bool focus = true}) async { Future<void> open({bool focus = true}) async {

View File

@@ -1674,14 +1674,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.7" 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: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@@ -67,7 +67,6 @@ dependencies:
win32: ^5.2.0 win32: ^5.2.0
qr_flutter: ^4.1.0 qr_flutter: ^4.1.0
flutter_displaymode: ^0.6.0 flutter_displaymode: ^0.6.0
windows_single_instance: ^1.0.1
flutter_loggy_dio: ^3.0.1 flutter_loggy_dio: ^3.0.1
dio_smart_retry: ^6.0.0 dio_smart_retry: ^6.0.0
cupertino_http: ^1.2.0 cupertino_http: ^1.2.0

View File

@@ -15,7 +15,6 @@
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <vclibs/vclibs_plugin.h> #include <vclibs/vclibs_plugin.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
#include <windows_single_instance/windows_single_instance_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
ProtocolHandlerPluginRegisterWithRegistrar( ProtocolHandlerPluginRegisterWithRegistrar(
@@ -36,6 +35,4 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("VclibsPlugin")); registry->GetRegistrarForPlugin("VclibsPlugin"));
WindowManagerPluginRegisterWithRegistrar( WindowManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowManagerPlugin")); registry->GetRegistrarForPlugin("WindowManagerPlugin"));
WindowsSingleInstancePluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowsSingleInstancePlugin"));
} }

View File

@@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_windows url_launcher_windows
vclibs vclibs
window_manager window_manager
windows_single_instance
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@@ -9,14 +9,24 @@
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
_In_ wchar_t *command_line, _In_ int show_command) { _In_ wchar_t *command_line, _In_ int show_command) {
HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"Hiddify Next"); HANDLE hMutexInstance = CreateMutex(NULL, TRUE, L"HiddifyMutex");
if (hwnd != NULL) { HWND handle = FindWindowA(NULL, "Hiddify Next");
DispatchToProtocolHandler(hwnd);
::ShowWindow(hwnd, SW_NORMAL); if (GetLastError() == ERROR_ALREADY_EXISTS) {
::SetForegroundWindow(hwnd); flutter::DartProject project(L"data");
return EXIT_FAILURE; std::vector<std::string> 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 // Attach to console when present (e.g., 'flutter run') or create a
// new console when running with a debugger. // new console when running with a debugger.
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
@@ -49,5 +59,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
} }
::CoUninitialize(); ::CoUninitialize();
ReleaseMutex(hMutexInstance);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -4,6 +4,7 @@
#include <flutter_windows.h> #include <flutter_windows.h>
#include "resource.h" #include "resource.h"
#include <protocol_handler/protocol_handler_plugin.h>
namespace { namespace {
@@ -123,6 +124,11 @@ Win32Window::~Win32Window() {
bool Win32Window::Create(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
if (SendAppLinkToInstance(title))
{
return false;
}
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
@@ -155,6 +161,44 @@ bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL); 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 // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,

View File

@@ -36,6 +36,8 @@ class Win32Window {
// |Show| is called. Returns true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool Create(const std::wstring& title, const Point& origin, const Size& size); 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. // Show the current window. Returns true if the window was successfully shown.
bool Show(); bool Show();