GDK-Win32: Fix AeroSnap on HiDPI

Commit 1d0fad3 revealed that there were some assumptions made that were
actually to compensate for the bug fixed by that commit, so we need to
remove those assumptions as they would result in AerSnap to not work
properly on HiDPI screens.

Also re-do how we set the x and y positions of our GdkWindow, so that we
are more consistent across the board when we go between a GDK window
coordinate and a Windows API window cooredinate.

This would also simplify the code a bit.

https://bugzilla.gnome.org/show_bug.cgi?id=785999
This commit is contained in:
Chun-wei Fan 2017-08-08 22:19:45 +08:00 committed by Руслан Ижбулатов
parent d7e2017c28
commit eb6d5b6b27
2 changed files with 70 additions and 74 deletions

View File

@ -1580,8 +1580,8 @@ _gdk_win32_do_emit_configure_event (GdkWindow *window,
impl->unscaled_height = rect.bottom - rect.top; impl->unscaled_height = rect.bottom - rect.top;
window->width = (impl->unscaled_width + impl->window_scale - 1) / impl->window_scale; window->width = (impl->unscaled_width + impl->window_scale - 1) / impl->window_scale;
window->height = (impl->unscaled_height + impl->window_scale - 1) / impl->window_scale; window->height = (impl->unscaled_height + impl->window_scale - 1) / impl->window_scale;
window->x = rect.left; window->x = rect.left / impl->window_scale;
window->y = rect.top; window->y = rect.top / impl->window_scale;
_gdk_window_update_size (window); _gdk_window_update_size (window);

View File

@ -248,8 +248,8 @@ gdk_win32_window_get_queued_window_rect (GdkWindow *window,
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl); GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
gdk_window_get_position (window, &x, &y); gdk_window_get_position (window, &x, &y);
window_rect.left = x; window_rect.left = x * impl->window_scale;
window_rect.top = y; window_rect.top = y * impl->window_scale;
window_rect.right = window_rect.left + gdk_window_get_width (window) * impl->window_scale; window_rect.right = window_rect.left + gdk_window_get_width (window) * impl->window_scale;
window_rect.bottom = window_rect.top + gdk_window_get_height (window) * impl->window_scale; window_rect.bottom = window_rect.top + gdk_window_get_height (window) * impl->window_scale;
@ -898,8 +898,8 @@ gdk_win32_window_foreign_new_for_display (GdkDisplay *display,
ClientToScreen ((HWND) anid, &point); ClientToScreen ((HWND) anid, &point);
if (parent != GetDesktopWindow ()) if (parent != GetDesktopWindow ())
ScreenToClient (parent, &point); ScreenToClient (parent, &point);
window->x = point.x; window->x = point.x / impl->window_scale;
window->y = point.y; window->y = point.y / impl->window_scale;
impl->unscaled_width = rect.right - rect.left; impl->unscaled_width = rect.right - rect.left;
impl->unscaled_height = rect.bottom - rect.top; impl->unscaled_height = rect.bottom - rect.top;
window->width = (impl->unscaled_width + impl->window_scale - 1) / impl->window_scale; window->width = (impl->unscaled_width + impl->window_scale - 1) / impl->window_scale;
@ -2992,8 +2992,8 @@ stash_window (GdkWindow *window,
GdkWindowImplWin32 *impl) GdkWindowImplWin32 *impl)
{ {
gint x, y; gint x, y;
gint width; gint width, wwidth;
gint height; gint height, wheight;
WINDOWPLACEMENT placement; WINDOWPLACEMENT placement;
HMONITOR hmonitor; HMONITOR hmonitor;
MONITORINFO hmonitor_info; MONITORINFO hmonitor_info;
@ -3037,20 +3037,23 @@ stash_window (GdkWindow *window,
placement.rcNormalPosition.left, placement.rcNormalPosition.left,
placement.rcNormalPosition.top)); placement.rcNormalPosition.top));
width = placement.rcNormalPosition.right - placement.rcNormalPosition.left; width = (placement.rcNormalPosition.right - placement.rcNormalPosition.left) / impl->window_scale;
height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top; height = (placement.rcNormalPosition.bottom - placement.rcNormalPosition.top) / impl->window_scale;
x = placement.rcNormalPosition.left - hmonitor_info.rcMonitor.left; x = (placement.rcNormalPosition.left - hmonitor_info.rcMonitor.left) / impl->window_scale;
y = placement.rcNormalPosition.top - hmonitor_info.rcMonitor.top; y = (placement.rcNormalPosition.top - hmonitor_info.rcMonitor.top) / impl->window_scale;
impl->snap_stash->x = ((gdouble) (x) / (gdouble) (hmonitor_info.rcWork.right - hmonitor_info.rcWork.left)) / impl->window_scale; wwidth = (hmonitor_info.rcWork.right - hmonitor_info.rcWork.left) / impl->window_scale;
impl->snap_stash->y = ((gdouble) (y) / (gdouble) (hmonitor_info.rcWork.bottom - hmonitor_info.rcWork.top)) / impl->window_scale; wheight = (hmonitor_info.rcWork.bottom - hmonitor_info.rcWork.top) / impl->window_scale;
impl->snap_stash->width = ((gdouble) width / (gdouble) (hmonitor_info.rcWork.right - hmonitor_info.rcWork.left)) / impl->window_scale;
impl->snap_stash->height = ((gdouble) height / (gdouble) (hmonitor_info.rcWork.bottom - hmonitor_info.rcWork.top)) / impl->window_scale;
impl->snap_stash_int->x = x / impl->window_scale; impl->snap_stash->x = (gdouble) (x) / (gdouble) (wwidth);
impl->snap_stash_int->y = y / impl->window_scale; impl->snap_stash->y = (gdouble) (y) / (gdouble) (wheight);
impl->snap_stash_int->width = width / impl->window_scale; impl->snap_stash->width = (gdouble) width / (gdouble) (wwidth);
impl->snap_stash_int->height = height / impl->window_scale; impl->snap_stash->height = (gdouble) height / (gdouble) (wheight);
impl->snap_stash_int->x = x;
impl->snap_stash_int->y = y;
impl->snap_stash_int->width = width;
impl->snap_stash_int->height = height;
GDK_NOTE (MISC, g_print ("Stashed window %d x %d @ %d : %d as %f x %f @ %f : %f\n", GDK_NOTE (MISC, g_print ("Stashed window %d x %d @ %d : %d as %f x %f @ %f : %f\n",
width, height, x, y, width, height, x, y,
@ -3078,8 +3081,8 @@ snap_up (GdkWindow *window)
y = 0; y = 0;
height = maxysize; height = maxysize;
x = (x - impl->margins.left) / impl->window_scale; x = x - impl->margins.left;
y = (y - impl->margins.top) / impl->window_scale; y = y - impl->margins.top;
width += impl->margins_x; width += impl->margins_x;
height += impl->margins_y; height += impl->margins_y;
@ -3102,10 +3105,10 @@ snap_left (GdkWindow *window,
stash_window (window, impl); stash_window (window, impl);
rect.width = rect.width / 2 / impl->window_scale; rect.width = rect.width / 2;
rect.x = rect.x - impl->margins.left / impl->window_scale; rect.x = rect.x - impl->margins.left;
rect.y = rect.y - impl->margins.top / impl->window_scale; rect.y = rect.y - impl->margins.top;
rect.width = rect.width + impl->margins_x; rect.width = rect.width + impl->margins_x;
rect.height = rect.height + impl->margins_y; rect.height = rect.height + impl->margins_y;
@ -3128,13 +3131,13 @@ snap_right (GdkWindow *window,
stash_window (window, impl); stash_window (window, impl);
rect.width = rect.width / 2 / impl->window_scale;; rect.width = rect.width / 2;
rect.x += rect.width; rect.x += rect.width;
rect.x = rect.x - impl->margins.left / impl->window_scale; rect.x = rect.x - impl->margins.left;
rect.y = rect.y - impl->margins.top / impl->window_scale; rect.y = rect.y - impl->margins.top;
rect.width = rect.width + impl->margins_x / impl->window_scale; rect.width = rect.width + impl->margins_x;
rect.height = rect.height + impl->margins_y / impl->window_scale; rect.height = rect.height + impl->margins_y;
gdk_window_move_resize (window, rect.x, rect.y, rect.width, rect.height); gdk_window_move_resize (window, rect.x, rect.y, rect.width, rect.height);
} }
@ -3395,8 +3398,7 @@ ensure_snap_indicator_surface (GdkW32DragMoveResizeContext *context,
*/ */
static void static void
adjust_indicator_rectangle (GdkRectangle *rect, adjust_indicator_rectangle (GdkRectangle *rect,
gboolean inward, gboolean inward)
guint scale)
{ {
gdouble inverter; gdouble inverter;
const gint gap = AEROSNAP_INDICATOR_EDGE_GAP; const gint gap = AEROSNAP_INDICATOR_EDGE_GAP;
@ -3411,8 +3413,8 @@ adjust_indicator_rectangle (GdkRectangle *rect,
rect->x += (gap * inverter); rect->x += (gap * inverter);
rect->y += (gap * inverter); rect->y += (gap * inverter);
rect->width -= (gap * 2 * inverter) * scale; rect->width -= (gap * 2 * inverter);
rect->height -= (gap * 2 * inverter) * scale; rect->height -= (gap * 2 * inverter);
#if defined(MORE_AEROSNAP_DEBUGGING) #if defined(MORE_AEROSNAP_DEBUGGING)
GDK_NOTE (MISC, g_print ("Adjusted %d x %d @ %d : %d -> %d x %d @ %d : %d\n", GDK_NOTE (MISC, g_print ("Adjusted %d x %d @ %d : %d -> %d x %d @ %d : %d\n",
@ -3430,8 +3432,7 @@ rounded_rectangle (cairo_t *cr,
gdouble radius, gdouble radius,
gdouble line_width, gdouble line_width,
GdkRGBA *fill, GdkRGBA *fill,
GdkRGBA *outline, GdkRGBA *outline)
guint scale)
{ {
gdouble degrees = M_PI / 180.0; gdouble degrees = M_PI / 180.0;
@ -3440,10 +3441,10 @@ rounded_rectangle (cairo_t *cr,
cairo_save (cr); cairo_save (cr);
cairo_new_sub_path (cr); cairo_new_sub_path (cr);
cairo_arc (cr, x * scale + width - radius * scale, y * scale + radius * scale, radius * scale, -90 * degrees, 0 * degrees); cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc (cr, x * scale + width - radius * scale, y * scale + height - radius * scale, radius * scale, 0 * degrees, 90 * degrees); cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc (cr, (x + radius) * scale, y * scale + height - radius * scale, radius * scale, 90 * degrees, 180 * degrees); cairo_arc (cr, (x + radius), y + height - radius, radius, 90 * degrees, 180 * degrees);
cairo_arc (cr, (x + radius) * scale, (y + radius) * scale, radius * scale, 180 * degrees, 270 * degrees); cairo_arc (cr, (x + radius), (y + radius), radius, 180 * degrees, 270 * degrees);
cairo_close_path (cr); cairo_close_path (cr);
if (fill) if (fill)
@ -3490,7 +3491,7 @@ draw_indicator (GdkW32DragMoveResizeContext *context,
gint64 animation_duration; gint64 animation_duration;
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (context->window->impl); GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (context->window->impl);
line_width = AEROSNAP_INDICATOR_LINE_WIDTH; line_width = AEROSNAP_INDICATOR_LINE_WIDTH * impl->window_scale;
corner_radius = AEROSNAP_INDICATOR_CORNER_RADIUS; corner_radius = AEROSNAP_INDICATOR_CORNER_RADIUS;
animation_duration = AEROSNAP_INDICATOR_ANIMATION_DURATION; animation_duration = AEROSNAP_INDICATOR_ANIMATION_DURATION;
last_draw = FALSE; last_draw = FALSE;
@ -3558,13 +3559,13 @@ draw_indicator (GdkW32DragMoveResizeContext *context,
cr = cairo_create (context->indicator_surface); cr = cairo_create (context->indicator_surface);
rounded_rectangle (cr, rounded_rectangle (cr,
current_rect.x - context->indicator_window_rect.x, (current_rect.x - context->indicator_window_rect.x) * impl->window_scale,
current_rect.y - context->indicator_window_rect.y, (current_rect.y - context->indicator_window_rect.y) * impl->window_scale,
current_rect.width, current_rect.width * impl->window_scale,
current_rect.height, current_rect.height * impl->window_scale,
corner_radius, corner_radius,
line_width, line_width,
&fill, &outline, impl->window_scale); &fill, &outline);
cairo_destroy (cr); cairo_destroy (cr);
#if defined(MORE_AEROSNAP_DEBUGGING) #if defined(MORE_AEROSNAP_DEBUGGING)
@ -3708,10 +3709,10 @@ start_indicator_drawing (GdkW32DragMoveResizeContext *context,
return; return;
to_adjusted = to; to_adjusted = to;
adjust_indicator_rectangle (&to_adjusted, TRUE, scale); adjust_indicator_rectangle (&to_adjusted, TRUE);
from_adjusted = from; from_adjusted = from;
adjust_indicator_rectangle (&from_adjusted, TRUE, scale); adjust_indicator_rectangle (&from_adjusted, TRUE);
context->draw_timestamp = 0; context->draw_timestamp = 0;
context->indicator_start = from_adjusted; context->indicator_start = from_adjusted;
@ -3752,10 +3753,8 @@ update_fullup_indicator (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WIN32 (window->impl); impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
maxysize = GetSystemMetrics (SM_CYVIRTUALSCREEN); maxysize = GetSystemMetrics (SM_CYVIRTUALSCREEN);
gdk_window_get_position (window, &to.x, &to.y); gdk_window_get_position (window, &to.x, &to.y);
to.x /= impl->window_scale; to.width = gdk_window_get_width (window);
to.y /= impl->window_scale; to.height = gdk_window_get_height (window);
to.width = gdk_window_get_width (window) * impl->window_scale;
to.height = gdk_window_get_height (window) * impl->window_scale;
to.y = 0; to.y = 0;
to.height = maxysize; to.height = maxysize;
@ -3764,7 +3763,7 @@ update_fullup_indicator (GdkWindow *window,
if (context->timer == 0) if (context->timer == 0)
{ {
from_adjusted = from; from_adjusted = from;
adjust_indicator_rectangle (&from_adjusted, FALSE, impl->window_scale); adjust_indicator_rectangle (&from_adjusted, FALSE);
GDK_NOTE (MISC, g_print ("Restart fullup animation from %d x %d @ %d : %d -> %d x %d @ %d x %d\n", GDK_NOTE (MISC, g_print ("Restart fullup animation from %d x %d @ %d : %d -> %d x %d @ %d x %d\n",
context->indicator_target.width, context->indicator_target.height, context->indicator_target.width, context->indicator_target.height,
@ -3778,7 +3777,7 @@ update_fullup_indicator (GdkWindow *window,
from_or_to = unity_of_rects (from, to); from_or_to = unity_of_rects (from, to);
to_adjusted = to; to_adjusted = to;
adjust_indicator_rectangle (&to_adjusted, TRUE, impl->window_scale); adjust_indicator_rectangle (&to_adjusted, TRUE);
GDK_NOTE (MISC, g_print ("Retarget fullup animation %d x %d @ %d : %d -> %d x %d @ %d x %d\n", GDK_NOTE (MISC, g_print ("Retarget fullup animation %d x %d @ %d : %d -> %d x %d @ %d x %d\n",
context->indicator_target.width, context->indicator_target.height, context->indicator_target.width, context->indicator_target.height,
@ -3833,7 +3832,7 @@ start_indicator (GdkWindow *window,
end_size.height = workarea.height; end_size.height = workarea.height;
break; break;
case GDK_WIN32_AEROSNAP_STATE_HALFRIGHT: case GDK_WIN32_AEROSNAP_STATE_HALFRIGHT:
end_size.x = (workarea.x + workarea.width / 2) / impl->window_scale; end_size.x = (workarea.x + workarea.width / 2);
end_size.y = workarea.y; end_size.y = workarea.y;
end_size.width = workarea.width / 2; end_size.width = workarea.width / 2;
end_size.height = workarea.height; end_size.height = workarea.height;
@ -3869,21 +3868,18 @@ stop_indicator (GdkWindow *window,
static gint static gint
point_in_aerosnap_region (gint x, point_in_aerosnap_region (gint x,
gint y, gint y,
AeroSnapEdgeRegion *region, AeroSnapEdgeRegion *region)
guint scale)
{ {
gint edge, trigger; gint edge, trigger;
gint x_scaled = x * scale;
gint y_scaled = y * scale;
edge = (x_scaled >= region->edge.x && edge = (x >= region->edge.x &&
y_scaled >= region->edge.y && y >= region->edge.y &&
x_scaled <= region->edge.x + region->edge.width && x <= region->edge.x + region->edge.width &&
y_scaled <= region->edge.y + region->edge.height) ? 1 : 0; y <= region->edge.y + region->edge.height) ? 1 : 0;
trigger = (x_scaled >= region->trigger.x && trigger = (x >= region->trigger.x &&
y_scaled >= region->trigger.y && y >= region->trigger.y &&
x_scaled <= region->trigger.x + region->trigger.width && x <= region->trigger.x + region->trigger.width &&
y_scaled <= region->trigger.y + region->trigger.height) ? 1 : 0; y <= region->trigger.y + region->trigger.height) ? 1 : 0;
return edge + trigger; return edge + trigger;
} }
@ -3921,25 +3917,25 @@ handle_aerosnap_move_resize (GdkWindow *window,
for (i = 0; i < context->maximize_regions->len && maximize == 0; i++) for (i = 0; i < context->maximize_regions->len && maximize == 0; i++)
{ {
reg = &g_array_index (context->maximize_regions, AeroSnapEdgeRegion, i); reg = &g_array_index (context->maximize_regions, AeroSnapEdgeRegion, i);
maximize = point_in_aerosnap_region (x, y, reg, impl->window_scale); maximize = point_in_aerosnap_region (x, y, reg);
} }
for (i = 0; i < context->halfleft_regions->len && halfleft == 0; i++) for (i = 0; i < context->halfleft_regions->len && halfleft == 0; i++)
{ {
reg = &g_array_index (context->halfleft_regions, AeroSnapEdgeRegion, i); reg = &g_array_index (context->halfleft_regions, AeroSnapEdgeRegion, i);
halfleft = point_in_aerosnap_region (x, y, reg, impl->window_scale); halfleft = point_in_aerosnap_region (x, y, reg);
} }
for (i = 0; i < context->halfright_regions->len && halfright == 0; i++) for (i = 0; i < context->halfright_regions->len && halfright == 0; i++)
{ {
reg = &g_array_index (context->halfright_regions, AeroSnapEdgeRegion, i); reg = &g_array_index (context->halfright_regions, AeroSnapEdgeRegion, i);
halfright = point_in_aerosnap_region (x, y, reg, impl->window_scale); halfright = point_in_aerosnap_region (x, y, reg);
} }
for (i = 0; i < context->fullup_regions->len && fullup == 0; i++) for (i = 0; i < context->fullup_regions->len && fullup == 0; i++)
{ {
reg = &g_array_index (context->fullup_regions, AeroSnapEdgeRegion, i); reg = &g_array_index (context->fullup_regions, AeroSnapEdgeRegion, i);
fullup = point_in_aerosnap_region (x, y, reg, impl->window_scale); fullup = point_in_aerosnap_region (x, y, reg);
} }
#if defined(MORE_AEROSNAP_DEBUGGING) #if defined(MORE_AEROSNAP_DEBUGGING)
@ -5494,8 +5490,8 @@ gdk_win32_ref_cairo_surface_layered (GdkWindow *window,
RECT window_rect; RECT window_rect;
gdk_window_get_position (window, &x, &y); gdk_window_get_position (window, &x, &y);
window_rect.left = x; window_rect.left = x * impl->window_scale;
window_rect.top = y; window_rect.top = y * impl->window_scale;
window_rect.right = window_rect.left + gdk_window_get_width (window) * impl->window_scale; window_rect.right = window_rect.left + gdk_window_get_width (window) * impl->window_scale;
window_rect.bottom = window_rect.top + gdk_window_get_height (window) * impl->window_scale; window_rect.bottom = window_rect.top + gdk_window_get_height (window) * impl->window_scale;