summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2018-04-25 18:16:26 +0200
committerBenjamin Berg <benjamin@sipsolutions.net>2018-05-17 09:30:59 +0000
commitc377c338f0f431c1cdc2393d3053debe0efee602 (patch)
tree2d77150e61c6cca326c5610a3118ff30d1fadc8b
parentd1eabc2346fe1b6c9124a8b60e8bc565145913f2 (diff)
downloadgnome-control-center-wip/benzea/display.tar.gz
display: Implement major/minor axis snapping and infinit for edgeswip/benzea/display
This improves the snapping behaviour in a number of ways. It allows increasing the snapping distance while still helping the user to align monitors by snapping a different distance for the minor axis. The patch also allows setting this distance to infinity so that we get the correct behaviour in the case of two monitors for the corners.
-rw-r--r--panels/display/cc-display-arrangement.c99
1 files changed, 68 insertions, 31 deletions
diff --git a/panels/display/cc-display-arrangement.c b/panels/display/cc-display-arrangement.c
index 3b489f4b1..0bc5fcd33 100644
--- a/panels/display/cc-display-arrangement.c
+++ b/panels/display/cc-display-arrangement.c
@@ -38,7 +38,7 @@ struct _CcDisplayArrangement
gdouble drag_anchor_x;
gdouble drag_anchor_y;
- guint max_snap_distance;
+ guint major_snap_distance;
};
typedef struct _CcDisplayArrangement CcDisplayArrangement;
@@ -67,7 +67,8 @@ struct SnapData {
#define MARGIN_PX 0
#define MARGIN_MON 0.66
-#define MAX_SNAP_DISTANCE 10
+#define MAJOR_SNAP_DISTANCE 25
+#define MINOR_SNAP_DISTANCE 5
#define MIN_OVERLAP 25
G_DEFINE_TYPE (CcDisplayArrangement, cc_display_arrangement, GTK_TYPE_DRAWING_AREA)
@@ -216,7 +217,9 @@ maybe_update_snap (CcDisplayArrangement *arr,
gint mon_y,
gint new_x,
gint new_y,
- gboolean snapped)
+ enum SnapDirection snapped,
+ enum SnapDirection major_axis,
+ gint minor_unlimited)
{
enum SnapDirection update_snap = SNAP_DIR_NONE;
gdouble dist_x, dist_y;
@@ -225,18 +228,52 @@ maybe_update_snap (CcDisplayArrangement *arr,
get_snap_distance (arr, mon_x, mon_y, new_x, new_y, &dist_x, &dist_y);
dist = MAX (dist_x, dist_y);
- if (dist > arr->max_snap_distance)
- return;
+ /* Snap by the variable max snap distance on the major axis, ensure the
+ * minor axis is below the minimum snapping distance (often just zero). */
+ switch (major_axis)
+ {
+ case SNAP_DIR_X:
+ if (dist_x > arr->major_snap_distance)
+ return;
+ if (dist_y > MINOR_SNAP_DISTANCE)
+ {
+ if (new_y > mon_y && minor_unlimited <= 0)
+ return;
+ if (new_y < mon_y && minor_unlimited >= 0)
+ return;
+ }
+ break;
+
+ case SNAP_DIR_Y:
+ if (dist_y > arr->major_snap_distance)
+ return;
+ if (dist_x > MINOR_SNAP_DISTANCE)
+ {
+ if (new_x > mon_x && minor_unlimited <= 0)
+ return;
+ if (new_x < mon_x && minor_unlimited >= 0)
+ return;
+ }
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
if (snapped == SNAP_DIR_BOTH)
{
if (snap_data->snapped == SNAP_DIR_NONE)
update_snap = SNAP_DIR_BOTH;
- if (dist < MAX(snap_data->dist_x, snap_data->dist_y))
+ /* Update, if this is closer on the main axis. */
+ if (((major_axis == SNAP_DIR_X) && (dist_x < snap_data->dist_x)) ||
+ ((major_axis == SNAP_DIR_Y) && (dist_y < snap_data->dist_y)))
update_snap = SNAP_DIR_BOTH;
- if (dist == MAX(snap_data->dist_x, snap_data->dist_y) && (dist_x < snap_data->dist_x || dist_y < snap_data->dist_y))
+ /* Also update if we were only snapping in one direction earlier and it
+ * is better or equally good. */
+ if ((snap_data->snapped == SNAP_DIR_X && (dist <= snap_data->dist_x)) ||
+ (snap_data->snapped == SNAP_DIR_Y && (dist <= snap_data->dist_y)))
update_snap = SNAP_DIR_BOTH;
}
else if (snapped == SNAP_DIR_X)
@@ -334,52 +371,52 @@ find_best_snapping (CcDisplayArrangement *arr,
/* We only snap horizontally or vertically to an edge of the same monitor */
if (dist_y < dist_x)
{
- maybe_update_snap (arr, snap_data, x1, y1, x1, top_snap_pos, SNAP_DIR_Y);
- maybe_update_snap (arr, snap_data, x1, y1, x1, bottom_snap_pos, SNAP_DIR_Y);
+ maybe_update_snap (arr, snap_data, x1, y1, x1, top_snap_pos, SNAP_DIR_Y, SNAP_DIR_Y, 0);
+ maybe_update_snap (arr, snap_data, x1, y1, x1, bottom_snap_pos, SNAP_DIR_Y, SNAP_DIR_Y, 0);
}
else if (dist_x < 9999)
{
- maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, y1, SNAP_DIR_X);
- maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, y1, SNAP_DIR_X);
+ maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, y1, SNAP_DIR_X, SNAP_DIR_X, 0);
+ maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, y1, SNAP_DIR_X, SNAP_DIR_X, 0);
}
/* Left/right edge identical on the top */
- maybe_update_snap (arr, snap_data, x1, y1, _x1, top_snap_pos, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, _x2 - w, top_snap_pos, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, _x1, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0);
+ maybe_update_snap (arr, snap_data, x1, y1, _x2 - w, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0);
/* Left/right edge identical on the bottom */
- maybe_update_snap (arr, snap_data, x1, y1, _x1, bottom_snap_pos, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, _x2 - w, bottom_snap_pos, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, _x1, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0);
+ maybe_update_snap (arr, snap_data, x1, y1, _x2 - w, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0);
/* Top/bottom edge identical on the left */
- maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y1, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y2 - h, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y1, SNAP_DIR_BOTH, SNAP_DIR_X, 0);
+ maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y2 - h, SNAP_DIR_BOTH, SNAP_DIR_X, 0);
/* Top/bottom edge identical on the right */
- maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y1, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y2 - h, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y1, SNAP_DIR_BOTH, SNAP_DIR_X, 0);
+ maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y2 - h, SNAP_DIR_BOTH, SNAP_DIR_X, 0);
/* If snapping is infinite, then add snapping points with minimal overlap
* to prevent detachment.
* This is similar to the above but simply re-defines the snapping pos
* to have only minimal overlap */
- if (arr->max_snap_distance == G_MAXUINT)
+ if (arr->major_snap_distance == G_MAXUINT)
{
/* Hanging over the left/right edge on the top */
- maybe_update_snap (arr, snap_data, x1, y1, _x1 - w + MIN_OVERLAP, top_snap_pos, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, _x2 - MIN_OVERLAP, top_snap_pos, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, _x1 - w + MIN_OVERLAP, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 1);
+ maybe_update_snap (arr, snap_data, x1, y1, _x2 - MIN_OVERLAP, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, -1);
/* Left/right edge identical on the bottom */
- maybe_update_snap (arr, snap_data, x1, y1, _x1 - w + MIN_OVERLAP, bottom_snap_pos, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, _x2 - MIN_OVERLAP, bottom_snap_pos, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, _x1 - w + MIN_OVERLAP, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 1);
+ maybe_update_snap (arr, snap_data, x1, y1, _x2 - MIN_OVERLAP, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, -1);
/* Top/bottom edge identical on the left */
- maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y1 - h + MIN_OVERLAP, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y2 - MIN_OVERLAP, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y1 - h + MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, 1);
+ maybe_update_snap (arr, snap_data, x1, y1, left_snap_pos, _y2 - MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, -1);
/* Top/bottom edge identical on the right */
- maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y1 - h + MIN_OVERLAP, SNAP_DIR_BOTH);
- maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y2 - MIN_OVERLAP, SNAP_DIR_BOTH);
+ maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y1 - h + MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, 1);
+ maybe_update_snap (arr, snap_data, x1, y1, right_snap_pos, _y2 - MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, -1);
}
}
}
@@ -469,9 +506,9 @@ on_output_changed_cb (CcDisplayArrangement *arr,
CcDisplayMonitor *output)
{
if (cc_display_config_count_useful_monitors (arr->config) > 2) {
- arr->max_snap_distance = MAX_SNAP_DISTANCE;
+ arr->major_snap_distance = MAJOR_SNAP_DISTANCE;
} else {
- arr->max_snap_distance = G_MAXUINT;
+ arr->major_snap_distance = G_MAXUINT;
}
gtk_widget_queue_draw (GTK_WIDGET (arr));
@@ -857,7 +894,7 @@ cc_display_arrangement_init (CcDisplayArrangement *arr)
gtk_widget_add_events (GTK_WIDGET (arr),
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
- arr->max_snap_distance = MAX_SNAP_DISTANCE;
+ arr->major_snap_distance = MAJOR_SNAP_DISTANCE;
}
CcDisplayArrangement*