Repository navigation
Conversation
|
Hey @Descolada, so I've thought about this one, and I think I'd like to see an |
|
@cwensley interesting idea. As far as I understand, currently only macOS distinguishes active app (the overarching currently used program, claims the global menu bar at the top of the screen, owns the Dock icon indicator etc) vs focused window (where keyboard focus is). It's possible to activate an app without focusing a window, but not focusing a window without activating the app (and a window can't have keyboard focus without also being the active app). So, I think On further thought, it could perhaps be a property instead
What do you think? If you think this is worth implementing then I can attempt it + change the current PR to do |
Clicking "Show OpenTabletDriver" in the tray icon did not bring the window to the front when the form was already shown. Eto's Form.Show() only calls the handler's Show() the first time the form is shown (when !Loaded); every later call just sets Visible = true, so the existing FormHandler.Show() override with ActivateIgnoringOtherApps() never ran on the re-show path. Bringing the window forward in BringToFront() was not an option because it cannot be overridden: Window.BringToFront() is a plain non-virtual method that forwards to the handler, and the Mac handler's BringToFront() is non-virtual as well (it only calls NSWindow.orderFront, which reorders windows within our own app and does not activate the app, so it would not foreground the window anyway). Visible, on the other hand, is virtual on the handler and is the single choke point that every re-show path goes through: the tray menu item, Form.Show() on an already loaded form, and the hide-to-tray restore in MainForm. Upstream, picoe/Eto#2964 ("Mac: Bring focused windows to the foreground") is still open and the maintainer would prefer an Application.Instance.Activate() API over activating on every window focus, so it will likely take some time to land. This keeps the workaround local until then. References: - https://github.com/picoe/Eto/blob/2.11.0/src/Eto/Forms/Window.cs "public void BringToFront() => Handler.BringToFront();" is not virtual, so no subclass or handler override can inject app activation there. - https://github.com/picoe/Eto/blob/2.11.0/src/Eto/Forms/Form.cs Form.Show(): "var loaded = Loaded; if (!loaded) { ... Handler.Show(); } else { base.Visible = true; }" — re-showing an already loaded form bypasses the handler's Show() entirely and goes through Visible. - https://github.com/picoe/Eto/blob/2.11.0/src/Eto.Mac/Forms/MacWindow.cs Mac handler BringToFront() only does "Control.OrderFront(Control)", which cannot activate a background application. - picoe/Eto#2964 Open upstream fix for foregrounding windows on Mac; still under discussion (maintainer prefers an Application.Instance.Activate() API), so it will probably take some time to land. This PR includes AI generated code or other AI use. As part of this repo's rules, I am disclosing my use of AI in the creation of this PR. Co-Authored-By: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Add Application.Activate() as an optional handler capability so callers can request native application activation before focusing their chosen window. Implement it in the native macOS backend, with a version-appropriate fallback and the existing automatic-activation policy preserved. Other backends no-op. Bring the PR branch up to date with develop and replace the original implicit Window.Focus activation change with the reviewed explicit API. Validation: core netstandard2.0 and MonoMac net10.0 builds pass without warnings.
|
@cwensley I've switched to explicit activation, as suggested: form.Show();
Application.Instance.Activate();
form.Focus();My
I also considered activating the frontmost application window on other platforms, or bringing all application windows forward. These approaches introduce policies around modal dialogs, tool windows, minimized windows, and Z-order, potentially surfacing windows the caller did not intend to activate. Frontmost application window activation would be restricted as well, because for example GTK in Wayland doesn't expose window z-order information. So I rejected that broader scope here: the caller chooses the desired window and explicitly calls This also supports OpenTabletDriver’s re-show scenario without coupling activation to every visibility change or |
On macOS, focusing a window can leave its application in the background. Add an explicit
Application.Activate()request so callers can activate the application before focusing their chosen window:The native macOS backend implements an optional handler capability, preserving existing handler compatibility; other backends do nothing. Activation remains subject to the OS, with
IsActiveandIsActiveChangedreporting the observed state. The implementation includes a version-appropriate fallback and preserves the existing automatic-activation policy.Validation: core (
netstandard2.0) and MonoMac (net10.0) builds pass with zero warnings/errors. Native macOS runtime verification remains outstanding.