diff options
author | Alexander Larsson <alexl@redhat.com> | 2011-10-27 16:09:42 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2011-11-10 17:41:06 +0100 |
commit | d27b402a85ccbe8252a141a086b3f810b9b14e4f (patch) | |
tree | 508cf5fcc311a9fc12f50d355fda1aa00a49d628 /gdk | |
parent | 2662fe37dfaa647cb6ebc94bd6031eee1362bedd (diff) | |
download | gtk+-d27b402a85ccbe8252a141a086b3f810b9b14e4f.tar.gz |
win32: Add custom placements for some window types
Windows with transients: center on parent
Splash screens: center on monitor
Also properly ignores initial moves of unmapped
windows that are not override redirect or HINT_POS
Fixes bugs #324254 and #612359
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/win32/gdkwindow-win32.c | 88 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.h | 4 |
2 files changed, 90 insertions, 2 deletions
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 2b3317860f..35ec5a6545 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -442,6 +442,7 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, GdkWindowImplWin32 *impl; const gchar *title; wchar_t *wtitle; + gboolean override_redirect; gint window_width, window_height; gint offset_x = 0, offset_y = 0; gint x, y; @@ -469,8 +470,12 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, g_assert (attributes->y == window->y); remaining_mask &= ~GDK_WA_Y; } + override_redirect = FALSE; if ((attributes_mask & GDK_WA_NOREDIR) != 0) - remaining_mask &= ~GDK_WA_NOREDIR; + { + override_redirect = !!attributes->override_redirect; + remaining_mask &= ~GDK_WA_NOREDIR; + } if ((remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT)) != 0) g_warning ("_gdk_window_impl_new: uexpected attribute 0x%X", @@ -486,6 +491,7 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, g_assert (gdk_screen_get_system_visual (screen) == attributes->visual); impl->extension_events_selected = FALSE; + impl->override_redirect = override_redirect; /* wclass is not any longer set always, but if is ... */ if ((attributes_mask & GDK_WA_WMCLASS) == GDK_WA_WMCLASS) @@ -623,6 +629,9 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display, # endif } + GetWindowRect (GDK_WINDOW_HWND (window), &rect); + impl->initial_x = rect.left; + impl->initial_y = rect.top; g_object_ref (window); gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window); @@ -898,6 +907,7 @@ show_window_internal (GdkWindow *window, gboolean already_mapped, gboolean deiconify) { + GdkWindowImplWin32 *window_impl; HWND old_active_window; gboolean focus_on_map = FALSE; DWORD exstyle; @@ -960,6 +970,76 @@ show_window_internal (GdkWindow *window, return; } + /* For initial map of "normal" windows we want to emulate WM window + * positioning behaviour, which means: + * + Use user specified position if GDK_HINT_POS or GDK_HINT_USER_POS + * otherwise: + * + default to the initial CW_USEDEFAULT placement, + * no matter if the user moved the window before showing it. + * + Certain window types and hints have more elaborate positioning + * schemes. + */ + window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (!already_mapped && + GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL && + (window_impl->hint_flags & (GDK_HINT_POS | GDK_HINT_USER_POS)) == 0 && + !window_impl->override_redirect) + { + gboolean center = FALSE; + RECT window_rect, center_on_rect; + int x, y; + + x = window_impl->initial_x; + y = window_impl->initial_y; + + if (window_impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN) + { + HMONITOR monitor; + MONITORINFO mi; + + monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST); + mi.cbSize = sizeof (mi); + if (monitor && GetMonitorInfo (monitor, &mi)) + center_on_rect = mi.rcMonitor; + else + { + center_on_rect.left = 0; + center_on_rect.right = 0; + center_on_rect.right = GetSystemMetrics (SM_CXSCREEN); + center_on_rect.bottom = GetSystemMetrics (SM_CYSCREEN); + } + center = TRUE; + } + else if (window_impl->transient_owner != NULL && + GDK_WINDOW_IS_MAPPED (window_impl->transient_owner)) + { + GdkWindow *owner = window_impl->transient_owner; + /* Center on transient parent */ + center_on_rect.left = owner->x; + center_on_rect.top = owner->y; + center_on_rect.right = center_on_rect.left + owner->width; + center_on_rect.bottom = center_on_rect.top + owner->height; + _gdk_win32_adjust_client_rect (GDK_WINDOW (owner), ¢er_on_rect); + center = TRUE; + } + + if (center) + { + window_rect.left = 0; + window_rect.top = 0; + window_rect.right = window->width; + window_rect.bottom = window->height; + _gdk_win32_adjust_client_rect (window, &window_rect); + + x = center_on_rect.left + ((center_on_rect.right - center_on_rect.left) - (window_rect.right - window_rect.left)) / 2; + y = center_on_rect.top + ((center_on_rect.bottom - center_on_rect.top) - (window_rect.bottom - window_rect.top)) / 2; + } + + API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, + x, y, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER)); + } + if (window->state & GDK_WINDOW_STATE_FULLSCREEN) { gdk_window_fullscreen (window); @@ -2068,9 +2148,13 @@ static void gdk_win32_window_set_override_redirect (GdkWindow *window, gboolean override_redirect) { + GdkWindowImplWin32 *window_impl; + g_return_if_fail (GDK_IS_WINDOW (window)); - g_warning ("gdk_window_set_override_redirect not implemented"); + window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + + window_impl->override_redirect = !!override_redirect; } static void diff --git a/gdk/win32/gdkwindow-win32.h b/gdk/win32/gdkwindow-win32.h index 648ae116d0..c393814ec0 100644 --- a/gdk/win32/gdkwindow-win32.h +++ b/gdk/win32/gdkwindow-win32.h @@ -76,8 +76,12 @@ struct _GdkWindowImplWin32 gint num_transients; gboolean changing_state; + gint initial_x; + gint initial_y; + guint no_bg : 1; guint inhibit_configure : 1; + guint override_redirect : 1; cairo_surface_t *cairo_surface; HDC hdc; |