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

focus change requests in java applications does not work #718

Closed
totaam opened this issue Oct 21, 2014 · 26 comments
Closed

focus change requests in java applications does not work #718

totaam opened this issue Oct 21, 2014 · 26 comments

Comments

@totaam
Copy link
Collaborator

totaam commented Oct 21, 2014

Issue migrated from trac ticket # 718

component: core | priority: major | resolution: fixed

2014-10-21 15:30:34: totaam created the issue


As per the (ugly) example application attached to this ticket, it is impossible to request a raise window in Java using Window.toFront.

Usage:

javac ToolbarFrame1.java
java ToolbarFrame1

Then click raise on one of the windows (only one of the two works... because of lazy coding)

@totaam
Copy link
Collaborator Author

totaam commented Oct 21, 2014

2014-10-21 15:30:52: totaam uploaded file ToolbarFrame1.java (1.2 KiB)

example Java raise application

@totaam
Copy link
Collaborator Author

totaam commented Oct 21, 2014

2014-10-21 15:34:05: totaam changed status from new to assigned

@totaam
Copy link
Collaborator Author

totaam commented Oct 21, 2014

2014-10-21 15:34:05: totaam changed owner from antoine to totaam

@totaam
Copy link
Collaborator Author

totaam commented Oct 21, 2014

2014-10-21 15:34:05: totaam edited the issue description

@totaam
Copy link
Collaborator Author

totaam commented Oct 21, 2014

2014-10-21 15:40:56: totaam edited the issue description

@totaam
Copy link
Collaborator Author

totaam commented Oct 21, 2014

2014-10-21 15:40:56: totaam commented


The fix looks quite simple:

--- xpra/x11/gtk_x11/window.py	(revision 7956)
+++ xpra/x11/gtk_x11/window.py	(working copy)
@@ -624,7 +624,10 @@
     def do_xpra_focus_in_event(self, event):
         grablog("focus_in_event(%s) mode=%s, detail=%s",
             event, GRAB_CONSTANTS.get(event.mode), DETAIL_CONSTANTS.get(event.detail, event.detail))
-        self.may_emit_grab(event)
+        if event.mode==NotifyNormal and event.detail==NotifyNonlinearVirtual:
+            self.emit("raised", event)
+        else:
+            self.may_emit_grab(event)
 
     def do_xpra_focus_out_event(self, event):
         grablog("focus_out_event(%s) mode=%s, detail=%s",

But this is similar to grabs (#139 - see also #556) so maybe there are corner cases, and maybe this can cause regressions with clients that deal with focus client side? Will need testing with some of the test apps (and maybe write new ones for it).

So I am not applying it just yet.

@totaam
Copy link
Collaborator Author

totaam commented Oct 28, 2014

2014-10-28 14:12:54: totaam commented


Worth mentioning: jdk7 known issues:. Quoting here since there is no internal link:

-Area: API: AWT*

''Synopsis: This issue is specific to Window.toFront() and Window.toBack() behavior on X11 systems (Linux, Solaris). AWT always performs all necessary actions required to bring a window to the top or the bottom in the stacking order, according to the specifications of the windowing systems (e.g. the ICCCM and/or the EWMH for X11 systems). Whether the actions take effect or not depends on the window manager currently running in the system. Some windowing systems enforce additional constraints on when a window may be brought to the top in the window stacking order. In most cases, the purpose for such additional constraints is to enhance usability or security of these windowing environments. In other cases, these may simply be bugs in the windowing systems. This means that invoking the Window.toFront() or Window.toBack() methods may not always produce the expected results.
While this issue is, to some extent, reflected in the specification of the toFront() method, we've received several user complaints on this particular behavior while developing JDK7. All of these CRs have been closed as "Not a Defect" because AWT can't short-circuit the additional constraints, or work around any bugs in third-party software. If the problem is encountered with a Java application, in most cases it makes sense to check if native applications behave the same way, and file a bug against the windowing system accordingly.''

@totaam
Copy link
Collaborator Author

totaam commented Nov 2, 2014

2014-11-02 10:28:21: totaam commented


The first difficulty is in finding some test code that does raise another window, even when minimized. Sounds simple, but it isn't in Java. See How to bring a window to the front?
When the window is minimized using the client window manager rather than programmatically (as apposed to How do I minimize and restore frames and JFrames?), the only thing that does restore it is to hide it then show it again, otherwise Java just doesn't change its state... (see [/attachment/ticket/718/RaiseTest.java RaiseTest.java])

Also it seems there are a few Java bugs in this area:

Now, we do fail this test. Adding the patch from comment:2 does improve things, but not it isn't very reliable and we don't handle the window when minimized, because we don't actually minimize it server side...

@totaam
Copy link
Collaborator Author

totaam commented Nov 3, 2014

2014-11-03 16:11:29: totaam commented


I am moving the lack of support for setting the minimized state of windows to #726. This should resolve the raising of minimized windows (assuming this ticket is also fixed).

Running the example above under xtrace, I see that the request to raise the window is done using a XConfigureRequestEvent with stack-mode=Above:

000:<:04c9: 16: Request(12): ConfigureWindow window=0x00800007 values={stack-mode=Above(0x00)}

So we should be able to select for those events on the window.. except I can't seem to receive them!?
The window in the request data is the "client window" as found in our window model, that's the application's own window.
According to the docs ConfigureRequest Events: To receive ConfigureRequest events, set the SubstructureRedirectMask bit in the event-mask attribute of the window. ConfigureRequest events are generated when a ConfigureWindow protocol request is issued on a child window by another client. For example, suppose a client application calls XLowerWindow() to lower a window. If you had selected SubstructureRedirectMask on the parent window and if the override-redirect attribute of the window is set to False, the X server reports a ConfigureRequest event to you and does not lower the specified window.

We do already select those events using X11Window.substructureRedirect, this is how we already intercept client applications that resize themselves, but I am not seeing the stack-raise event in the X11 filter! Why!?

@totaam
Copy link
Collaborator Author

totaam commented Nov 4, 2014

2014-11-04 07:27:30: totaam commented


Improved the test examples in r8050 + r8051.

Running the GTK resize test and xtracing it with:

xtrace ./tests/xpra/test_apps/test_window_resize.py |& \
    egrep -vi "render|keyboard|cliprect|copyarea|changegc|pixmap|polyfill|motionnotify|expose|polysegment"

I see the configure request, but still not in the xpra event loop. At least it is consistent.

@totaam
Copy link
Collaborator Author

totaam commented Dec 27, 2014

2014-12-27 17:03:56: antoine commented


Running the raise test example, I can see that Java fails to see our window as iconified.

There is a difference between what a normal desktop environment does and what we do when minimizing a window:

  • the normal window state is: Map State: IsViewable
  • my DE sets it to: Map State: IsUnMapped
  • xpra: Map State: IsUnviewable

In all cases:

  • the window state goes from window state: Normal to window state: Iconic
  • _NET_WM_STATE goes from empty to _NET_WM_STATE_HIDDEN

@totaam
Copy link
Collaborator Author

totaam commented Dec 28, 2014

2014-12-28 16:57:29: antoine commented


See #726 for the fix to WM_STATE. Now going back to the actual toFront to try to find a cleaner solution for detecting the "window raise" event.

The relevant code for toFront() in the Java source looks like this one in solaris/classes/sun/awt/X11/XBaseWindow.java using XRaiseWindow:

public void toFront() {
    XToolkit.awtLock();
    try {
        XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
    } finally {
        XToolkit.awtUnlock();
    }
}

This should allow us to write a simple example to test with.

@totaam
Copy link
Collaborator Author

totaam commented Jan 1, 2015

2015-01-01 16:57:54: antoine commented


The improvements done as part of #765 (in particular r8319) now allow Java to see the window as iconified.
The updated example code correctly unminimizes the window before trying to raise it. But the raising part is still problematic..

@totaam
Copy link
Collaborator Author

totaam commented Jan 1, 2015

2015-01-01 17:16:33: antoine uploaded file RaiseTest.java (2.3 KiB)

updated test code, which does raise the window even when it is minimized

@totaam
Copy link
Collaborator Author

totaam commented Jan 1, 2015

2015-01-01 17:17:29: antoine changed status from assigned to new

@totaam
Copy link
Collaborator Author

totaam commented Jan 1, 2015

2015-01-01 17:17:29: antoine changed owner from totaam to afarr

@totaam
Copy link
Collaborator Author

totaam commented Jan 1, 2015

2015-01-01 17:17:29: antoine commented


Having read again (with difficulty) Normal Focus Events and Focus Events While Grabbed, I believe the change from comment:2 may well be correct in the end so I've applied it in r8351. (it could be backported - but not need to rush it)

afarr: just re-assigning to you so you know about this, in case we hit focus related issues somewhere else - this could be the cause. Feel free to just close it as an ACK.
To run the example test code, just run:

javac RaiseTest.java
java RaiseTest

@totaam
Copy link
Collaborator Author

totaam commented Jan 5, 2015

2015-01-05 05:34:21: totaam commented


I've not seen any adverse effects so far, so backported to v0.14.x in 8384.

@totaam
Copy link
Collaborator Author

totaam commented Jan 5, 2015

2015-01-05 06:06:30: antoine commented


Spoke too soon: r8286 (+backport in 8287) needed to prevent minimize + restore loops when minimizing a window which does not have focus.

@totaam
Copy link
Collaborator Author

totaam commented Feb 18, 2015

2015-02-18 02:23:05: afarr commented


Err... think I'm doing something wrong trying to launch.

Running: $ java ToolbarFrame1.java I get Error: Could not find or load main class ToolbarFrame1.java.

(Google says something about javac, but that's giving me a command not found error... I know I'm missing something.)

@totaam
Copy link
Collaborator Author

totaam commented Feb 18, 2015

2015-02-18 04:23:14: antoine commented


Please see comment:10, you need to run javac before you can run java on the class file that gets generated.
[[BR]]

javac, but that's giving me a command not found error..
[[BR]]
Which package provides javac depends on what distro you are testing with.

@totaam
Copy link
Collaborator Author

totaam commented Feb 23, 2015

2015-02-23 23:03:38: afarr changed owner from afarr to antoine

@totaam
Copy link
Collaborator Author

totaam commented Feb 23, 2015

2015-02-23 23:03:38: afarr commented


Ok... run and now vaguely familiar with it. Handing back to you to close (assuming you don't have more bits to handle).

@totaam
Copy link
Collaborator Author

totaam commented Feb 24, 2015

2015-02-24 00:55:47: antoine changed status from new to closed

@totaam
Copy link
Collaborator Author

totaam commented Feb 24, 2015

2015-02-24 00:55:47: antoine set resolution to fixed

@totaam
Copy link
Collaborator Author

totaam commented Feb 24, 2015

2015-02-24 00:55:47: antoine commented


Done! Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant