Bug 578929 - Add new API for setFocus/forceFocus without activating the shell
Summary: Add new API for setFocus/forceFocus without activating the shell
Status: RESOLVED MOVED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.23   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 563073 (view as bug list)
Depends on:
Blocks: 209198 277009
  Show dependency tree
 
Reported: 2022-02-23 07:46 EST by Thomas Singer CLA
Modified: 2022-11-15 11:20 EST (History)
6 users (show)

See Also:


Attachments
Snippet to reproduce (1.74 KB, text/plain)
2022-02-23 07:47 EST, Thomas Singer CLA
no flags Details
Snippet to reproduce (1.75 KB, text/plain)
2022-02-23 08:28 EST, Thomas Singer CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Singer CLA 2022-02-23 07:46:15 EST
Please run the attached snippet. It opens 3 shells, simulates some loading and then wants to set the focused control for each of the shells. Unfortunately, it brings the shell to front, even if it was in the background. If I would want to bring a shell to front, I would invoke shell.setActive(), but I just want to change the focuses control inside a shell.
Comment 1 Thomas Singer CLA 2022-02-23 07:47:48 EST
Created attachment 288110 [details]
Snippet to reproduce
Comment 2 Thomas Singer CLA 2022-02-23 08:28:10 EST
Created attachment 288111 [details]
Snippet to reproduce
Comment 3 Eclipse Genie CLA 2022-02-23 09:22:13 EST
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/191138
Comment 4 Lars Vogel CLA 2022-02-23 09:43:11 EST
IIRC on Windows the forceFocus does not work, see Bug 192036. Is this already fixed?
Comment 5 Rolf Theunissen CLA 2022-02-24 03:34:52 EST
OS.SetFocus will activate the receiving window when it is attached to the thread.
So, currently, when Control.setFocus is called, the containing shell is activated.

The Control.setFocus call should not be calling OS.SetFocus when the shell is not active. i.e. Control.isActive() should be checking if the shell is the active shell on the current thread, not only checking if there is a modal shell shown.

That is, a check like 'if (display.getActiveShell() != shell) return false' should be added in Control.isActive().


https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setfocus
Comment 6 Thomas Singer CLA 2022-02-24 04:10:28 EST
(In reply to Rolf Theunissen from comment #5)
> OS.SetFocus will activate the receiving window when it is attached to the
> thread.
> So, currently, when Control.setFocus is called, the containing shell is
> activated.
> 
> The Control.setFocus call should not be calling OS.SetFocus when the shell
> is not active. i.e. Control.isActive() should be checking if the shell is
> the active shell on the current thread, not only checking if there is a
> modal shell shown.
> 
> That is, a check like 'if (display.getActiveShell() != shell) return false'
> should be added in Control.isActive().
> 
> 
> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-
> setfocus

Do you mean like in my patch?
Comment 7 Rolf Theunissen CLA 2022-02-24 07:59:10 EST
(In reply to Thomas Singer from comment #6)
> Do you mean like in my patch?

I missed your patch before.

But No. I think your patch is trying to add behavior to setFocus that is already implemented by Shell#forceActive. Moreover, I think that the behavior you observer is Win32 only, or are other platforms affected? e.g. I expect that setFocus on GTK does not raise the window.

I would expect a one/two-liner change in Control#isActive() (line 1832)
+ if (display.getActiveShell() != shell) return false;
Some cleanup w.r.t shell = getShell() calls.
Comment 8 Thomas Singer CLA 2022-02-24 09:01:02 EST
(In reply to Rolf Theunissen from comment #7)
> (In reply to Thomas Singer from comment #6)
> > Do you mean like in my patch?
> 
> I missed your patch before.
> 
> But No. I think your patch is trying to add behavior to setFocus that is
> already implemented by Shell#forceActive. Moreover, I think that the
> behavior you observer is Win32 only, or are other platforms affected? e.g. I
> expect that setFocus on GTK does not raise the window.

This problem/behavior is reproducible on macOS/GTK, too.

> I would expect a one/two-liner change in Control#isActive() (line 1832)
> + if (display.getActiveShell() != shell) return false;
> Some cleanup w.r.t shell = getShell() calls.

That's what I've tried initially, but it caused problems selecting something by clicking with the mouse.
Comment 9 Rolf Theunissen CLA 2022-02-24 09:55:56 EST
At least the behavior is consistent on all platforms. Can you update the "Hardware" section to reflect that this is an issue on all platforms.

Then I understand you patch as backward compatibility is required.
Comment 10 Rolf Theunissen CLA 2022-02-24 10:59:41 EST
*** Bug 563073 has been marked as a duplicate of this bug. ***
Comment 11 Rolf Theunissen CLA 2022-02-24 11:01:45 EST
(In reply to Rolf Theunissen from comment #10)
> *** Bug 563073 has been marked as a duplicate of this bug. ***

From Bug 563073, on Windows the Shell is shown on top of all windows the first time setFocus is called, otherwise it is only shown on top of the windows of the same application.
Comment 12 Rolf Theunissen CLA 2022-02-24 11:22:48 EST
Stale Bug 210410 seems related too, but that mouse hover focusing is not commonly used on Windows.
How does GTK react on mouse hover focusing, i.e., does the window get focus without getting to the foreground?
Comment 13 Rolf Theunissen CLA 2022-02-24 11:32:12 EST
(In reply to Rolf Theunissen from comment #12)
> Stale Bug 210410 seems related too, but that mouse hover focusing is not
> commonly used on Windows.
> How does GTK react on mouse hover focusing, i.e., does the window get focus
> without getting to the foreground?

For GTK Stale Bug 413650 seems related.
Comment 14 Rolf Theunissen CLA 2022-02-24 11:46:34 EST
Looking at Bug 209198 and Bug 277009, the behavior that the windows jumps to the front might not be the correct default.
We could consider to change the default too, but I have no clue how many regressions that could introduce, where people assume different behavior.
Comment 15 Thomas Singer CLA 2022-02-24 13:34:01 EST
My patch should not change the existing behavior, except of the addition of restoreFocus in GTK-Shell. Otherwise it only adds new overloaded setFocus/forceFocus methods that allow to not bring the shell to front.
Comment 16 Rolf Theunissen CLA 2022-02-25 02:08:56 EST
(In reply to Thomas Singer from comment #15)
> My patch should not change the existing behavior, except of the addition of
> restoreFocus in GTK-Shell. Otherwise it only adds new overloaded
> setFocus/forceFocus methods that allow to not bring the shell to front.

Yes, that is true. But depends on what you like to accomplish here or what your ambition is. Your patch does only solve your current issue by adding additional API, i.e., increase complexity. While there is the opportunity to fix long standing usability issues (> 15 years) in the platform. Though, that comes with higher risk of course.
Comment 17 Thomas Singer CLA 2022-02-25 02:24:12 EST
Please feel free to provide a different patch.
Comment 18 Thomas Singer CLA 2022-02-25 07:48:00 EST
I think, the existing parameter-less setFocus/forceFocus methods are needed if backward compatibility is required. If that is the case, we need new API anyway to prevent the implicit bring-shell-to-front. The other bugs might need this new API to be resolved, so maybe I should rename the title to "Add new API for setFocus/forceFocus without bringing shell to front".

What do you think about the suggested boolean parameter? Would you rather prefer separate methods, e.g. requestFocus() instead of setFocus(false)?
Comment 19 Rolf Theunissen CLA 2022-02-28 04:06:39 EST
I have reconsidered too. We are talking about keyboard-focus here. So if you call 'setFocus' you expect that a control gets keyboard focus or not. For this it makes a lot of sense that the window made the active window too, which will raise it to the front (depending on the OS or window manager).

What you like to do is set the focus control for a window, when it is active, set the focus to that control. However, when it is inactive, set focus to that control when the window becomes active, i.e., restoreFocus.
I was also thinking to call this something like requestFocus, i.e., this control will get focus when the window is or becomes active.
I don't know if the (public) API of forceFocus should be changed, i.e., if forceFocus return 'true' you expect that that control really has the keyboard focus.

I would rename to something like: "Add new API for setFocus/forceFocus without activating the shell". Now it is implicit that activating the shell brings it to the front too. Another bug might want to change that behavior too (if someone feels the need for it)

Note1: There can be three behaviors w.r.t. the Z-order: 1) do not change it, 2) bring on top for the application, 3) bring on top for all applications.

Note2: besides setFocus and forceFocus, there is also setRadioFocus and setTabGroupFocus that might need updates.
Comment 20 Thomas Singer CLA 2022-10-20 10:29:40 EDT
We are now using our patch (https://github.com/eclipse-platform/eclipse.platform.swt/commit/8ffb9ef5602a6ebeaf00204c5977e27cdee28587) since a couple of months and the problem of SmartGit coming unintended to front when changing the focused control while in the background has been resolved. Feel free to do whatever you like with it. We are maintaining our own clone of the SWT repository at https://github.com/syntevo/eclipse.platform.swt to fix problems like this.
Comment 21 Andrey Loskutov CLA 2022-10-20 10:59:37 EDT
(In reply to Thomas Singer from comment #20)
> We are now using our patch
> (https://github.com/eclipse-platform/eclipse.platform.swt/commit/
> 8ffb9ef5602a6ebeaf00204c5977e27cdee28587) since a couple of months and the
> problem of SmartGit coming unintended to front when changing the focused
> control while in the background has been resolved. Feel free to do whatever
> you like with it. We are maintaining our own clone of the SWT repository at
> https://github.com/syntevo/eclipse.platform.swt to fix problems like this.

Thomas, feel free to provide PR for this. Or is there any reason you won't this to be merged?
Comment 22 Thomas Singer CLA 2022-10-20 14:23:24 EDT
The last comments sounded like my fix would be rejected.
Comment 23 Thomas Singer CLA 2022-11-09 08:27:07 EST
My pull request at https://github.com/eclipse-platform/eclipse.platform.swt/issues/450 waits since 2 weeks to be reviewed.
Comment 24 Lars Vogel CLA 2022-11-15 11:20:50 EST
(In reply to Thomas Singer from comment #23)
> My pull request at
> https://github.com/eclipse-platform/eclipse.platform.swt/issues/450 waits
> since 2 weeks to be reviewed.

Can you ask Alexandr to have a look? IIRC you guys are working together. Marking as moved, as platform does not use bugzilla anymore, only Github issues and PR https://github.com/eclipse-platform/eclipse.platform.swt/issues/450