summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk/win32/gdkevents-win32.c14
-rw-r--r--gdk/win32/gdksurface-win32.c208
-rw-r--r--gdk/win32/gdksurface-win32.h7
3 files changed, 170 insertions, 59 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 286aa923e8..bb847b5ebd 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -2354,9 +2354,7 @@ gdk_event_translate (MSG *msg,
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
- {
- gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
- }
+ gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
else if (_gdk_input_ignore_core == 0)
{
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
@@ -2835,6 +2833,16 @@ gdk_event_translate (MSG *msg,
else
unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
+ /*
+ * If we are minizing, pause all surface layout computations, and re-start the
+ * computation once we are coming out of a minimized state
+ */
+ if (!(old_state & GDK_TOPLEVEL_STATE_MINIMIZED) && set_bits & GDK_TOPLEVEL_STATE_MINIMIZED)
+ gdk_surface_freeze_updates (window);
+
+ if (old_state & GDK_TOPLEVEL_STATE_MINIMIZED && unset_bits & GDK_TOPLEVEL_STATE_MINIMIZED)
+ gdk_surface_thaw_updates (window);
+
gdk_surface_set_is_mapped (window, !!IsWindowVisible (msg->hwnd));
gdk_synthesize_surface_state (window, unset_bits, set_bits);
diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c
index d0ddf83d10..2722bb32cc 100644
--- a/gdk/win32/gdksurface-win32.c
+++ b/gdk/win32/gdksurface-win32.c
@@ -53,6 +53,10 @@
#include <math.h>
static void gdk_surface_win32_finalize (GObject *object);
+static void compute_toplevel_size (GdkSurface *surface,
+ gboolean update_geometry,
+ int *width,
+ int *height);
static gpointer parent_class = NULL;
static GSList *modal_window_stack = NULL;
@@ -1100,6 +1104,8 @@ gdk_win32_surface_resize (GdkSurface *window,
outer_rect.bottom - outer_rect.top,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
window->resize_count += 1;
+
+ gdk_surface_request_layout (window);
}
static void
@@ -1160,8 +1166,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
{
GdkWin32Surface *surface = GDK_WIN32_SURFACE (window);
- surface->inhibit_configure = TRUE;
-
/* We ignore changes to the window being moved or resized by the
user, as we don't want to fight the user */
if (GDK_SURFACE_HWND (window) == _modal_move_resize_window)
@@ -1186,8 +1190,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
}
out:
- surface->inhibit_configure = FALSE;
-
gdk_surface_request_layout (window);
}
@@ -2307,6 +2309,7 @@ snap_up (GdkSurface *window)
impl = GDK_WIN32_SURFACE (window);
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_FULLUP;
+ impl->resized = FALSE;
stash_window (window, impl);
@@ -2322,6 +2325,14 @@ snap_up (GdkSurface *window)
width += impl->shadow_x;
height += impl->shadow_y;
+ /* XXX: FIXME, AeroSnap snap_up() not really working well,
+ *
+ * * The snap_up() puts the window at the top left corner.
+ * * Without the following call, the height maximizes but we see a spew of
+ * "GdkToplevelSize: geometry size (x,y) exceeds bounds" warnings
+ */
+ compute_toplevel_size (window, TRUE, &width, &height);
+
gdk_win32_surface_move_resize (window, x, y, width, height);
}
@@ -2336,6 +2347,7 @@ snap_left (GdkSurface *window,
impl = GDK_WIN32_SURFACE (window);
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFLEFT;
+ impl->resized = FALSE;
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
@@ -2364,6 +2376,7 @@ snap_right (GdkSurface *window,
impl = GDK_WIN32_SURFACE (window);
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFRIGHT;
+ impl->resized = FALSE;
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
@@ -4028,8 +4041,18 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
rect.top != new_rect.top ||
rect.bottom != new_rect.bottom))
{
+ if (GDK_IS_TOPLEVEL (window))
+ {
+ int scale = impl->surface_scale;
+
+ impl->unscaled_width = new_rect.right - new_rect.left;
+ impl->unscaled_height = new_rect.bottom - new_rect.top;
+ impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
+ impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
+ impl->resized = TRUE;
+ }
+
context->native_move_resize_pending = TRUE;
- gdk_surface_request_layout (window);
}
else if (context->op == GDK_WIN32_DRAGOP_MOVE &&
(rect.left != new_rect.left ||
@@ -4064,6 +4087,8 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
if (context->op == GDK_WIN32_DRAGOP_RESIZE ||
context->op == GDK_WIN32_DRAGOP_MOVE)
handle_aerosnap_move_resize (window, context, x, y);
+
+ gdk_surface_request_layout (window);
}
static void
@@ -4172,6 +4197,7 @@ gdk_win32_surface_minimize (GdkSurface *window)
static void
gdk_win32_surface_maximize (GdkSurface *window)
{
+ GdkWin32Surface *impl;
g_return_if_fail (GDK_IS_SURFACE (window));
@@ -4182,6 +4208,9 @@ gdk_win32_surface_maximize (GdkSurface *window)
GDK_SURFACE_HWND (window),
_gdk_win32_surface_state_to_string (window->state)));
+ impl = GDK_WIN32_SURFACE (window);
+ impl->resized = FALSE;
+
if (GDK_SURFACE_IS_MAPPED (window))
GtkShowWindow (window, SW_MAXIMIZE);
else
@@ -4611,6 +4640,118 @@ gdk_win32_surface_set_input_region (GdkSurface *window,
}
static void
+compute_toplevel_size (GdkSurface *surface,
+ gboolean update_geometry,
+ int *width,
+ int *height)
+{
+ GdkDisplay *display = gdk_surface_get_display (surface);
+ GdkMonitor *monitor;
+ GdkToplevelSize size;
+ int bounds_width, bounds_height;
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+
+ monitor = gdk_display_get_monitor_at_surface (display, surface);
+ if (monitor)
+ {
+ GdkRectangle workarea;
+
+ gdk_win32_monitor_get_workarea (monitor, &workarea);
+ bounds_width = workarea.width;
+ bounds_height = workarea.height;
+ }
+ else
+ {
+ bounds_width = G_MAXINT;
+ bounds_height = G_MAXINT;
+ }
+
+ gdk_toplevel_size_init (&size, bounds_width, bounds_height);
+ gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
+ g_warn_if_fail (size.width > 0);
+ g_warn_if_fail (size.height > 0);
+ *width = size.width;
+ *height = size.height;
+
+ if (size.shadow.is_valid)
+ {
+ gdk_win32_surface_set_shadow_width (surface,
+ size.shadow.left,
+ size.shadow.right,
+ size.shadow.top,
+ size.shadow.bottom);
+ }
+
+ if (update_geometry)
+ {
+ GdkGeometry geometry;
+ GdkSurfaceHints mask;
+ GdkToplevelLayout *layout = impl->toplevel_layout;
+
+ if (gdk_toplevel_layout_get_resizable (layout))
+ {
+ geometry.min_width = size.min_width;
+ geometry.min_height = size.min_height;
+ mask = GDK_HINT_MIN_SIZE;
+ }
+ else
+ {
+ geometry.max_width = geometry.min_width = *width;
+ geometry.max_height = geometry.min_height = *height;
+ mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
+ }
+ gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
+ gdk_surface_constrain_size (&geometry, mask, *width, *height, width, height);
+ }
+}
+
+static void
+_gdk_win32_surface_request_layout (GdkSurface *surface)
+{
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+ int scale = impl->surface_scale;
+ RECT rect;
+
+ if (GDK_IS_TOPLEVEL (surface) && impl->resized)
+ {
+ surface->width = impl->next_layout.configured_width;
+ surface->height = impl->next_layout.configured_height;
+ }
+ else
+ {
+ _gdk_win32_get_window_rect (surface, &rect);
+
+ impl->unscaled_width = rect.right - rect.left;
+ impl->unscaled_height = rect.bottom - rect.top;
+
+ impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
+ impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
+ surface->x = rect.left / scale;
+ surface->y = rect.top / scale;
+ }
+}
+
+static gboolean
+_gdk_win32_surface_compute_size (GdkSurface *surface)
+{
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
+ int width, height;
+
+ if (GDK_IS_TOPLEVEL (surface))
+ compute_toplevel_size (surface, TRUE, &width, &height);
+
+ if (!impl->resized)
+ {
+ surface->width = impl->next_layout.configured_width;
+ surface->height = impl->next_layout.configured_height;
+
+ _gdk_surface_update_size (surface);
+ }
+
+ return FALSE;
+}
+
+static void
gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -4636,6 +4777,8 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
impl_class->get_scale_factor = _gdk_win32_surface_get_scale_factor;
impl_class->get_unscaled_size = _gdk_win32_surface_get_unscaled_size;
+ impl_class->request_layout = _gdk_win32_surface_request_layout;
+ impl_class->compute_size = _gdk_win32_surface_compute_size;
}
HGDIOBJ
@@ -4929,52 +5072,14 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
- GdkDisplay *display = gdk_surface_get_display (surface);
- GdkMonitor *monitor;
- GdkToplevelSize size;
- int bounds_width, bounds_height;
+ GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
int width, height;
- GdkGeometry geometry;
- GdkSurfaceHints mask;
gboolean maximize;
gboolean fullscreen;
- monitor = gdk_display_get_monitor_at_surface (display, surface);
- if (monitor)
- {
- GdkRectangle workarea;
-
- gdk_win32_monitor_get_workarea (monitor, &workarea);
- bounds_width = workarea.width;
- bounds_height = workarea.height;
- }
- else
- {
- bounds_width = G_MAXINT;
- bounds_height = G_MAXINT;
- }
-
- gdk_toplevel_size_init (&size, bounds_width, bounds_height);
- gdk_toplevel_notify_compute_size (toplevel, &size);
- g_warn_if_fail (size.width > 0);
- g_warn_if_fail (size.height > 0);
- width = size.width;
- height = size.height;
-
- if (gdk_toplevel_layout_get_resizable (layout))
- {
- geometry.min_width = size.min_width;
- geometry.min_height = size.min_height;
- mask = GDK_HINT_MIN_SIZE;
- }
- else
- {
- geometry.max_width = geometry.min_width = width;
- geometry.max_height = geometry.min_height = height;
- mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
- }
- gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
- gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
+ g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
+ impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
+ compute_toplevel_size (surface, FALSE, &width, &height);
gdk_win32_surface_resize (surface, width, height);
if (gdk_toplevel_layout_get_maximized (layout, &maximize))
@@ -4995,15 +5100,6 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
gdk_win32_surface_show (surface, FALSE);
maybe_notify_mapped (surface);
-
- if (size.shadow.is_valid)
- {
- gdk_win32_surface_set_shadow_width (surface,
- size.shadow.left,
- size.shadow.right,
- size.shadow.top,
- size.shadow.bottom);
- }
}
static gboolean
diff --git a/gdk/win32/gdksurface-win32.h b/gdk/win32/gdksurface-win32.h
index a60e67e574..08d8bf9d73 100644
--- a/gdk/win32/gdksurface-win32.h
+++ b/gdk/win32/gdksurface-win32.h
@@ -354,6 +354,13 @@ struct _GdkWin32Surface
int unscaled_width;
int unscaled_height;
+ GdkToplevelLayout *toplevel_layout;
+ struct {
+ int configured_width;
+ int configured_height;
+ } next_layout;
+ gboolean resized;
+
#ifdef GDK_WIN32_ENABLE_EGL
EGLSurface egl_surface;
EGLSurface egl_dummy_surface;