Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS: Dock management #105

Open
probablykasper opened this issue Jun 24, 2021 · 9 comments
Open

macOS: Dock management #105

probablykasper opened this issue Jun 24, 2021 · 9 comments

Comments

@probablykasper
Copy link
Member

Ability to hide app from Dock

There's a window-level .skip_taskbar() method, but as far as I can tell nothing for hiding the app itself from the Dock

@amrbashir
Copy link
Member

skip_taskbar should always be for window-level.

I am assuming you are on macOs and unfortunately it is not supported atm because on macOs it is app-level and we still haven't decided how to introduce this.

@amrbashir
Copy link
Member

I think we forgot to document that it doesn't work on macOs

@lemarier
Copy link
Member

This could be accomplished with set_activation_policy

https://github.com/tauri-apps/tao/blob/dev/examples/system_tray_no_menu.rs#L36

But, tauri do not expose it yet.

@probablykasper
Copy link
Member Author

@amrbashir Yeah, I agree that skip_taskbar should only be window-level.

In Electron they just have dock.hide() and dock.show(), maybe Tauri could have set_dock_visibility(bool)

@lemarier lemarier transferred this issue from tauri-apps/tauri Jun 24, 2021
@lemarier lemarier changed the title Ability to hide app from Dock macOS: Dock management Jun 24, 2021
@lemarier
Copy link
Member

@wburningham
Copy link

I'm looking to make a simple systray-only app for OSX. This feature would be a big help.

@amrbashir how much work is it to add a set_dock_visibility(bool) like @probablykasper suggested?

@amrbashir
Copy link
Member

@wburningham it should be fairly simple but I don't know much about macOS development so I guess this issue is waiting for someone with macOS development background to make a PR.

@rtiagom
Copy link

rtiagom commented May 30, 2024

We really need a way to configure the dock menu in the AppDelegate applicationDockMenu

https://www.electronjs.org/docs/latest/tutorial/macos-dock

@1111mp
Copy link

1111mp commented Oct 15, 2024

@amrbashir Yeah, I agree that skip_taskbar should only be window-level.

In Electron they just have dock.hide() and dock.show(), maybe Tauri could have set_dock_visibility(bool)

I was looking for an alternative to electron's dock.show & dock.hide api from tauri and found this. Sorry, I am not familiar enough with Tauri, so I can only provide some documentation on how to implement the API.

This is the implementation in electron:

dock.hiden https://github.com/electron/electron/blob/9ecb848c677fa1bdd4ad423a83e3827c5c03b716/shell/browser/browser_mac.mm#L489

void Browser::DockHide() {
  // Transforming application state from UIElement to Foreground is an
  // asynchronous operation, and unfortunately there is currently no way to know
  // when it is finished.
  // So if we call DockHide => DockShow => DockHide => DockShow in a very short
  // time, we would trigger a bug of macOS that, there would be multiple dock
  // icons of the app left in system.
  // To work around this, we make sure DockHide does nothing if it is called
  // immediately after DockShow. After some experiments, 1 second seems to be
  // a proper interval.
  if (!last_dock_show_.is_null() &&
      base::Time::Now() - last_dock_show_ < base::Seconds(1)) {
    return;
  }

  for (auto* const& window : WindowList::GetWindows())
    [window->GetNativeWindow().GetNativeNSWindow() setCanHide:NO];

  ProcessSerialNumber psn = {0, kCurrentProcess};
  TransformProcessType(&psn, kProcessTransformToUIElementApplication);
}

dock.show https://github.com/electron/electron/blob/9ecb848c677fa1bdd4ad423a83e3827c5c03b716/shell/browser/browser_mac.mm#L518

v8::Local<v8::Promise> Browser::DockShow(v8::Isolate* isolate) {
  last_dock_show_ = base::Time::Now();
  gin_helper::Promise<void> promise(isolate);
  v8::Local<v8::Promise> handle = promise.GetHandle();

  BOOL active = [[NSRunningApplication currentApplication] isActive];
  ProcessSerialNumber psn = {0, kCurrentProcess};
  if (active) {
    // Workaround buggy behavior of TransformProcessType.
    // http://stackoverflow.com/questions/7596643/
    NSArray* runningApps = [NSRunningApplication
        runningApplicationsWithBundleIdentifier:@"com.apple.dock"];
    for (NSRunningApplication* app in runningApps) {
      [app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
      break;
    }
    __block gin_helper::Promise<void> p = std::move(promise);
    dispatch_time_t one_ms = dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC);
    dispatch_after(one_ms, dispatch_get_main_queue(), ^{
      TransformProcessType(&psn, kProcessTransformToForegroundApplication);
      dispatch_time_t one_ms_2 = dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC);
      dispatch_after(one_ms_2, dispatch_get_main_queue(), ^{
        [[NSRunningApplication currentApplication]
            activateWithOptions:NSApplicationActivateIgnoringOtherApps];
        p.Resolve();
      });
    });
  } else {
    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
    promise.Resolve();
  }
  return handle;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 📬Proposal
Development

No branches or pull requests

6 participants