|
|
Home » U++ Library support » TopWindow&PopUp, TrayIcon » Problems with CursorImage/Popups/Frames on X11
Problems with CursorImage/Popups/Frames on X11 [message #12963] |
Fri, 30 November 2007 17:09 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
To cut a long story short, because of some missing windowing events in X11 (notable the equivalent of WM_EXITSIZEMOVE) I've ended up in a position where the only solution to a problem is to imitate a window using a popup. How they expect you to be able to implement anything clever in X11 with such an inadequate messaging system I have no idea
This means I have to implement moving/resizing of the popup, which works fine. What doesn't work is setting the cursor icons. The SizeVert/SizeHorz icons appear when you mouse over the frames at first, but after you move/resize the window the popup seems to stop recieving MOUSEMOVE events to FrameMouseEvent. Additionally, while the popup has mouse capture my CursorImage overload is returning the correct image, but the cursor remains as an arrow.
I've also tried to use OverrideCursor with no effect.
Everything works correctly when the Ctrl is not a popup, so it must be something to do with this.
I've attached my test project and I'd really appreciate it if you'd have a look as I've completely run out of ideas. Sorry to give such a complex test case.
Edit: Click 'OK' on the first window to open the popup.
Cheers,
James
[Updated on: Fri, 30 November 2007 17:18] Report message to a moderator
|
|
|
Re: Problems with CursorImage/Popups/Frames on X11 [message #12999 is a reply to message #12963] |
Tue, 04 December 2007 15:24 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
mrjt wrote on Fri, 30 November 2007 11:09 | To cut a long story short, because of some missing windowing events in X11 (notable the equivalent of WM_EXITSIZEMOVE) I've ended up in a position where the only solution to a problem is to imitate a window using a popup. How they expect you to be able to implement anything clever in X11 with such an inadequate messaging system I have no idea
This means I have to implement moving/resizing of the popup, which works fine. What doesn't work is setting the cursor icons. The SizeVert/SizeHorz icons appear when you mouse over the frames at first, but after you move/resize the window the popup seems to stop recieving MOUSEMOVE events to FrameMouseEvent. Additionally, while the popup has mouse capture my CursorImage overload is returning the correct image, but the cursor remains as an arrow.
I've also tried to use OverrideCursor with no effect.
Everything works correctly when the Ctrl is not a popup, so it must be something to do with this.
I've attached my test project and I'd really appreciate it if you'd have a look as I've completely run out of ideas. Sorry to give such a complex test case.
Edit: Click 'OK' on the first window to open the popup.
Cheers,
James
|
Well, technically, the problem is that SetCapture does not work correctly for Popup in X11. While that could be fixed (barely), the real trouble is that you CANNOT use popup as main window in X11. The real reason is that X11 window manager knows nothing about popups, therefore clicking on any other windows (outside your app) is not able to change popup's Z.
Mirek
|
|
|
|
Re: Problems with CursorImage/Popups/Frames on X11 [message #13090 is a reply to message #13024] |
Mon, 10 December 2007 17:37 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
I've found a possible solution to this:
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MWM_HINTS_ELEMENTS 5
typedef struct {
uint32_t flags;
uint32_t functions;
uint32_t decorations;
int32_t input_mode;
uint32_t status;
} MWMHints;
...
MWMHints mwmhints;
Atom prop;
memset(&mwmhints, 0, sizeof(mwmhints));
prop = XInternAtom(Xdisplay, "_MOTIF_WM_HINTS", false);
mwmhints.flags = MWM_HINTS_DECORATIONS;
mwmhints.decorations = 0;
XChangeProperty(Xdisplay, wnd.GetWindow(), prop, prop, 32, PropModeReplace,
(unsigned char *) &mwmhints,
PROP_MWM_HINTS_ELEMENTS);
... This tells the Window Manager not to add decorations to the window which allows me to add my own without redirecting any events. It uses Motif hints, but these are allegedly supported by most WMs. It certainly works on KDE.
|
|
|
Re: Problems with CursorImage/Popups/Frames on X11 [message #13091 is a reply to message #13090] |
Mon, 10 December 2007 18:06 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
mrjt wrote on Mon, 10 December 2007 11:37 | I've found a possible solution to this:
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MWM_HINTS_ELEMENTS 5
typedef struct {
uint32_t flags;
uint32_t functions;
uint32_t decorations;
int32_t input_mode;
uint32_t status;
} MWMHints;
...
MWMHints mwmhints;
Atom prop;
memset(&mwmhints, 0, sizeof(mwmhints));
prop = XInternAtom(Xdisplay, "_MOTIF_WM_HINTS", false);
mwmhints.flags = MWM_HINTS_DECORATIONS;
mwmhints.decorations = 0;
XChangeProperty(Xdisplay, wnd.GetWindow(), prop, prop, 32, PropModeReplace,
(unsigned char *) &mwmhints,
PROP_MWM_HINTS_ELEMENTS);
... This tells the Window Manager not to add decorations to the window which allows me to add my own without redirecting any events. It uses Motif hints, but these are allegedly supported by most WMs. It certainly works on KDE.
|
Hm, good find!
Potentially very useful
I guess we should add something like "DecorationLess" to TopWindow?
Mirek
|
|
|
|
|
Re: Problems with CursorImage/Popups/Frames on X11 [message #13106 is a reply to message #13093] |
Tue, 11 December 2007 12:45 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
After some more experimentation I would advise against using this method, it's non-standard and KDE doesn't seem to cope with window redrawing very well.
There is some good news though . Did you know that if you call Popup on a TopWindow then mouse capture works correctly? I would guess that this is because of something happenning in TopWindow::EventProc. There is still some sort of problem with the popup taking capture on opening but this may be either due to the special popup grabbing code or an error in my code. I've attached a modified version of my package to illustrate this (click OK on first window, then OK on the popup).
The only problem that remains is the persistence of the popup when the main window is minimised, but it seems that this shouldn't be too hard to fix.
Additionally, I believe there is a mistake in TopWindow::SyncCaption:
if(GetOwner())
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_DIALOG");
if(tool)
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_TOOLBAR");
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_NORMAL");
should be:
if(tool)
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_TOOLBAR");
if(GetOwner())
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_DIALOG");
wina[n++] = XAtom("_NET_WM_WINDOW_TYPE_NORMAL");
As the window types should be listed in order of preference the TOOLBAR type should go first.
James
[Updated on: Tue, 11 December 2007 12:45] Report message to a moderator
|
|
|
|
|
|
Re: Problems with CursorImage/Popups/Frames on X11 [message #13380 is a reply to message #13378] |
Thu, 03 January 2008 18:29 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
That was the first thing I tried
Problem is that Upp (or indeed any client app) doesn't get notified of mouse events in the title bar since it's technically a different window. The only alternative is to call XQueryPointer which has two further problems:
- Knowing the mouse state wouldn't be enough since there is no way of telling if the XConfigureNotify is from a user action. You would have to guess at the size of the decoration and see if the mouse is in it.
- It requires Server<-->Client communication, which I believe should be avoided on such a frequent event.
Please suggest any other ideas, but I'm reasonably sure it's not possible. I've spent quite a lot of time looking at this, logging events etc.
James
[Updated on: Thu, 03 January 2008 18:32] Report message to a moderator
|
|
|
Re: Problems with CursorImage/Popups/Frames on X11 [message #13688 is a reply to message #13380] |
Tue, 22 January 2008 10:52 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
Well, turns out I was completely wrong and it *is* possible (at least on KDE) to implement X11 docking with native windows. You have to SetFocus on the window when it's moved so that X11 passes back focus when the move stops. It's pure luck that I did that *and* had an EventDump going at the same time
However, during my studies I did find the solution to two of the problems I was having with using pop-ups as main windows.
1) CursorImage not working. In X11Wnd.cpp (ln. 590, SetMouseCursor) there is the following code:
Quote: | if(IsPopUp()) {
Ctrl *tw = GetTopWindow();
if(tw)
w = tw->GetWindow();
w = GetTopCtrl()->GetWindow();
}
| This effectively passes all CursorImage events to the owner of the pop-up, and commenting it out makes them work correctly. Presumably there is a good reason for this, but I can't think of a case where this would be necessary at the cost of breaking the behaviour of all other pop-ups. Could it be removed?
2) Popups not overlapping each other properly (not moving to foreground). This can be fixed by replacing line 192/192 in CtrlKbd.cpp (SetFocus0) with:
Quote: | Ptr<Ctrl> topctrl = GetTopCtrl();
Ptr<Ctrl> topwindow = topctrl->IsPopUp() ? topctrl : GetTopWindow();
| This is not a serious issue though, since you can manually call SetForground on the popup when it gets focus.
The only remaining problem is the managing of popups (which I thougt would be the easy bit )- ie hiding/showing in accordance to changing in window stacking order, minization etc. - I'm pretty sure you should do this using CirculateRequest/CirculateNotify, but I can't persuade X11 to send me the events even though the eventmask is correct.
I'm now much happier. Thanks for your help.
[Updated on: Tue, 22 January 2008 13:01] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Sat May 04 15:31:54 CEST 2024
Total time taken to generate the page: 0.02510 seconds
|
|
|