setFullScreen maximiseButtonPress weirdness

10 posts / 0 new
Last post
jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
setFullScreen maximiseButtonPress weirdness

I finally got around to to setting up a new Linux environment (Ubuntu 11.10, running under VirtualBox).

The good news is that building went without a hitch. The better news (for me) is that my previously untested Datagram socket extensions worked first try.

However, I get a very strange behavior with the maximise button. Not just on my app, but with the JuceDemo as well.

Initially, resizing works correctly. As does minimize and resume.

The maximize button behaves as expected in that it takes the window full size of the desktop and the graphic for the maximizeButton changes. However, if you try to 'un maximize', you're stuck. The button will change, and the window will very briefly resume width/height (though anchored to upper left corner of screen). Then it will shoot back to full screen. And it's stuck. You can try manually resizing, but shortly after you start the window shoots back to full size.

I did a little spelunking, and it appears the the problem is that a ConfigureNotify event comes in with x,y,w,h set to full screen. The send_event flag in the configure event is true. There only appear to be four XSendEvent calls in juce_linux_Windowing.cpp, and the only one seemingly called (twice) is in the toFront method when the button is clicked.

It's not clear to me why this would generate a synthetic ConfigureNotify event. I vaguely remember a bunch of rules about gravity and relative coordinates with synthetic ConfigureNotify events, but it's been ages since I dealt with XWindow hell.

The native window title bar appears to be broken for maximize as well. The full screen behavior is as expected, with the native title bar vanishing, but the title bar doesn't do the 'popup' for restore.

I'll try to muck with a different gui, like gnome, tomorrow, but since it built clean from the tip, it seemed worth mentioning even though it still isn't clear to me what is going on.

jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
Re: setFullScreen maximiseButtonPress weirdness

Addendum: The native titlebar on the Introjucer appears to work correctly. It is JuceDemo, and especially non native titlebar, that is very weird/stuck on maximize.

jules
Offline
Last seen: 4 hours 48 min ago
Joined: 29 Apr 2013 - 18:37
Re: setFullScreen maximiseButtonPress weirdness

Thanks. Annoyingly I can't test this, since I'm stuck on an older version of Ubuntu after my attempts at getting v11 to work in Parallels were a total failure..

jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
Re: setFullScreen maximiseButtonPress weirdness

No problem. I'll do some more digging when I get a chance. I checked the obvious stuff, like the X Window hints in the Linux setBounds, but didn't get much further.

FWIW, I generally find Parallels great for running Windows on a Mac, but terrible for Linux. VirtualBox is pretty much the opposite, though I've never had much luck with the VB 3D accelleration stuff.

jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
Re: setFullScreen maximiseButtonPress weirdness

OK, I did a little checking with xwininfo and xev. When the window goes full screen, the WM is setting _NET_WM_STATE_FULLSCREEN. While the attribute is set, resizing is temporary, and you get ConfigNotifications forcing back to full size.

I did a quick hack of the setBounds() function inside juce_linux_Windowing.cpp, changing the start of the function to:

    void setBounds (int x, int y, int w, int h, bool isNowFullScreen)
    {
        // transitioning back from fullscreen, we might need to remove
        // the FULLSCREEN window property
        if (fullScreen && (! isNowFullScreen))
        {
            Atom fs = Atoms::getIfExists ("_NET_WM_STATE_FULLSCREEN");
        
            if (fs != None)
            {
                Window root = RootWindow (display, DefaultScreen (display));

                XClientMessageEvent clientMsg;
                clientMsg.display = display;
                clientMsg.window = windowH;
                clientMsg.type = ClientMessage;
                clientMsg.format = 32;
                clientMsg.message_type = Atoms::WindowState;
                clientMsg.data.l[0] = 0;  // Remove
                clientMsg.data.l[1] = fs;
                clientMsg.data.l[2] = 0;
                clientMsg.data.l[3] = 1;  // Normal Source

                ScopedXLock xlock;
                XSendEvent (display, root, false, 
                            SubstructureRedirectMask | SubstructureNotifyMask, 
                            (XEvent*) &clientMsg);
            }
        }

        fullScreen = isNowFullScreen;

This appears to work with Unity and Gnome, with both native and non-native title bars. But I'm not sure this is really where/how to handle it.

jules
Offline
Last seen: 4 hours 48 min ago
Joined: 29 Apr 2013 - 18:37
Re: setFullScreen maximiseButtonPress weirdness

:D

jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
Re: setFullScreen maximiseButtonPress weirdness

Tip fixes seem to work fine. Thanks! One of these days I'll get your style down enough for a no conflict merge (though it was only the (unnecessary) parens around a unary not that got me this time - curse my feeble brain and it's mental block on C++ operator precedence!) ;-)

On a related note, I've just noticed that when the native titlebar is selected, the JuceDemo can be positioned partially offscreen. But when the Juce titlebar is selected, the window can only be positioned so that it is wholly on the display. Was that intentional? If not, I'll put it on my list of things to look at when I get a chance.

Thanks again!

jules
Offline
Last seen: 4 hours 48 min ago
Joined: 29 Apr 2013 - 18:37
Re: setFullScreen maximiseButtonPress weirdness

Quote:
One of these days I'll get your style down enough for a no conflict merge (though it was only the (unnecessary) parens around a unary not that got me this time - curse my feeble brain and it's mental block on C++ operator precedence!)

It was pretty damn close! I generally avoid extra brackets when the '!' is the last element of the expression, e.g. (a && !b), because there's no way that could be misinterpreted. But when it comes earlier, I do usually add them, e.g. ((!a) && b), because (!a && b) just looks ambiguous to me..

jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
Re: setFullScreen maximiseButtonPress weirdness

FWIW, I put a Logger:: call in the Linux SetBounds and it seems clear that the Window Manager is keeping the Juce title bar window completely onscreen. The requested X and Y coordinates keep moving. SetBounds isn't generally called with the native titlebar. Presumably it has something to do with Hints or Attributes, but I just don't have any time to dig deeper right now.

jfitzpat
Offline
Last seen: 1 hour 14 min ago
Joined: 10 Jan 2012 - 05:29
Re: setFullScreen maximiseButtonPress weirdness

In case anyone finds this thread by search down the road:

I monitored XWindow traffic and the culprit in 'constrained to Window' is _NET_WM_ALLOWED_ACTIONS/_NET_WM_ACTION_CHANGE_DESKTOP.

But the interaction with metacity (? seems to be what Unity/Ubuntu uses by default) is surprisingly complicated. If you drag stock Ubuntu apps slowly, you'll see they briefly 'stick' at the edge of the desktop before moving. I hacked a test to get a Juce (non native title bar) window dragging between workspaces, and it is solvable. But a proper generic 'fix' would be a lot more complicated than I have time/patience for, at least in this lifetime.

Native title bar windows behave correctly (well, consistant with other apps), and Juce title bar windows can at least be dragged between multiple monitors if they are configured as an extended desktop.

If someone else finds a simpler fix, I'd like to hear about it. I'd forgotten how much I hate XWindows...