maximized state and normal frame size lost after hide/show

Eirik Byrkjeflot Anonsen eirik at eirikba.org
Sat Aug 15 05:01:49 PDT 2015


Cosmin Apreutesei <cosmin.apreutesei at gmail.com> writes:

>> Aha.
>>
>> XWithdrawWindow() basically tells the windowmanager: "please forget about
>> this window. I'll now re-use it for entirely different purposes"
>
> I see. So the WM removes the state because it thinks I'm done with the
> window. I have to find another way then.
>
>> The correct solution depends on what you're trying to do,
>
> I'm trying to hide a window and then later be able to put it back it
> in its previous state (that includes maximized state).
>
> I'll try XUnmapWindow() and send UnmapNotify myself like Qt does, see
> how that goes.
>
>> FYI, X11 is not an API but a protocol.
>
> Well, I think this is a false dichotomy. It's not like I have a
> problem with the wire format :) Besides, that's not even technically
> true if you want to use OpenGL these days.
>
>> APIs like Xlib or xcb implement it
>> and user code would rather use toolkits like Qt, gtk, fltk, ... which more
>> or less nicely abtract the usual tasks.
>
> That's the advice I see everywhere. "Hey, X is not for you, so you'd
> better swallow up a 50MB pile of C++ whose build system alone has more
> LOC that your entire X backend will ever have.". Well, I don't buy it.
> Just look at the X backends in Qt, GLFW, SDL, Chromium, etc. it's a
> battlefield. Doesn't look like these will end my pains automatically.
> They look more like a big rug to sweep X under to me :)

Yes, proper toolkits have a lot of code, partially to deal with all the
weird things programmers want to do, and partially to deal with all the
idiosyncrasies of making that actually work on most users' systems.
Cross-platform toolkits add another mess to try to make completely
different systems look more-or-less the same to the programmer.

Most programmers, particularly for smallish projects, only use a small
part of all the things some toolkits offer, and if you only want to make
things work on a single system setup (e.g. Unity on Ubuntu-15.04) then
you can ignore most of the complexity and using Xlib directly may
possibly make sense. (Oh, and I assume you intend to only support
english language both for input and output.)

On the other hand, if you want to make things work for most users, you
will have to consider that they may be running debian 6 or fedora 22 or
ubuntu 17.10. Maybe they will be running Gnome or xmonad as window
manager. At this point it is really much, much easier to let a
well-tested toolkit deal with all of those problems.

Sure, it is easier on windows. There's only one version of windows
(unless you want to support XP, Vista, Windows 7, Windows 8 and Windows
10), and windows only have a single WM (Well, one per version of
windows, anyway. But there's generally not a lot of difference between
them.) So it makes some sense to code for only a single system there.

>>> function restore()
>>>    if minimized() then
>>>       unminimize()
>>>    elseif maximized() then
>>>       unmaximize()
>>>    end
>>> end
>>>
>>> If that's not provided by the API already, how can I possibly
>>> implement the above with an async API?
>>
>>
>> I'm not actually sure where you see an async problem in the above -
>
> Well, what does the following sequence do with an async API on a
> maximized window that is also minimized?
>
>     restore()
>     restore()
>
>  - with an async API the second call will go through the first branch
> since the window wasn't unminimized yet;
>  - with a blocking API it would do what you expect;
>  - with an async API that implements restore() itself as a single
> command it would also do what you expect.
>
> The fact that you didn't see any problem with that code should be
> evidence of how non-intuitive async APIs are. You simply can't mix
> commands with queries with async APIs (incidentally this is why grabs
> i.e. command queues were invented but they're limited to
> mouse/keyboard).
>
>> if you want to wait for a reaction of the window manager process, you obviously need to wait for that
>
> This is what I'm doing now (empty-the-queue, issue-the-command,
> poll-until-specific-event) but:
>
>  - if the event I'm waiting for doesn't come my app will block forever.
>  - discarding events while waiting might invalidate any tracked state
> (like the window's normal position that we discussed before).
>
> I just don't feel the robustness, you know :)

Yes, this part is complex. If you really need to have commands that
behave differently depending on volatile global state, async queries
aren't going to cut it. However, I believe you hardly ever have a real
use for that. And then the cost of supporting it just isn't worth it.

For your specific case, why are you calling restore() twice in a row?
Did you really intend to disable both maximize and minimize? Then why
not have a restore_all() that does both? Or do you really have two
independent pieces of code that both wants to "restore", but doesn't
really care whether that leaves the window minimized or not? Then why is
it a problem that it is left in the minimized state?

>> You're confusing things here in that X11 is, as mentioned, NOT an API and
>> Xlib is a very low-level API. It's not meant to be "simple".
>
> Nice try :) First, low-level APIs don't have to be complex, they can
> be simple and powerful. Second, you can't just call something bad
> "complex" and hope people won't notice the difference and leave you
> alone :)

I think Thomas meant "simple" as in "providing high-level abstractions
for programmers" rather than "simple" in contrast to "complex". There is
no doubt that both X11 and Xlib have issues. But X11 is actually not
very complex. There are only a small number of pretty basic commands.
Xlib is more complex, as it does provide some high-level abstractions.
But it isn't really complex in itself either. The complexity arises when
you try to implement all the policy protocols yourself using only Xlib.
The policy protocols *are* complex, mostly because they let the WMs have
a lot of leeway in what they implement and how they implement it.

> X is bad because it talks to both clients (toolkits, apps) and WMs
> using the same API, when in fact clients should only ever talk to WMs
> and shouldn't even be able to connect to X.

But if you only talk to the WM you would never be able to render
anything into the client area of your window. Ok, so you mean only talk
to the WM and some painting library. And maybe some library that
provides cut-and-paste data. And maybe another library for
drag-and-drop.

> Clients would then target
> WMs and would be able to use specific features of each WM like the
> ability to maximize a window, or the ability to create a notification
> icon or an OSX-style top-edge menu bar, or the ability to use
> on-screen input methods.

Do you really think this is a good idea? It would mean that if you write
your application for Unity, it will only work on Unity. You want to make
it work with Gnome, you will have to provide a separate implementation
for that. And then another one for Kde. And another for fvwm. And
another for ion3. And another for xmonad. Etc.

Of course, we could abstract out the common behaviours of all WMs in a
single protocol, so that each application can signal its intentions to
the WM, and then each WM can deal with that as it deems best. Oh look,
that's actually what we have :)


> You see, it's fine that X is all mechanism
> and no policy. Problem is, **user interaction is all about policy**.

Right. And if you try to force your policy on the user against the
user's wishes and the WM's design, it will be hard to make that work.
Maybe I misread you, but I feel that you have some specific behaviour
you want, and this is not part of the common WM behaviours. In that
case, what you are doing is trying to force an unsupported policy on the
user. I understand that sometimes that is actually what you want. I have
been there myself. But I remain unconvinced that it is a good idea to do
it, as it tends to cause problems in WMs you haven't considered.

Personally, I find the advantage of this design is pretty clear: It
means we actually have quite a few WMs with quite different policies.
And it mostly works. Generally speaking it is only the applications that
insist on trying to force specific policies on the users that break in
non-standard WMs.

Or to put it another way: If X had defined policy, we wouldn't have any
Gnome, Kde, awesome or ratpoison. We would have only mwm. If we were
lucky. Freeing the WM from the display server has enabled the
development of alternative policies.

(Or even a third point of view: This puts the burden and ability to come
up with new, useful policies in the WM. The alternative is that
applications have the ability to make up their own policies. But if the
WMs create new policies, then they apply to all applications in a
unified and useful manner. If applications do it, then these new
policies will only work for some applications, and typically differently
for each. The counter to that is that applications are usually where the
usefulness of new policies become apparent, so they actually have the
ability to invent them. I think there is some truth to that.)

> If X would've been architected that way, Mir wouldn't even happen.
> Here them out: "we think that the handling of input methods should be
> reflected in the display server protocol, too. As another example, we
> consider the shell integration parts of the protocol as privileged and
> we'd rather avoid having any sort of shell behavior defined in the
> client facing protocol."
>
> Don't get me wrong, I don't think Mir folks
> know what they're doing any more than Wayland folks do because I don't
> think that either team has been much on the other side of their APIs
> to really know how it feels, i.e. it doesn't look like they design
> these APIs from user code... but what do I know about any of this :)

While that is a reasonable point, I think the infrastructure should not
itself focus on programmer-friendly APIs. Instead they should focus on
flexibility and efficiency, so that it is possible to make
programmer-friendly APIs on top of it. Remember the old saying about
making user-friendly interfaces on top of fast code vs fast interfaces
on top of slow code.

eirik


More information about the xorg mailing list