ice-wm / icewm

IceWM releases only, see Wiki
https://github.com/ice-wm/icewm/releases
Other
289 stars 16 forks source link

Window Focus Issue - Citrix Workspace #135

Closed RandomCitrixWorkspaceUser closed 1 year ago

RandomCitrixWorkspaceUser commented 1 year ago

Hi IceWM development team - when using Ubuntu devices with Citrix Workspace installed, we're having some window focus issues with a windows forms .net application. Citrix workspace is connecting to a windows server to run the windows forms .net application. Once the main form is open, you can click a button to open a modal dialog window. Once that modal dialog is open, if a user changes focus to another window/application, and then back to the modal dialog, and then when they close the modal dialog form, MessageBox.Show is called to show a message on screen. Once this window is closed by clicking ok, the window focus changes back to the "other window/application", instead of back to the modal dialog within Citrix.

Our development contact indicated this is because IceWM doesn't support "XEMBED_FOCUS_IN" and "XEMBED_FOCUS_OUT". Would it be possible to get those added to IceWM?

Apologies for any wrong terminology.

gijsbers commented 1 year ago

It's slightly confusing: "they close the modal dialog form", and "instead of back to the modal dialog". Maybe give each window in your description also a unique name like a capital letter. "modal dialog form B", etc. Does this description sofar assume the use of the xembed specification? I thought icewm only uses that in the system tray. Thanks for submitting this issue. The handling of modal dialogs and focus is surely an area open for improvement.

RandomCitrixWorkspaceUser commented 1 year ago

Hi Gijsbers! I'll list all open windows:

Window A: Citrix Workspace Window B: Main form application Window C: Modal dialog form window (generated by Form.ShowDialog() method - https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.showdialog?view=windowsdesktop-7.0) Window D: Modal dialog window (generated by .net "MessageBox.Show()" method - https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.messagebox.show?view=windowsdesktop-7.0)

Users will open Citrix Workspace (Window A), and then launch the Main form application (Window B). This is their primary focus window during their work.

One of the options on Window B is to press a button, which opens a modal child form (Window C).

Window C has a "submit" button that launches a Messagebox.Show() dialog (Window D) to confirm submission, and then closes Window C.

If a user has Window C open, and changes focus to Window A, and then clicks back in to Window C, and clicks 'Submit', Window D shows up appropriately, but once Window D is closed, the operating system focus reverts back to Window A, instead of returning to Window B, the parent of Window C.

We attempted to escalate this issue with Citrix, and they indicated the issue is the lack of support of those two XEMBED specifications within IceWM. Unfortunately I'm not very knowledgeable in that area beyond what was shared with me.

RandomCitrixWorkspaceUser commented 1 year ago

The specific information Citrix provided is as follows:

"We found the root cause should be current IceWM window manager doesn't support

XEMBED_FOCUS_IN and XEMBED_FOCUS_OUT message

(refer to IceWM git repos

[https://github.com/ice-wm/icewm/blob/master/COMPLIANCE]

which is used by our X11 based implementation to deal with the embedded window events from our CWAL (Citrix Workspace App for Linux) code."

gijsbers commented 1 year ago

With regards to XEMBED_FOCUS_IN:

I was wondering what other X11 window managers do with XEMBED_FOCUS_IN and searched their code for its use. The only example I could find is awesome, which uses it in its system tray.

In the xembed specification it reads:

XEMBED_FOCUS_IN Sent from the embedder to the client when it gets focus. The detail code determines, where the client shall move its own logical focus to.

But the only embedding done here is for icons in the system tray, not for windows, nor for dialogs.

Hence I fail to see how XEMBED_FOCUS_IN could be of any help. It is the responsibility of the embedder to use XEMBED_FOCUS_IN. If the Citrix is the embedder, then it should not expect a window manager to do anything with XEMBED_FOCUS_IN.

RandomCitrixWorkspaceUser commented 1 year ago

Hi gijsbers -

Would it help if I could provide a brief video example of the issue?

gijsbers commented 1 year ago

I think I understand some of the scenario with Window D. The information I would value most are their window properties of windows B+C+D which communicate to icewm their interrelatedness. That alone may already provide enough knowledge to think about a code improvement. The command to do so is: xprop | grep -e '[:=]' Then click on a window and repeat for the other two. If you could prove that a solution requires the use of XEMBED_FOCUS_IN with a video, then go ahead, but I think it couldn't. Classical window properties could suffice to change focus from D to B.

RandomCitrixWorkspaceUser commented 1 year ago

Hi!

I tried running the command you advised, but grep was giving an error, so I removed the pipe to grep and will provide the entire output of xprop:

Note: The window hierarchy is like this: Windows D is a modal that should be owned by Window C, which is also a modal, owned by Window B

I ran the xprop command with Window D having "focus" (as the Window B and C are not able to get focus due to modal). If you'd like other command output, please let me know.

Window B

_ICEWM_TRAY(CARDINAL) = 0 _WIN_LAYER(CARDINAL) = 4 _NET_WM_DESKTOP(CARDINAL) = 0 _WIN_WORKSPACE(CARDINAL) = 0 WM_STATE(WM_STATE): window state: Normal icon window: 0x0 _NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ _WIN_STATE(CARDINAL) = 12, 1023 _NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 0, 0 _NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_ACTION_STICK, _NET_WM_ACTION_CHANGE_DESKTOP _NET_WM_VISIBLE_ICON_NAME(UTF8_STRING) = "Window B" _NET_WM_VISIBLE_NAME(UTF8_STRING) = "Window B" _NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x2e00003 WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW _MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x2, 0x0, 0x0, 0x0, 0x0 WM_CLASS(STRING) = "Window B", "Window B" WM_LOCALE_NAME(STRING) = "en_US.UTF-8" WM_NORMAL_HINTS(WM_SIZE_HINTS): program specified location: 0, 0 program specified size: 1024 by 743 WM_CLIENT_MACHINE(STRING) = "LabPC" WM_ICON_NAME(UTF8_STRING) = "Window B" WM_NAME(UTF8_STRING) = "Window B" _NET_WM_ICON_NAME(UTF8_STRING) = "Window B" _NET_WM_NAME(UTF8_STRING) = "Window B" WM_HINTS(WM_HINTS): Client accepts input or input focus: False Initial state is Normal State. bitmap id # to use for icon: 0x0

Window C

_ICEWM_TRAY(CARDINAL) = 0 _WIN_LAYER(CARDINAL) = 4 _NET_WM_DESKTOP(CARDINAL) = 0 _WIN_WORKSPACE(CARDINAL) = 0 WM_STATE(WM_STATE): window state: Normal icon window: 0x0 _NET_WM_STATE(ATOM) = _WIN_STATE(CARDINAL) = 0, 1023 _NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 0, 0 _NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_ACTION_STICK, _NET_WM_ACTION_CHANGE_DESKTOP _NET_WM_VISIBLE_ICON_NAME(UTF8_STRING) = "Window C" _NET_WM_VISIBLE_NAME(UTF8_STRING) = "Window C" _NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x2e00003 WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW _MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x2, 0x0, 0x0, 0x0, 0x0 WM_CLASS(STRING) = "Window C", "Window C" WM_LOCALE_NAME(STRING) = "en_US.UTF-8" WM_NORMAL_HINTS(WM_SIZE_HINTS): program specified location: 210, 198 program specified size: 604 by 347 WM_CLIENT_MACHINE(STRING) = "LabPC" WM_ICON_NAME(UTF8_STRING) = "Window C" WM_NAME(UTF8_STRING) = "Window C" _NET_WM_ICON_NAME(UTF8_STRING) = "Window C" _NET_WM_NAME(UTF8_STRING) = "Window C" WM_HINTS(WM_HINTS): Client accepts input or input focus: False Initial state is Normal State. bitmap id # to use for icon: 0x0

Window D

_ICEWM_TRAY(CARDINAL) = 0 _WIN_LAYER(CARDINAL) = 4 _NET_WM_DESKTOP(CARDINAL) = 0 _WIN_WORKSPACE(CARDINAL) = 0 WM_STATE(WM_STATE): window state: Normal icon window: 0x0 _NET_WM_STATE(ATOM) = _WIN_STATE(CARDINAL) = 0, 1023 _NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 0, 0 _NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_ACTION_STICK, _NET_WM_ACTION_CHANGE_DESKTOP _NET_WM_VISIBLE_ICON_NAME(UTF8_STRING) = "Window D" _NET_WM_VISIBLE_NAME(UTF8_STRING) = "Window D" _NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x2e00003 WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW _MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x2, 0x0, 0x0, 0x0, 0x0 WM_CLASS(STRING) = "Window D", "Window D" WM_LOCALE_NAME(STRING) = "en_US.UTF-8" WM_NORMAL_HINTS(WM_SIZE_HINTS): program specified location: 369, 317 program specified size: 300 by 172 WM_CLIENT_MACHINE(STRING) = "LabPC" WM_ICON_NAME(UTF8_STRING) = "Window D" WM_NAME(UTF8_STRING) = "Window D" _NET_WM_ICON_NAME(UTF8_STRING) = "Window D" _NET_WM_NAME(UTF8_STRING) = "Window D" WM_HINTS(WM_HINTS): Client accepts input or input focus: True Initial state is Normal State. bitmap id # to use for icon: 0x0

RandomCitrixWorkspaceUser commented 1 year ago

My apologies - I just realized I was testing with IceWM 1.5.5 (linux-gnu/x86_64).

Please allow me some time to re-test with IceWM 3.3.5

gijsbers commented 1 year ago

Thanks for providing these window properties. What is striking is that there are no properties which indicate to window manager any kind of relatedness between these windows. There is no window_group, there is no WM_CLIENT_LEADER, there is no WM_TRANSIENT_FOR. In short, this application is non-conformant to the ICCCM. There is also no _NET_WM_STATE_MODAL flag from the EWMH standard. Hence, there is no way that icewm could detect that these are dialogs. I would suggest to the developers of this application to implement the above standards more fully.

RandomCitrixWorkspaceUser commented 1 year ago

Hi gijsbers -

Do you think this might be related to the Citrix Workspace App for Linux, or within our .net app that is running within Citrix workspace?

As an aside, the team at Citrix tested with XFCE window manager, and said the focus change/focus issue does not exist in XFCE, but confirmed it does exist in IceWM.

gijsbers commented 1 year ago

I don't know which of your subsystem needs to be modified. I do know that icewm has no way to infer that these windows are related, because those windows don't carry the required informational window properties to do so. So it is free to assign focus to whatever window it finds at the top of its stack. That XFCE doesn't exhibit this behavior, is because it organizes its stack differently. Just investigate the four properties I mentioned above and consider that they do carry the required information for a window manager to offer the functionality you want.