forked from AuroraMiddleware/gtk
Merge branch 'fix-3728-3799' into 'main'
GDK-Win32: Force toplevel surfaces to configure as needed (fix issues #3728 and #3799) Closes #3728 and #3799 See merge request GNOME/gtk!3712
This commit is contained in:
commit
5e090c1fac
@ -653,6 +653,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
impl->hdc = GetDC (impl->handle);
|
||||
impl->inhibit_configure = TRUE;
|
||||
|
||||
return surface;
|
||||
}
|
||||
@ -1042,14 +1043,15 @@ gdk_win32_surface_do_move (GdkSurface *window,
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_resize (GdkSurface *window,
|
||||
int width, int height)
|
||||
gdk_win32_surface_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
RECT outer_rect;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (width < 1)
|
||||
@ -1058,28 +1060,29 @@ gdk_win32_surface_resize (GdkSurface *window,
|
||||
height = 1;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_win32_surface_resize: %p: %dx%d\n",
|
||||
GDK_SURFACE_HWND (window), width, height));
|
||||
GDK_SURFACE_HWND (surface), width, height));
|
||||
|
||||
if (window->state & GDK_TOPLEVEL_STATE_FULLSCREEN)
|
||||
if (surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN)
|
||||
return;
|
||||
|
||||
get_outer_rect (window, width, height, &outer_rect);
|
||||
get_outer_rect (surface, width, height, &outer_rect);
|
||||
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
|
||||
"NOACTIVATE|NOMOVE|NOZORDER)\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
GDK_SURFACE_HWND (surface),
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
0, 0,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
|
||||
window->resize_count += 1;
|
||||
surface->resize_count += 1;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
if (!GDK_WIN32_SURFACE (surface)->force_recompute_size)
|
||||
gdk_surface_request_layout (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2495,35 +2498,41 @@ _gdk_win32_surface_handle_aerosnap (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
apply_snap (GdkSurface *window,
|
||||
GdkWin32AeroSnapState snap)
|
||||
apply_snap (GdkSurface *surface,
|
||||
GdkWin32AeroSnapState snap)
|
||||
{
|
||||
GdkMonitor *monitor;
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_surface_get_display (window);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
switch (snap)
|
||||
{
|
||||
case GDK_WIN32_AEROSNAP_STATE_UNDETERMINED:
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_MAXIMIZE:
|
||||
unsnap (window, monitor);
|
||||
gdk_win32_surface_maximize (window);
|
||||
unsnap (surface, monitor);
|
||||
gdk_win32_surface_maximize (surface);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_HALFLEFT:
|
||||
unsnap (window, monitor);
|
||||
snap_left (window, monitor, monitor);
|
||||
unsnap (surface, monitor);
|
||||
snap_left (surface, monitor, monitor);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_HALFRIGHT:
|
||||
unsnap (window, monitor);
|
||||
snap_right (window, monitor, monitor);
|
||||
unsnap (surface, monitor);
|
||||
snap_right (surface, monitor, monitor);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_FULLUP:
|
||||
snap_up (window);
|
||||
snap_up (surface);
|
||||
break;
|
||||
}
|
||||
|
||||
if (snap != GDK_WIN32_AEROSNAP_STATE_UNDETERMINED)
|
||||
{
|
||||
GDK_WIN32_SURFACE (surface)->inhibit_configure = TRUE;
|
||||
GDK_WIN32_SURFACE (surface)->force_recompute_size = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Registers a dumb window class. This window
|
||||
@ -3403,10 +3412,10 @@ get_cursor_name_from_op (GdkW32WindowDragOp op,
|
||||
}
|
||||
|
||||
static void
|
||||
setup_drag_move_resize_context (GdkSurface *window,
|
||||
setup_drag_move_resize_context (GdkSurface *surface,
|
||||
GdkW32DragMoveResizeContext *context,
|
||||
GdkW32WindowDragOp op,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkDevice *device,
|
||||
int button,
|
||||
double x,
|
||||
@ -3415,12 +3424,13 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
{
|
||||
RECT rect;
|
||||
const char *cursor_name;
|
||||
GdkSurface *pointer_window;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
|
||||
gboolean maximized = gdk_toplevel_get_state (GDK_TOPLEVEL (window)) & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
GdkSurface *pointer_surface;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
gboolean maximized = gdk_toplevel_get_state (GDK_TOPLEVEL (surface)) & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
int root_x, root_y;
|
||||
gboolean restore_configure = FALSE;
|
||||
|
||||
gdk_win32_surface_get_root_coords (window, x, y, &root_x, &root_y);
|
||||
gdk_win32_surface_get_root_coords (surface, x, y, &root_x, &root_y);
|
||||
|
||||
/* Before we drag, we need to undo any maximization or snapping.
|
||||
* AeroSnap behaviour:
|
||||
@ -3443,7 +3453,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
* resize
|
||||
* don't unsnap
|
||||
* apply new width and x position to unsnapped cache,
|
||||
* so that unsnapped window only regains its height
|
||||
* so that unsnapped surface only regains its height
|
||||
* and y position, but inherits x and width from
|
||||
* the fullup snapped state
|
||||
* vertical resize:
|
||||
@ -3458,7 +3468,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
*
|
||||
* TODO: make this implementation behave as AeroSnap on resizes?
|
||||
* There's also the case where
|
||||
* a halfleft/halfright window isn't unsnapped when it's
|
||||
* a halfleft/halfright surface isn't unsnapped when it's
|
||||
* being moved horizontally, but it's more difficult to implement.
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_RESIZE &&
|
||||
@ -3466,7 +3476,8 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
impl->snap_state == GDK_WIN32_AEROSNAP_STATE_HALFLEFT ||
|
||||
impl->snap_state == GDK_WIN32_AEROSNAP_STATE_FULLUP))
|
||||
{
|
||||
discard_snapinfo (window);
|
||||
discard_snapinfo (surface);
|
||||
restore_configure = TRUE;
|
||||
}
|
||||
else if (maximized ||
|
||||
(impl->snap_state == GDK_WIN32_AEROSNAP_STATE_HALFRIGHT ||
|
||||
@ -3476,24 +3487,25 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
GdkMonitor *monitor;
|
||||
int wx, wy, wwidth, wheight;
|
||||
int swx, swy, swwidth, swheight;
|
||||
gboolean pointer_outside_of_window;
|
||||
gboolean pointer_outside_of_surface;
|
||||
int offsetx, offsety;
|
||||
gboolean left_half;
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_surface_get_display (window);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
gdk_surface_get_geometry (window, &wx, &wy, &wwidth, &wheight);
|
||||
restore_configure = TRUE;
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
gdk_surface_get_geometry (surface, &wx, &wy, &wwidth, &wheight);
|
||||
|
||||
swx = wx;
|
||||
swy = wy;
|
||||
swwidth = wwidth;
|
||||
swheight = wheight;
|
||||
|
||||
/* Subtract window shadow. We don't want pointer to go outside of
|
||||
* the visible window during drag-move. For drag-resize it's OK.
|
||||
* Don't take shadow into account if the window is maximized -
|
||||
* maximized windows don't have shadows.
|
||||
/* Subtract surface shadow. We don't want pointer to go outside of
|
||||
* the visible surface during drag-move. For drag-resize it's OK.
|
||||
* Don't take shadow into account if the surface is maximized -
|
||||
* maximized surfaces don't have shadows.
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE && !maximized)
|
||||
{
|
||||
@ -3503,16 +3515,16 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
swheight -= impl->shadow_y;
|
||||
}
|
||||
|
||||
pointer_outside_of_window = root_x < swx || root_x > swx + swwidth ||
|
||||
pointer_outside_of_surface = root_x < swx || root_x > swx + swwidth ||
|
||||
root_y < swy || root_y > swy + swheight;
|
||||
/* Calculate the offset of the pointer relative to the window */
|
||||
/* Calculate the offset of the pointer relative to the surface */
|
||||
offsetx = root_x - swx;
|
||||
offsety = root_y - swy;
|
||||
|
||||
/* Figure out in which half of the window the pointer is.
|
||||
/* Figure out in which half of the surface the pointer is.
|
||||
* The code currently only concerns itself with horizontal
|
||||
* dimension (left/right halves).
|
||||
* There's no upper/lower half, because usually window
|
||||
* There's no upper/lower half, because usually surface
|
||||
* is dragged by its upper half anyway. If that changes, adjust
|
||||
* accordingly.
|
||||
*/
|
||||
@ -3522,26 +3534,26 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
if (!left_half)
|
||||
offsetx = swwidth - offsetx;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d, this is %d : %d relative to the window's %s\n",
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d, this is %d : %d relative to the surface's %s\n",
|
||||
root_x, root_y, offsetx, offsety,
|
||||
left_half ? "left half" : "right half"));
|
||||
|
||||
/* Move window in such a way that on unmaximization/unsnapping the pointer
|
||||
* is still pointing at the appropriate half of the window,
|
||||
/* Move surface in such a way that on unmaximization/unsnapping the pointer
|
||||
* is still pointing at the appropriate half of the surface,
|
||||
* with the same offset from the left or right edge. If the new
|
||||
* window size is too small, and adding that offset puts the pointer
|
||||
* surface size is too small, and adding that offset puts the pointer
|
||||
* into the other half or even beyond, move the pointer to the middle.
|
||||
*/
|
||||
if (!pointer_outside_of_window && maximized)
|
||||
if (!pointer_outside_of_surface && maximized)
|
||||
{
|
||||
WINDOWPLACEMENT placement;
|
||||
int unmax_width, unmax_height;
|
||||
int shadow_unmax_width, shadow_unmax_height;
|
||||
|
||||
placement.length = sizeof (placement);
|
||||
API_CALL (GetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
API_CALL (GetWindowPlacement, (GDK_SURFACE_HWND (surface), &placement));
|
||||
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized window placement is %ld x %ld @ %ld : %ld\n",
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized surface placement is %ld x %ld @ %ld : %ld\n",
|
||||
placement.rcNormalPosition.right - placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.bottom - placement.rcNormalPosition.top,
|
||||
placement.rcNormalPosition.left,
|
||||
@ -3587,9 +3599,9 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.top));
|
||||
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (surface), &placement));
|
||||
}
|
||||
else if (!pointer_outside_of_window && impl->snap_stash_int)
|
||||
else if (!pointer_outside_of_surface && impl->snap_stash_int)
|
||||
{
|
||||
GdkRectangle new_pos;
|
||||
GdkRectangle snew_pos;
|
||||
@ -3619,22 +3631,22 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
new_pos.y = root_y - new_pos.height / 2;
|
||||
}
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped window to %d : %d\n",
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped surface to %d : %d\n",
|
||||
new_pos.x, new_pos.y));
|
||||
discard_snapinfo (window);
|
||||
gdk_win32_surface_move_resize (window, new_pos.x, new_pos.y,
|
||||
discard_snapinfo (surface);
|
||||
gdk_win32_surface_move_resize (surface, new_pos.x, new_pos.y,
|
||||
new_pos.width, new_pos.height);
|
||||
}
|
||||
|
||||
|
||||
if (maximized)
|
||||
gdk_win32_surface_unmaximize (window);
|
||||
gdk_win32_surface_unmaximize (surface);
|
||||
else
|
||||
unsnap (window, monitor);
|
||||
unsnap (surface, monitor);
|
||||
|
||||
if (pointer_outside_of_window)
|
||||
if (pointer_outside_of_surface)
|
||||
{
|
||||
/* Pointer outside of the window, move pointer into window */
|
||||
/* Pointer outside of the surface, move pointer into surface */
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d is outside of %d x %d @ %d : %d, move it to %d : %d\n",
|
||||
root_x, root_y, wwidth, wheight, wx, wy, wx + wwidth / 2, wy + wheight / 2));
|
||||
root_x = wx + wwidth / 2;
|
||||
@ -3647,26 +3659,29 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_win32_get_window_rect (window, &rect);
|
||||
if (restore_configure)
|
||||
impl->inhibit_configure = FALSE;
|
||||
|
||||
_gdk_win32_get_window_rect (surface, &rect);
|
||||
|
||||
cursor_name = get_cursor_name_from_op (op, edge);
|
||||
|
||||
context->cursor = gdk_cursor_new_from_name (cursor_name, NULL);
|
||||
|
||||
pointer_window = window;
|
||||
pointer_surface = surface;
|
||||
|
||||
/* Note: This triggers a WM_CAPTURECHANGED, which will trigger
|
||||
* gdk_win32_surface_end_move_resize_drag(), which will end
|
||||
* our op before it even begins, but only if context->op is not NONE.
|
||||
* This is why we first do the grab, *then* set the op.
|
||||
*/
|
||||
gdk_device_grab (device, pointer_window,
|
||||
gdk_device_grab (device, pointer_surface,
|
||||
FALSE,
|
||||
GDK_ALL_EVENTS_MASK,
|
||||
context->cursor,
|
||||
timestamp);
|
||||
|
||||
context->window = g_object_ref (window);
|
||||
context->window = g_object_ref (surface);
|
||||
context->op = op;
|
||||
context->edge = edge;
|
||||
context->device = device;
|
||||
@ -3686,10 +3701,10 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
calculate_aerosnap_regions (context);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("begin drag moveresize: window %p, toplevel %p, "
|
||||
g_print ("begin drag moveresize: surface %p, toplevel %p, "
|
||||
"op %u, edge %d, device %p, "
|
||||
"button %d, coord %d:%d, time %u\n",
|
||||
pointer_window, window,
|
||||
pointer_surface, surface,
|
||||
context->op, context->edge, context->device,
|
||||
context->button, context->start_root_x,
|
||||
context->start_root_y, context->timestamp));
|
||||
@ -4084,45 +4099,61 @@ gdk_win32_surface_minimize (GdkSurface *window)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_maximize (GdkSurface *window)
|
||||
gdk_win32_surface_maximize (GdkSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_maximize: %p: %s\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
GDK_SURFACE_HWND (surface),
|
||||
_gdk_win32_surface_state_to_string (surface->state)));
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_MAXIMIZE);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
impl->inhibit_configure = TRUE;
|
||||
impl->force_recompute_size = FALSE;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
GtkShowWindow (surface, SW_MAXIMIZE);
|
||||
else
|
||||
gdk_synthesize_surface_state (window,
|
||||
gdk_synthesize_surface_state (surface,
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MAXIMIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_unmaximize (GdkSurface *window)
|
||||
gdk_win32_surface_unmaximize (GdkSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_unmaximize: %p: %s\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
GDK_SURFACE_HWND (surface),
|
||||
_gdk_win32_surface_state_to_string (surface->state)));
|
||||
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (window);
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (surface);
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_RESTORE);
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
GtkShowWindow (surface, SW_RESTORE);
|
||||
else
|
||||
gdk_synthesize_surface_state (window,
|
||||
gdk_synthesize_surface_state (surface,
|
||||
GDK_TOPLEVEL_STATE_MAXIMIZED,
|
||||
0);
|
||||
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (impl->inhibit_configure)
|
||||
{
|
||||
impl->inhibit_configure = FALSE;
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4547,6 +4578,9 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
&surface->x, &surface->y,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!impl->inhibit_configure)
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4561,8 +4595,18 @@ _gdk_win32_surface_compute_size (GdkSurface *surface)
|
||||
|
||||
if (!impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
if (GDK_IS_TOPLEVEL (surface) && impl->force_recompute_size)
|
||||
{
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
impl->force_recompute_size = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
}
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
@ -337,6 +337,7 @@ struct _GdkWin32Surface
|
||||
int configured_height;
|
||||
RECT configured_rect;
|
||||
} next_layout;
|
||||
gboolean force_recompute_size;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
guint egl_force_redraw_all : 1;
|
||||
|
Loading…
Reference in New Issue
Block a user