mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 22:10:08 +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>
|
2007-10-17 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* gtk/Makefile.am (libgtk_win32_2_0_la_LDFLAGS): Move -Wl,-luuid
|
* gtk/Makefile.am (libgtk_win32_2_0_la_LDFLAGS): Move -Wl,-luuid
|
||||||
|
@ -1266,6 +1266,37 @@ apply_filters (GdkWindow *window,
|
|||||||
return result;
|
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
|
static gboolean
|
||||||
gdk_window_is_ancestor (GdkWindow *ancestor,
|
gdk_window_is_ancestor (GdkWindow *ancestor,
|
||||||
GdkWindow *window)
|
GdkWindow *window)
|
||||||
@ -2826,16 +2857,18 @@ gdk_event_translate (MSG *msg,
|
|||||||
{
|
{
|
||||||
SetForegroundWindow (GDK_WINDOW_HWND (impl->transient_owner));
|
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;
|
return_val = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3331,6 +3364,49 @@ gdk_event_translate (MSG *msg,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_ACTIVATE:
|
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
|
/* Bring any tablet contexts to the top of the overlap order when
|
||||||
* one of our windows is activated.
|
* one of our windows is activated.
|
||||||
* NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP
|
* 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->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
||||||
impl->extension_events_selected = FALSE;
|
impl->extension_events_selected = FALSE;
|
||||||
impl->transient_owner = NULL;
|
impl->transient_owner = NULL;
|
||||||
|
impl->transient_children = NULL;
|
||||||
|
impl->num_transients = 0;
|
||||||
|
impl->changing_state = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -831,6 +834,7 @@ _gdk_windowing_window_destroy (GdkWindow *window,
|
|||||||
{
|
{
|
||||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||||
GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
|
GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||||
|
|
||||||
@ -840,6 +844,19 @@ _gdk_windowing_window_destroy (GdkWindow *window,
|
|||||||
if (private->extension_events != 0)
|
if (private->extension_events != 0)
|
||||||
_gdk_input_window_destroy (window);
|
_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 */
|
/* Remove ourself from our transient owner */
|
||||||
if (window_impl->transient_owner != NULL)
|
if (window_impl->transient_owner != NULL)
|
||||||
{
|
{
|
||||||
@ -1929,6 +1946,8 @@ gdk_window_set_transient_for (GdkWindow *window,
|
|||||||
{
|
{
|
||||||
HWND window_id, parent_id;
|
HWND window_id, parent_id;
|
||||||
GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
|
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));
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||||
|
|
||||||
@ -1951,7 +1970,32 @@ gdk_window_set_transient_for (GdkWindow *window,
|
|||||||
return;
|
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
|
/* This changes the *owner* of the window, despite the misleading
|
||||||
* name. (Owner and parent are unrelated concepts.) At least that's
|
* name. (Owner and parent are unrelated concepts.) At least that's
|
||||||
@ -2923,7 +2967,7 @@ QueryTree (HWND hwnd,
|
|||||||
gint *nchildren)
|
gint *nchildren)
|
||||||
{
|
{
|
||||||
guint i, n;
|
guint i, n;
|
||||||
HWND child;
|
HWND child = NULL;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
do {
|
do {
|
||||||
@ -3407,7 +3451,7 @@ gdk_window_set_modal_hint (GdkWindow *window,
|
|||||||
|
|
||||||
private->modal_hint = modal;
|
private->modal_hint = modal;
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
/* Not sure about this one.. -- Cody */
|
/* Not sure about this one.. -- Cody */
|
||||||
if (GDK_WINDOW_IS_MAPPED (window))
|
if (GDK_WINDOW_IS_MAPPED (window))
|
||||||
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (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));
|
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_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s\n",
|
||||||
GDK_WINDOW_HWND (window),
|
GDK_WINDOW_HWND (window),
|
||||||
skips_taskbar ? "TRUE" : "FALSE"));
|
skips_taskbar ? "TRUE" : "FALSE"));
|
||||||
|
@ -88,6 +88,9 @@ struct _GdkWindowImplWin32
|
|||||||
gboolean extension_events_selected;
|
gboolean extension_events_selected;
|
||||||
|
|
||||||
GdkWindow *transient_owner;
|
GdkWindow *transient_owner;
|
||||||
|
GSList *transient_children;
|
||||||
|
gint num_transients;
|
||||||
|
gboolean changing_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWindowImplWin32Class
|
struct _GdkWindowImplWin32Class
|
||||||
|
Loading…
Reference in New Issue
Block a user