diff --git a/ChangeLog b/ChangeLog index 763281b512..a4d41890b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,56 @@ +2008-10-04 Tor Lillqvist + + Bug 132501 - Make utility window translate to tool window in win32 + + Implement the utility window type hint. Such windows are kept on + top of other windows. Makes GIMP's toolbox and dock windows behave + more like in GNOME under metacity. Apply the same logic also to + windows marked with the dialog window type hint, and windows that + are transient for some other window. I'll call such windows + "transient-type" below. + + * gdk/win32/gdkevents-win32.c (doesnt_want_key): Drop unused + variables. + + (ensure_stacking_on_unminimize) + (ensure_stacking_on_window_pos_changing) + (ensure_stacking_on_activate_app): New functions to implement the + desired stacking order. Make sure that a window that is not + transient-type stays below any transient-type windows of the + application. When activating a non-transient-type window make sure + it rises as high as possible. + + (gdk_event_translate): Call above functions on + WM_WINDOWPOSCHANGING, WM_ACTIVATEAPP and on WM_SIZE when + unminimizing. Improve debugging printout. + + * gdk/win32/gdkwindow-win32.c (get_effective_window_decorations): + Handle utility windows like toolbar windows. + + (gdk_window_new_internal) (update_style_bits): Give utility + windows the WS_EX_TOOLWINDOW extended style. + + (gdk_window_set_title): If debugging "misc" or "events", make the + handle of top-level windows show up in their title bars. Very + useful when looking at debugging output. + + (gdk_window_set_keep_above) (gdk_window_set_keep_below) + (gdk_window_set_modal_hint) (gdk_window_set_skip_taskbar_hint) + (gdk_window_set_skip_pager_hint): Add and improve debugging + printout. + + (gdk_window_set_type_hint): Print hint symbolically in GDK_NOTE(). + +2008-10-04 Tor Lillqvist + + * gdk/win32/gdkmain-win32.c (_gdk_win32_window_exstyle_to_string) + (_gdk_win32_window_pos_bits_to_string): New debugging printout + functions. Decode the WS_EX_* and SWP_* bits. + + * gdk/win32/gdkprivate-win32.h: Declare them. Define + GDK_DEBUG_MISC_OR_EVENTS for use in GDK_NOTE() to match either + "misc" or "events". + 2008-10-03 Matthias Clasen * gtk/gtkmodules.c (_gtk_modules_settings_changed): Add some diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 356d44c6f9..de104d3f02 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -292,11 +292,7 @@ _gdk_win32_window_procedure (HWND hwnd, retval = inner_window_procedure (hwnd, message, wparam, lparam); debug_indent -= 2; -#ifdef _WIN64 - GDK_NOTE (EVENTS, g_print (" => %I64d%s", retval, (debug_indent == 0 ? "\n" : ""))); -#else - GDK_NOTE (EVENTS, g_print (" => %ld%s", retval, (debug_indent == 0 ? "\n" : ""))); -#endif + GDK_NOTE (EVENTS, g_print (" => %I64d%s", (gint64) retval, (debug_indent == 0 ? "\n" : ""))); return retval; } @@ -1781,9 +1777,6 @@ static gboolean doesnt_want_key (gint mask, MSG *msg) { - GdkWindow *modal_current = _gdk_modal_current (); - GdkWindow *window = (GdkWindow *) gdk_win32_handle_table_lookup ((GdkNativeWindow)msg->hwnd); - return (((msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) && !(mask & GDK_KEY_RELEASE_MASK)) || ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) && @@ -2106,6 +2099,143 @@ generate_button_event (GdkEventType type, _gdk_event_button_generate (_gdk_display, event); } +static void +ensure_stacking_on_unminimize (MSG *msg) +{ + HWND rover; + HWND lowest_transient = NULL; + + rover = msg->hwnd; + while ((rover = GetNextWindow (rover, GW_HWNDNEXT))) + { + GdkWindow *rover_gdkw = gdk_win32_handle_table_lookup (rover); + + /* Checking window group not implemented yet */ + if (rover_gdkw) + { + GdkWindowImplWin32 *rover_impl = + (GdkWindowImplWin32 *)((GdkWindowObject *)rover_gdkw)->impl; + + if (rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY || + rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG || + rover_impl->transient_owner != NULL) + { + lowest_transient = rover; + } + } + } + if (lowest_transient != NULL) + { + GDK_NOTE (EVENTS, g_print (" restacking: %p", lowest_transient)); + SetWindowPos (msg->hwnd, lowest_transient, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + } +} + +static gboolean +ensure_stacking_on_window_pos_changing (MSG *msg, + GdkWindow *window) +{ + GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)((GdkWindowObject *) window)->impl; + WINDOWPOS *windowpos = (WINDOWPOS *) msg->lParam; + + if (GetActiveWindow () == msg->hwnd && + impl->type_hint != GDK_WINDOW_TYPE_HINT_UTILITY && + impl->type_hint != GDK_WINDOW_TYPE_HINT_DIALOG && + impl->transient_owner == NULL) + { + /* Make sure the window stays behind any transient-type windows + * of the same window group. + * + * If the window is not active and being activated, we let + * Windows bring it to the top and rely on the WM_ACTIVATEAPP + * handling to bring any utility windows on top of it. + */ + HWND rover; + gboolean restacking; + + rover = windowpos->hwndInsertAfter; + restacking = FALSE; + while (rover) + { + GdkWindow *rover_gdkw = gdk_win32_handle_table_lookup (rover); + + /* Checking window group not implemented yet */ + if (rover_gdkw) + { + GdkWindowImplWin32 *rover_impl = + (GdkWindowImplWin32 *)((GdkWindowObject *)rover_gdkw)->impl; + + if (rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY || + rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG || + rover_impl->transient_owner != NULL) + { + restacking = TRUE; + windowpos->hwndInsertAfter = rover; + } + } + rover = GetNextWindow (rover, GW_HWNDNEXT); + } + + if (restacking) + { + GDK_NOTE (EVENTS, g_print (" restacking: %p", windowpos->hwndInsertAfter)); + return TRUE; + } + } + return FALSE; +} + +static void +ensure_stacking_on_activate_app (MSG *msg, + GdkWindow *window) +{ + GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)((GdkWindowObject *) window)->impl; + + if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY || + impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG || + impl->transient_owner != NULL) + { + SetWindowPos (msg->hwnd, HWND_TOP, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + return; + } + + if (IsWindowVisible (msg->hwnd) && + gdk_win32_handle_table_lookup (GetActiveWindow ())) + { + /* This window is not a transient-type window and this or some + * other window in this app is the active window. Make sure this + * window is as visible as possible, just below the lowest + * transient-type window of this app. + */ + HWND rover; + + rover = msg->hwnd; + while ((rover = GetNextWindow (rover, GW_HWNDPREV))) + { + GdkWindow *rover_gdkw = gdk_win32_handle_table_lookup (rover); + + /* Checking window group not implemented yet */ + if (rover_gdkw) + { + GdkWindowImplWin32 *rover_impl = + (GdkWindowImplWin32 *)((GdkWindowObject *)rover_gdkw)->impl; + + if (rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY || + rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG || + rover_impl->transient_owner != NULL) + { + GDK_NOTE (EVENTS, g_print (" restacking: %p", rover)); + SetWindowPos (msg->hwnd, rover, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + break; + } + } + } + } +} + static gboolean gdk_event_translate (MSG *msg, gint *ret_valp) @@ -2117,6 +2247,7 @@ gdk_event_translate (MSG *msg, HCURSOR hcursor; BYTE key_state[256]; HIMC himc; + WINDOWPOS *windowpos; GdkEvent *event; @@ -2852,7 +2983,6 @@ gdk_event_translate (MSG *msg, break; case WM_SYNCPAINT: - sync_timer = SetTimer (GDK_WINDOW_HWND (window), 1, 200, sync_timer_proc); @@ -2886,7 +3016,14 @@ gdk_event_translate (MSG *msg, break; case WM_SHOWWINDOW: - GDK_NOTE (EVENTS, g_print (" %d", (int) msg->wParam)); + GDK_NOTE (EVENTS, g_print (" %s %s", + (msg->wParam ? "YES" : "NO"), + (msg->lParam == 0 ? "ShowWindow" : + (msg->lParam == SW_OTHERUNZOOM ? "OTHERUNZOOM" : + (msg->lParam == SW_OTHERZOOM ? "OTHERZOOM" : + (msg->lParam == SW_PARENTCLOSING ? "PARENTCLOSING" : + (msg->lParam == SW_PARENTOPENING ? "PARENTOPENING" : + "???"))))))); if (!(((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK)) break; @@ -2927,7 +3064,6 @@ gdk_event_translate (MSG *msg, break; case WM_SYSCOMMAND: - switch (msg->wParam) { case SC_MINIMIZE: @@ -2970,6 +3106,9 @@ gdk_event_translate (MSG *msg, GdkWindowState withdrawn_bit = IsWindowVisible (msg->hwnd) ? GDK_WINDOW_STATE_WITHDRAWN : 0; + if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_ICONIFIED) + ensure_stacking_on_unminimize (msg); + if (!GDK_WINDOW_DESTROYED (window)) handle_configure_event (msg, window); @@ -3024,7 +3163,33 @@ gdk_event_translate (MSG *msg, KillTimer (NULL, modal_timer); break; - case WM_WINDOWPOSCHANGED : + case WM_WINDOWPOSCHANGING: + GDK_NOTE (EVENTS, g_print (" %s %s %dx%d@%+d%+d now below %p", + _gdk_win32_window_pos_bits_to_string (windowpos->flags), + (windowpos->hwndInsertAfter == HWND_BOTTOM ? "BOTTOM" : + (windowpos->hwndInsertAfter == HWND_NOTOPMOST ? "NOTOPMOST" : + (windowpos->hwndInsertAfter == HWND_TOP ? "TOP" : + (windowpos->hwndInsertAfter == HWND_TOPMOST ? "TOPMOST" : + (sprintf (buf, "%p", windowpos->hwndInsertAfter), + buf))))), + windowpos->cx, windowpos->cy, windowpos->x, windowpos->y, + GetNextWindow (msg->hwnd, GW_HWNDPREV))); + + return_val = ensure_stacking_on_window_pos_changing (msg, window); + break; + + case WM_WINDOWPOSCHANGED: + GDK_NOTE (EVENTS, (windowpos = (WINDOWPOS *) msg->lParam, + g_print (" %s %s %dx%d@%+d%+d", + _gdk_win32_window_pos_bits_to_string (windowpos->flags), + (windowpos->hwndInsertAfter == HWND_BOTTOM ? "BOTTOM" : + (windowpos->hwndInsertAfter == HWND_NOTOPMOST ? "NOTOPMOST" : + (windowpos->hwndInsertAfter == HWND_TOP ? "TOP" : + (windowpos->hwndInsertAfter == HWND_TOPMOST ? "TOPMOST" : + (sprintf (buf, "%p", windowpos->hwndInsertAfter), + buf))))), + windowpos->cx, windowpos->cy, windowpos->x, windowpos->y))); + /* Once we've entered the moving or sizing modal loop, we won't * return to the main loop until we're done sizing or moving. */ @@ -3034,6 +3199,7 @@ gdk_event_translate (MSG *msg, { if (((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK) { + GDK_NOTE (EVENTS, g_print (" do magic")); if (((GdkWindowObject *) window)->resize_count > 1) ((GdkWindowObject *) window)->resize_count -= 1; @@ -3457,11 +3623,17 @@ gdk_event_translate (MSG *msg, break; case WM_ACTIVATE: - + GDK_NOTE (EVENTS, g_print (" %s%s %p", + (LOWORD (msg->wParam) == WA_ACTIVE ? "ACTIVE" : + (LOWORD (msg->wParam) == WA_CLICKACTIVE ? "CLICKACTIVE" : + (LOWORD (msg->wParam) == WA_INACTIVE ? "INACTIVE" : "???"))), + HIWORD (msg->wParam) ? " minimized" : "", + (HWND) msg->lParam)); /* We handle mouse clicks for modally-blocked windows under WM_MOUSEACTIVATE, * but we still need to deal with alt-tab, or with SetActiveWindow() type - * situations. */ - if (is_modally_blocked (window) && msg->wParam == WA_ACTIVE) + * situations. + */ + if (is_modally_blocked (window) && LOWORD (msg->wParam) == WA_ACTIVE) { GdkWindow *modal_current = _gdk_modal_current (); SetActiveWindow (GDK_WINDOW_HWND (modal_current)); @@ -3479,6 +3651,13 @@ gdk_event_translate (MSG *msg, _gdk_input_set_tablet_active (); break; + case WM_ACTIVATEAPP: + GDK_NOTE (EVENTS, g_print (" %s thread: %I64d", + msg->wParam ? "YES" : "NO", + (gint64) msg->lParam)); + + ensure_stacking_on_activate_app (msg, window); + break; /* Handle WINTAB events here, as we know that gdkinput.c will * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c index be02856cf8..498a709261 100644 --- a/gdk/win32/gdkmain-win32.c +++ b/gdk/win32/gdkmain-win32.c @@ -553,7 +553,7 @@ _gdk_win32_window_style_to_string (LONG style) buf[0] = '\0'; #define BIT(x) \ - if (style & WS_ ## x) \ + if (style & WS_ ## x) \ (bufp += sprintf (bufp, "%s" #x, s), s = "|") /* Note that many of the WS_* macros are in face several bits. @@ -585,6 +585,81 @@ _gdk_win32_window_style_to_string (LONG style) return static_printf ("%s", buf); } +gchar * +_gdk_win32_window_exstyle_to_string (LONG style) +{ + gchar buf[1000]; + gchar *bufp = buf; + gchar *s = ""; + + buf[0] = '\0'; + +#define BIT(x) \ + if (style & WS_EX_ ## x) \ + (bufp += sprintf (bufp, "%s" #x, s), s = "|") + + /* Note that many of the WS_EX_* macros are in face several bits. + * Handle just the individual bits here. Sort as in w32api's + * winuser.h. + */ + BIT (ACCEPTFILES); + BIT (APPWINDOW); + BIT (CLIENTEDGE); + BIT (COMPOSITED); + BIT (CONTEXTHELP); + BIT (CONTROLPARENT); + BIT (DLGMODALFRAME); + BIT (LAYERED); + BIT (LAYOUTRTL); + BIT (LEFTSCROLLBAR); + BIT (MDICHILD); + BIT (NOACTIVATE); + BIT (NOINHERITLAYOUT); + BIT (NOPARENTNOTIFY); + BIT (RIGHT); + BIT (RTLREADING); + BIT (STATICEDGE); + BIT (TOOLWINDOW); + BIT (TOPMOST); + BIT (TRANSPARENT); + BIT (WINDOWEDGE); +#undef BIT + + return static_printf ("%s", buf); +} + +gchar * +_gdk_win32_window_pos_bits_to_string (UINT flags) +{ + gchar buf[1000]; + gchar *bufp = buf; + gchar *s = ""; + + buf[0] = '\0'; + +#define BIT(x) \ + if (flags & SWP_ ## x) \ + (bufp += sprintf (bufp, "%s" #x, s), s = "|") + + BIT (DRAWFRAME); + BIT (FRAMECHANGED); + BIT (HIDEWINDOW); + BIT (NOACTIVATE); + BIT (NOCOPYBITS); + BIT (NOMOVE); + BIT (NOSIZE); + BIT (NOREDRAW); + BIT (NOZORDER); + BIT (SHOWWINDOW); + BIT (NOOWNERZORDER); + BIT (NOSENDCHANGING); + BIT (DEFERERASE); + BIT (ASYNCWINDOWPOS); +#undef BIT + + return static_printf ("%s", buf); +} + gchar * _gdk_win32_rop2_to_string (int rop2) { diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 4196b4d576..0d3fe99b98 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -98,6 +98,7 @@ #define GDK_DEBUG_EVENTS_OR_INPUT (GDK_DEBUG_EVENTS|GDK_DEBUG_INPUT) #define GDK_DEBUG_PIXMAP_OR_COLORMAP (GDK_DEBUG_PIXMAP|GDK_DEBUG_COLORMAP) #define GDK_DEBUG_MISC_OR_COLORMAP (GDK_DEBUG_MISC|GDK_DEBUG_COLORMAP) +#define GDK_DEBUG_MISC_OR_EVENTS (GDK_DEBUG_MISC|GDK_DEBUG_EVENTS) #define GDK_TYPE_GC_WIN32 (_gdk_gc_win32_get_type ()) #define GDK_GC_WIN32(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_GC_WIN32, GdkGCWin32)) @@ -311,6 +312,8 @@ gchar *_gdk_win32_line_style_to_string (GdkLineStyle line_style); gchar *_gdk_win32_gcvalues_mask_to_string (GdkGCValuesMask mask); gchar *_gdk_win32_window_state_to_string (GdkWindowState state); gchar *_gdk_win32_window_style_to_string (LONG style); +gchar *_gdk_win32_window_exstyle_to_string (LONG style); +gchar *_gdk_win32_window_pos_bits_to_string (UINT flags); gchar *_gdk_win32_drawable_description (GdkDrawable *d); gchar *_gdk_win32_rop2_to_string (int rop2); diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 78ca696eb3..14f5129a2c 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -34,11 +34,7 @@ #include "gdkwindowimpl.h" #include "gdkprivate-win32.h" #include "gdkinput-win32.h" - -#if 0 -#include -#include -#endif +#include "gdkenumtypes.h" static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable); static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable, @@ -54,9 +50,9 @@ static void gdk_window_impl_win32_finalize (GObject *object); static gpointer parent_class = NULL; static GSList *modal_window_stack = NULL; -static void update_style_bits (GdkWindow *window); -static gboolean _gdk_window_get_functions (GdkWindow *window, - GdkWMFunction *functions); +static void update_style_bits (GdkWindow *window); +static gboolean _gdk_window_get_functions (GdkWindow *window, + GdkWMFunction *functions); #define WINDOW_IS_TOPLEVEL(window) \ (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ @@ -699,6 +695,9 @@ gdk_window_new_internal (GdkWindow *parent, else impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL; + if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY) + dwExStyle |= WS_EX_TOOLWINDOW; + if (private->parent) private->parent->children = g_list_prepend (private->parent->children, window); @@ -752,6 +751,9 @@ gdk_window_new_internal (GdkWindow *parent, hparent, GDK_WINDOW_HWND (window))); + /* Add window handle to title */ + GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title)); + g_free (wtitle); if (draw_impl->handle == NULL) @@ -1852,16 +1854,15 @@ get_effective_window_decorations (GdkWindow *window, return TRUE; case GDK_WINDOW_TYPE_HINT_TOOLBAR: + case GDK_WINDOW_TYPE_HINT_UTILITY: gdk_window_set_skip_taskbar_hint (window, TRUE); - *decoration = GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE; + gdk_window_set_skip_pager_hint (window, TRUE); + *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE); return TRUE; - case GDK_WINDOW_TYPE_HINT_UTILITY: - return FALSE; - case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN: - *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU - | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE); + *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU | + GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE); return TRUE; case GDK_WINDOW_TYPE_HINT_DOCK: @@ -1961,9 +1962,13 @@ gdk_window_set_title (GdkWindow *window, GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n", GDK_WINDOW_HWND (window), title)); + GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title)); + wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL); API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle)); g_free (wtitle); + + GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title)); } void @@ -1992,6 +1997,8 @@ gdk_window_set_transient_for (GdkWindow *window, window_id = GDK_WINDOW_HWND (window); parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL; + GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id)); + if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent))) { if (GDK_WINDOW_DESTROYED (window)) @@ -2879,19 +2886,29 @@ update_single_bit (LONG *style, static void update_style_bits (GdkWindow *window) { + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl; GdkWMDecoration decorations; - LONG old_style, new_style, exstyle; + LONG old_style, new_style, old_exstyle, new_exstyle; gboolean all; RECT rect, before, after; old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE); - exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); + old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); GetClientRect (GDK_WINDOW_HWND (window), &before); after = before; - AdjustWindowRectEx (&before, old_style, FALSE, exstyle); + AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle); new_style = old_style; + new_exstyle = old_exstyle; + + if (private->window_type == GDK_WINDOW_TEMP || + impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY) + new_exstyle |= WS_EX_TOOLWINDOW; + else + new_exstyle &= ~WS_EX_TOOLWINDOW; + if (get_effective_window_decorations (window, &decorations)) { all = (decorations & GDK_DECOR_ALL); @@ -2903,21 +2920,34 @@ update_style_bits (GdkWindow *window) update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX); } - if (old_style == new_style) + if (old_style == new_style && old_exstyle == new_exstyle ) { GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n", GDK_WINDOW_HWND (window))); return; } - GDK_NOTE (MISC, g_print ("update_style_bits: %p: %s => %s\n", - GDK_WINDOW_HWND (window), - _gdk_win32_window_style_to_string (old_style), - _gdk_win32_window_style_to_string (new_style))); + if (old_style != new_style) + { + GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n", + GDK_WINDOW_HWND (window), + _gdk_win32_window_style_to_string (old_style), + _gdk_win32_window_style_to_string (new_style))); + + SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style); + } - SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style); + if (old_exstyle != new_exstyle) + { + GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n", + GDK_WINDOW_HWND (window), + _gdk_win32_window_exstyle_to_string (old_exstyle), + _gdk_win32_window_exstyle_to_string (new_exstyle))); + + SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle); + } - AdjustWindowRectEx (&after, new_style, FALSE, exstyle); + AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle); GetWindowRect (GDK_WINDOW_HWND (window), &rect); rect.left += after.left - before.left; @@ -3492,13 +3522,18 @@ gdk_window_unfullscreen (GdkWindow *window) } void -gdk_window_set_keep_above (GdkWindow *window, gboolean setting) +gdk_window_set_keep_above (GdkWindow *window, + gboolean setting) { g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; + GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n", + GDK_WINDOW_HWND (window), + setting ? "YES" : "NO")); + if (GDK_WINDOW_IS_MAPPED (window)) { API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), @@ -3513,13 +3548,18 @@ gdk_window_set_keep_above (GdkWindow *window, gboolean setting) } void -gdk_window_set_keep_below (GdkWindow *window, gboolean setting) +gdk_window_set_keep_below (GdkWindow *window, + gboolean setting) { g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; + GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n", + GDK_WINDOW_HWND (window), + setting ? "YES" : "NO")); + if (GDK_WINDOW_IS_MAPPED (window)) { API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), @@ -3564,6 +3604,10 @@ gdk_window_set_modal_hint (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; + GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n", + GDK_WINDOW_HWND (window), + modal ? "YES" : "NO")); + private = (GdkWindowObject*) window; if (modal == private->modal_hint) @@ -3602,13 +3646,13 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window, g_return_if_fail (GDK_IS_WINDOW (window)); + GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n", + GDK_WINDOW_HWND (window), + skips_taskbar ? "YES" : "NO")); + // ### 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")); - if (skips_taskbar) { if (owner == NULL) @@ -3642,6 +3686,10 @@ gdk_window_set_skip_pager_hint (GdkWindow *window, gboolean skips_pager) { g_return_if_fail (GDK_IS_WINDOW (window)); + + GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n", + GDK_WINDOW_HWND (window), + skips_pager ? "YES" : "NO")); } void @@ -3653,8 +3701,15 @@ gdk_window_set_type_hint (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - GDK_NOTE (MISC, g_print ("gdk_window_set_type_hint: %p: %d\n", - GDK_WINDOW_HWND (window), hint)); + GDK_NOTE (MISC, + G_STMT_START{ + static GEnumClass *class = NULL; + if (!class) + class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT); + g_print ("gdk_window_set_type_hint: %p: %s\n", + GDK_WINDOW_HWND (window), + g_enum_get_value (class, hint)->value_name); + }G_STMT_END); ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;