[gnome-control-center/wip/benzea/display: 48/49] display: Enable infinit snapping when arranging two monitors



commit a92d595f00b0fd86cae4c9b671f191fb25e97d99
Author: Benjamin Berg <bberg redhat com>
Date:   Mon Apr 23 15:00:51 2018 +0200

    display: Enable infinit snapping when arranging two monitors
    
    Two monitors are a special case where it is easy to ensure that the
    monitors are always adjacent to each other by special casing the
    snapping code. Do so by increasing the snapping distance to infinity and
    adding extra snapping points so that corner cases are covered.

 panels/display/cc-display-arrangement.c | 36 ++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)
---
diff --git a/panels/display/cc-display-arrangement.c b/panels/display/cc-display-arrangement.c
index 5927734b9..e4f9fbe16 100644
--- a/panels/display/cc-display-arrangement.c
+++ b/panels/display/cc-display-arrangement.c
@@ -42,6 +42,8 @@ struct _CcDisplayArrangement
   /* Starting position of cursor inside the monitor. */
   gdouble           drag_anchor_x;
   gdouble           drag_anchor_y;
+
+  guint             max_snap_distance;
 };
 
 typedef struct _CcDisplayArrangement CcDisplayArrangement;
@@ -71,6 +73,7 @@ struct SnapData {
 #define MARGIN_PX  0
 #define MARGIN_MON  0.66
 #define MAX_SNAP_DISTANCE 10
+#define MIN_OVERLAP 25
 
 G_DEFINE_TYPE (CcDisplayArrangement, cc_display_arrangement, GTK_TYPE_DRAWING_AREA)
 
@@ -222,7 +225,7 @@ 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 > MAX_SNAP_DISTANCE)
+  if (dist > arr->max_snap_distance)
     return;
 
   if (snapped == SNAP_DIR_BOTH)
@@ -355,6 +358,29 @@ find_best_snapping (CcDisplayArrangement *arr,
       /* 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);
+
+      /* 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)
+        {
+          /* 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);
+
+          /* 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);
+
+          /* 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);
+
+          /* 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);
+        }
     }
 }
 #undef OVERLAP
@@ -441,6 +467,12 @@ cc_display_arrangement_update_cursor (CcDisplayArrangement *arr,
 static void
 output_changed_cb (CcDisplayArrangement *arr, CcDisplayMonitor *output)
 {
+  if (cc_display_config_count_useful_monitors (arr->config) > 2) {
+    arr->max_snap_distance = MAX_SNAP_DISTANCE;
+  } else {
+    arr->max_snap_distance = G_MAXUINT;
+  }
+
   gtk_widget_queue_draw (GTK_WIDGET (arr));
 }
 
@@ -822,6 +854,8 @@ cc_display_arrangement_init (CcDisplayArrangement *arr)
   /* XXX: Do we need to listen to touch events here? */
   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;
 }
 
 CcDisplayArrangement*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]