mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 05:31:07 +00:00
gdk/win32/gdkevents-win32.c Force non-modal transient dialogs to iconify
2007-10-17 Cody Russell <cody@jhu.edu> * gdk/win32/gdkevents-win32.c * gdk/win32/gdkwindow-win32.[ch]: Force non-modal transient dialogs to iconify with their parents on Win32. Maintain a list of transient children, and whenever a window is hidden or restored we now do the same thing to all connected transient windows above and below the current window in the chain. See comment under WM_ACTIVATE for the reasons why. (#164537, #371036, #405178) svn path=/trunk/; revision=18929
This commit is contained in:
parent
e6572dfb95
commit
21d3d60f48
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
2007-10-17 Cody Russell <cody@jhu.edu>
|
||||
|
||||
* gdk/win32/gdkevents-win32.c
|
||||
* gdk/win32/gdkwindow-win32.[ch]: Force non-modal transient dialogs
|
||||
to iconify with their parents on Win32. Maintain a list of transient
|
||||
children, and whenever a window is hidden or restored we now do the
|
||||
same thing to all connected transient windows above and below the
|
||||
current window in the chain. See comment under WM_ACTIVATE for the
|
||||
reasons why. (#164537, #371036, #405178)
|
||||
|
||||
2007-10-17 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/Makefile.am (libgtk_win32_2_0_la_LDFLAGS): Move -Wl,-luuid
|
||||
|
@ -1266,6 +1266,37 @@ apply_filters (GdkWindow *window,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
show_window_recurse (GdkWindow *window, gboolean hide_window)
|
||||
{
|
||||
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
|
||||
GSList *children = impl->transient_children;
|
||||
GdkWindow *child = NULL;
|
||||
|
||||
if (!impl->changing_state)
|
||||
{
|
||||
impl->changing_state = TRUE;
|
||||
|
||||
if (children != NULL)
|
||||
{
|
||||
while (children != NULL)
|
||||
{
|
||||
child = children->data;
|
||||
show_window_recurse (child, hide_window);
|
||||
|
||||
children = g_slist_next (children);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hide_window)
|
||||
ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
|
||||
else
|
||||
ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
|
||||
|
||||
impl->changing_state = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_window_is_ancestor (GdkWindow *ancestor,
|
||||
GdkWindow *window)
|
||||
@ -2826,16 +2857,18 @@ gdk_event_translate (MSG *msg,
|
||||
{
|
||||
SetForegroundWindow (GDK_WINDOW_HWND (impl->transient_owner));
|
||||
}
|
||||
|
||||
if (p_grab_window == window)
|
||||
{
|
||||
gdk_pointer_ungrab (msg->time);
|
||||
}
|
||||
|
||||
if (k_grab_window == window)
|
||||
{
|
||||
gdk_keyboard_ungrab (msg->time);
|
||||
}
|
||||
}
|
||||
|
||||
if (event->any.type == GDK_UNMAP &&
|
||||
p_grab_window == window)
|
||||
gdk_pointer_ungrab (msg->time);
|
||||
|
||||
if (event->any.type == GDK_UNMAP &&
|
||||
k_grab_window == window)
|
||||
gdk_keyboard_ungrab (msg->time);
|
||||
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
@ -3331,6 +3364,49 @@ gdk_event_translate (MSG *msg,
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
;
|
||||
|
||||
/*
|
||||
* On Windows, transient windows will not have their own taskbar entries.
|
||||
* Because of this, we must hide and restore groups of transients in both
|
||||
* directions. That is, all transient children must be hidden or restored
|
||||
* with this window, but if this window's transient owner also has a
|
||||
* transient owner then this window's transient owner must be hidden/restored
|
||||
* with this one. And etc, up the chain until we hit an ancestor that has no
|
||||
* transient owner.
|
||||
*
|
||||
* It would be a good idea if applications don't chain transient windows
|
||||
* together. There's a limit to how much evil GTK can try to shield you
|
||||
* from.
|
||||
*/
|
||||
GdkWindow *tmp_window = NULL;
|
||||
GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
|
||||
|
||||
while (tmp_impl->transient_owner != NULL)
|
||||
{
|
||||
tmp_window = tmp_impl->transient_owner;
|
||||
tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (tmp_window)->impl);
|
||||
}
|
||||
|
||||
if (tmp_window == NULL)
|
||||
tmp_window = window;
|
||||
|
||||
if (LOWORD (msg->wParam) == WA_INACTIVE && HIWORD (msg->wParam))
|
||||
{
|
||||
if (!tmp_impl->changing_state)
|
||||
{
|
||||
show_window_recurse (tmp_window, TRUE);
|
||||
}
|
||||
}
|
||||
else if (LOWORD (msg->wParam) == WA_ACTIVE && HIWORD (msg->wParam))
|
||||
{
|
||||
if (!tmp_impl->changing_state)
|
||||
{
|
||||
show_window_recurse (tmp_window, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Bring any tablet contexts to the top of the overlap order when
|
||||
* one of our windows is activated.
|
||||
* NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP
|
||||
|
@ -107,6 +107,9 @@ gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
|
||||
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
||||
impl->extension_events_selected = FALSE;
|
||||
impl->transient_owner = NULL;
|
||||
impl->transient_children = NULL;
|
||||
impl->num_transients = 0;
|
||||
impl->changing_state = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -831,6 +834,7 @@ _gdk_windowing_window_destroy (GdkWindow *window,
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
|
||||
GSList *tmp;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
@ -840,6 +844,19 @@ _gdk_windowing_window_destroy (GdkWindow *window,
|
||||
if (private->extension_events != 0)
|
||||
_gdk_input_window_destroy (window);
|
||||
|
||||
/* Remove all our transient children */
|
||||
tmp = window_impl->transient_children;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
GdkWindow *child = tmp->data;
|
||||
GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
|
||||
|
||||
child_impl->transient_owner = NULL;
|
||||
tmp = g_slist_next (tmp);
|
||||
}
|
||||
g_slist_free (window_impl->transient_children);
|
||||
window_impl->transient_children = NULL;
|
||||
|
||||
/* Remove ourself from our transient owner */
|
||||
if (window_impl->transient_owner != NULL)
|
||||
{
|
||||
@ -1929,6 +1946,8 @@ gdk_window_set_transient_for (GdkWindow *window,
|
||||
{
|
||||
HWND window_id, parent_id;
|
||||
GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
|
||||
GdkWindowImplWin32 *parent_impl = NULL;
|
||||
GSList *item;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
@ -1951,7 +1970,32 @@ gdk_window_set_transient_for (GdkWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
window_impl->transient_owner = parent;
|
||||
if (parent == NULL)
|
||||
{
|
||||
GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
|
||||
if (trans_impl->transient_children != NULL)
|
||||
{
|
||||
item = g_slist_find (trans_impl->transient_children, window);
|
||||
item->data = NULL;
|
||||
trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
|
||||
trans_impl->num_transients--;
|
||||
|
||||
if (!trans_impl->num_transients)
|
||||
{
|
||||
trans_impl->transient_children = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
window_impl->transient_owner = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
|
||||
|
||||
parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
|
||||
parent_impl->num_transients++;
|
||||
window_impl->transient_owner = parent;
|
||||
}
|
||||
|
||||
/* This changes the *owner* of the window, despite the misleading
|
||||
* name. (Owner and parent are unrelated concepts.) At least that's
|
||||
@ -2923,7 +2967,7 @@ QueryTree (HWND hwnd,
|
||||
gint *nchildren)
|
||||
{
|
||||
guint i, n;
|
||||
HWND child;
|
||||
HWND child = NULL;
|
||||
|
||||
n = 0;
|
||||
do {
|
||||
@ -3407,7 +3451,7 @@ gdk_window_set_modal_hint (GdkWindow *window,
|
||||
|
||||
private->modal_hint = modal;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* Not sure about this one.. -- Cody */
|
||||
if (GDK_WINDOW_IS_MAPPED (window))
|
||||
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
|
||||
@ -3426,6 +3470,9 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
// ### TODO: Need to figure out what to do here.
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s\n",
|
||||
GDK_WINDOW_HWND (window),
|
||||
skips_taskbar ? "TRUE" : "FALSE"));
|
||||
|
@ -88,6 +88,9 @@ struct _GdkWindowImplWin32
|
||||
gboolean extension_events_selected;
|
||||
|
||||
GdkWindow *transient_owner;
|
||||
GSList *transient_children;
|
||||
gint num_transients;
|
||||
gboolean changing_state;
|
||||
};
|
||||
|
||||
struct _GdkWindowImplWin32Class
|
||||
|
Loading…
Reference in New Issue
Block a user