Kaynağa Gözat

chore: enable single instance desktop application on windows (#3136)

Nathan.fooo 1 yıl önce
ebeveyn
işleme
ef9596f4ab

+ 24 - 10
frontend/appflowy_flutter/windows/runner/main.cpp

@@ -6,12 +6,28 @@
 #include "utils.h"
 
 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) {
+  HANDLE hMutexInstance = CreateMutex(NULL, TRUE, L"AppFlowyMutex");
+  HWND handle = FindWindowA(NULL, "AppFlowy");
+
+  if (GetLastError() == ERROR_ALREADY_EXISTS) {
+    flutter::DartProject project(L"data");
+    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"AppFlowy")) {
+      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())
-  {
+  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
     CreateAndAttachConsole();
   }
 
@@ -21,27 +37,25 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
 
   flutter::DartProject project(L"data");
 
-  std::vector<std::string> command_line_arguments =
-      GetCommandLineArguments();
+  std::vector<std::string> command_line_arguments = GetCommandLineArguments();
 
   project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
 
   FlutterWindow window(project);
   Win32Window::Point origin(10, 10);
   Win32Window::Size size(1280, 720);
-  if (!window.CreateAndShow(L"AppFlowy", origin, size))
-  {
+  if (!window.CreateAndShow(L"AppFlowy", origin, size)) {
     return EXIT_FAILURE;
   }
   window.SetQuitOnClose(true);
 
   ::MSG msg;
-  while (::GetMessage(&msg, nullptr, 0, 0))
-  {
+  while (::GetMessage(&msg, nullptr, 0, 0)) {
     ::TranslateMessage(&msg);
     ::DispatchMessage(&msg);
   }
 
   ::CoUninitialize();
+  ReleaseMutex(hMutexInstance);
   return EXIT_SUCCESS;
 }

+ 4 - 4
frontend/appflowy_flutter/windows/runner/win32_window.h

@@ -41,6 +41,10 @@ public:
                      const Point &origin,
                      const Size &size);
 
+  // Dispatches link if any.
+  // This method enables our app to be with a single instance too.
+  bool SendAppLinkToInstance(const std::wstring &title);
+
   // Release OS resources associated with window.
   void Destroy();
 
@@ -89,10 +93,6 @@ private:
   // Retrieves a class instance pointer for |window|
   static Win32Window *GetThisFromHandle(HWND const window) noexcept;
 
-  // Dispatches link if any.
-  // This method enables our app to be with a single instance too.
-  bool SendAppLinkToInstance(const std::wstring &title);
-
   bool quit_on_close_ = false;
 
   // window handle for top level window.