summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2011-10-27 16:09:42 +0200
committerAlexander Larsson <alexl@redhat.com>2011-11-10 17:41:06 +0100
commitd27b402a85ccbe8252a141a086b3f810b9b14e4f (patch)
tree508cf5fcc311a9fc12f50d355fda1aa00a49d628 /gdk
parent2662fe37dfaa647cb6ebc94bd6031eee1362bedd (diff)
downloadgtk+-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.c88
-rw-r--r--gdk/win32/gdkwindow-win32.h4
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), &center_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;