Inline answers.

On Wed, Sep 19, 2018 at 5:56 PM LRN via gtk-list <gtk-list@gnome.org> wrote:

> On 19.09.2018 19:40, Michel Donais wrote:
> > So, the code actually works using append_event, but it might not be the
> > best solution, as the WM_NCDESTROY event is terminal, so merely appending
> > an operation for future consideration is probably not the best case.
> >
>
> This got me thinking: why exactly does GTK not handle WM_DESTROY? That is a
> message that child windows get before they are destroyed, whereas
> WM_NCDESTROY
> is only sent after everything is supposed to be dead.
>

Yep, hence the reason why I'm being more evil to the action, by actually
deleting the object immediately instead of doing it eventually.

Window destruction is pretty much a backwards chicken-and-egg issue and I
do understand why it would be different per platform, as these are time and
context-specific operations, changing how it works depending on the
platform, but you pretty much want to have a seamless integration depending
if you are in X or Win32 or Mac or whatnot. So it's the kind of thing that
will give you a sure headache creating a normalized experience, and will
probably end up pissing off more people than it is supposed. Delay it and
have the wrath of people who need to react immediately to the user
interface change, or react later and feel the wrath of people trying to do
things synchronously when they should be doing most of it asynchronously.
And what about queued operations.


After that i've looked at gdk_x11_window_destroy_notify().
> It checks for the GDK window not being destroyed yet, and if it isn't, the
> window is destroyed (it warns if this is done for a non-foreign window),
> then
> detaches the GDK window from GDK display, clears its grab, if any, and
> unrefs it.
>

The GDK_WINDOW_DESTROYED() (the ->destroyed field) is weird. It is only set
> to
> TRUE by _gdk_window_destroy_hierarchy(), which sets it *after* it calls
> impl->destroy() (which results in XDestroyWindow on X11; i.e. normal
> windows
> are supposed to be XDestroyWindow-ed first, which will cause DestroyNotify,
> which will be handled in gdk_x11_window_destroy_notify(), and only after
> that
> the ->destroyed field will be set to TRUE, which will allow
> GDK_WINDOW_DESTROYED() to evaluate to TRUE). I don't understand why
> gdk_x11_window_destroy_notify() doesn't warn about non-foreign windows
> being
> destroyed all the time.
>

(all of this IMHO - not an GDK X expert) I think the piece of code assumes
you are using a GTK window, which asks for deletion on its own first, and
then, sends the event to the system. Also, the Gdk system grabs the
hierarchical operation first, and proceeds to do it hierarchically on its
own from there. To have the system begging to destroy something internally
without GDK knowing about it and having called it first would be something
quite odd indeed. So by having the foreign window check, you can say "yeah,
this is a foreign window, it's not ours, so it's normal it's being
destroyed through system first, and then we get the notification", where a
non-foreign window would mean someone meddling in Gdk's own business.

At least, this is what is supposed to be seen in GtkMain.c, where the
warning tells you this Destroy operation should never happen, as it
should've already happened for non-foreign windows.



> W32 backend does it differently - it explicitly sets ->destroyed to TRUE
> before
> calling DestroyWindow().
>

>From what I've seen in systems, usually, windows will react to being
destroyed instead of telling it will be destroyed. On my internal system,
my first crude implementation assumed exactly that: calling an operation
should do the operation. I ended up going to the standardized way of doing
things in CWnd, where any operation is done through events instead of done
through direct calls.

That is especially true with the window destruction, where all operations
are done in WM_DESTROY and WM_NCDESTROY, and WM_NOTIFY for child
destruction.

I assume the piece of code is put there because Windows can sometimes
decide to delay its operations, especially if our child window happens to
be owned by another thread. So the queue might not be empty at that point.
I can't tell for sure, but the idea of specifically setting ->destroyed at
that point would make sense in a weird and odd sense of way, so more
operations can know right now we got destroyed and stop even trying.

But it never is set up later on if the system decides to meddle in its Gtk
operations. For me, trying to put a Layout inside an existing HWND, those
meddlings are consistent alas. Even more thinking I can theoretically have
a (please cry) CWnd -> GtkLayout -> CWnd parenting layout. So the child and
the parent could decide to meddle. For Gtk, it's business as usual, though
as it's getting a GObject (Root) -> GtkWindow (Foreign) -> GtkLayout ->
GtkWidget (Foreign). As long as it understands there's Foreign operations
that can happen, I'm happy. And first message was because it wasn't
reacting accordingly.



> What a mess...
>

It is... But then, if you code for Win32 exclusively, it kinds of make
sense. If you code for X exclusively, it's about ok. But if you code for
both, it will not react the same. And we need to drink a lot of courage
juice to try to do the good thing.
_______________________________________________
gtk-list mailing list
gtk-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-list

Reply via email to