I thought I could get away with just unrealizing the
window, but it turns out that gtk_window_hide() is the
place where we remove grabs when a modal dialog goes
away, so we ended up with stuck grabs.
Nested main loops are bad, as they introduce layers of complexity caused
by the potential re-entrancy in the case of multiple event sources, like
IPC, threads, etc. Additionally, the programming model they provide—stop
the world while spinning a new loop—does not conform to the event-driven
model employed by GTK.
Replace it with an explicit nested main loop, as we need to block the
signal handler currently being emitted depending on the response of the
overwrite confirmation dialog.
This is a bit of a hack, and the only reason we need it is that the
print dialog will load the last used path as the output file name, when
printing to a file; this means that, in theory, it would be possible to
press Print without selecting a file, and accidentally overwriting an
existing file.
It would be much simpler if we did not store the last used path, and
always explicitly asked the user to select a file; this would avoid
destructive actions, and would allow us to rely on the overwrite
confirmation dialog right inside the file chooser.
Either use the "response" signal for dialogs that are already modal, or
use an explicit nested loop for tests that rely on the response id being
available in sequence.
Nested main loops are bad, as they introduce layers of complexity caused
by the potential re-entrancy in the case of multiple event sources, like
IPC, threads, etc. Additionally, the programming model they provide—stop
the world while spinning a new loop—does not conform to the event-driven
model employed by GTK.
Let keyboard/pointer paths handle their own events, and find the
current focus. The event will be propagated through instead of
being just emitted on the toplevel.
This makes it handled throughout all the gestures that want to
know about it.
Tracking of those broke sometime along the gdk cleanups, so we
started missing some GDK_GRAB_BROKEN events from being emitted
(eg. after a button press/implicit grab triggers an active grab).
Implicit grabs are only added if there's no prior grab (either
implicit through other button presses, or explicit), in order to
keep accounting correct, make those prevail.
It is unreliable to use the widget dom api to locate
action widgets. For example in a headerbar, they might
be deeper in the hierarchy, with boxes in between.
Therefore, make GtkDialog keep a list of action widgets,
and use that when operating on action widgets.