From 7f7d946de5af17fdfd674451116eb402861e835e Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <fourdan.olivier@wanadoo.fr>
Date: Wed, 15 Feb 2006 21:13:36 +0000
Subject: [PATCH] Merge a patch from Damon Harper <dl+xfce4-dev@usrbin.ca> that
 implements edge resistance instead of windows snapping

(Old svn revision: 19899)
---
 AUTHORS                      |  1 +
 defaults/defaults            |  1 +
 mcs-plugin/wmtweaks_plugin.c | 10 +++++-
 src/client.c                 | 65 +++++++++++++++++++++++++-----------
 src/settings.c               | 13 ++++++++
 src/settings.h               |  1 +
 6 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 29db1d3a2..20f778024 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,6 +9,7 @@ Contributors :
 Aquila Deus <aquila_deus@yahoo.co.uk>
 Aurelien Foret <orelien@chez.com>
 Benedikt Meurer <Benedikt.Meurer@unix-ag.uni-siegen.de>
+Damon Harper <dl+xfce4-dev@usrbin.ca>
 Ian Morgan <imorgan@webcon.ca>
 Jens Guballa <J.Guballa@t-online.de>
 Juho Vaha-Herttua <juhovh@iki.fi>
diff --git a/defaults/defaults b/defaults/defaults
index e03b2eeca..f2b3c5742 100644
--- a/defaults/defaults
+++ b/defaults/defaults
@@ -31,6 +31,7 @@ shadow_delta_x=0
 shadow_delta_y=0
 snap_to_border=true
 snap_to_windows=false
+snap_resist=true
 snap_width=10
 theme=Default
 title_alignment=left
diff --git a/mcs-plugin/wmtweaks_plugin.c b/mcs-plugin/wmtweaks_plugin.c
index 240c04f1a..92c437630 100644
--- a/mcs-plugin/wmtweaks_plugin.c
+++ b/mcs-plugin/wmtweaks_plugin.c
@@ -66,6 +66,7 @@ static gboolean prevent_focus_stealing = FALSE;
 static gboolean raise_with_any_button  = FALSE;
 static gboolean restore_on_move        = TRUE;
 static gboolean scroll_workspaces      = TRUE;
+static gboolean snap_resist            = TRUE;
 static gboolean toggle_workspaces      = TRUE;
 static gboolean wrap_layout            = FALSE;
 static gboolean wrap_cycle             = FALSE;
@@ -92,7 +93,8 @@ static int popup_opacity = 100;
     "Xfwm/RaiseWithAnyButton"
     "Xfwm/RestoreOnMove"
     "Xfwm/ScrollWorkspaces"
-    "Xfwm/ToggleWorkspaces"
+    "Xfwm/ScrollWorkspaces"
+    "Xfwm/SnapResist"
     "Xfwm/WrapLayout"
     "Xfwm/WrapCycle"
  */
@@ -361,6 +363,12 @@ create_dialog (McsPlugin * mcs_plugin)
     gtk_box_pack_start (GTK_BOX (vbox), check_button, TRUE, FALSE, 0);
     gtk_widget_show (check_button);
     
+    check_button = 
+        create_gboolean_button (mcs_plugin, _("Use edge resistance instead of windows snapping"),
+                                "Xfwm/SnapResist", &snap_resist);
+    gtk_box_pack_start (GTK_BOX (vbox), check_button, TRUE, FALSE, 0);
+    gtk_widget_show (check_button);
+    
     frame = xfce_framebox_new (_("Workspaces"), TRUE);
     gtk_widget_show (frame);
     gtk_box_pack_start (GTK_BOX (vbox1), frame, TRUE, FALSE, 0);
diff --git a/src/client.c b/src/client.c
index 9378d64e7..0d64100e1 100644
--- a/src/client.c
+++ b/src/client.c
@@ -2938,7 +2938,7 @@ clientDrawOutline (Client * c)
 }
 
 static void
-clientSnapPosition (Client * c)
+clientSnapPosition (Client * c, int prev_x, int prev_y)
 {
     Client *c2 = NULL;
     ScreenInfo *screen_info = NULL;
@@ -2990,24 +2990,36 @@ clientSnapPosition (Client * c)
     {
         if (abs (disp_x - frame_x) < abs (disp_max_x - frame_x2))
         {
-            best_delta_x = abs (disp_x - frame_x);
-            best_frame_x = disp_x;
+            if (!screen_info->params->snap_resist || ((frame_x <= disp_x) && (c->x < prev_x)))
+            {
+                best_delta_x = abs (disp_x - frame_x);
+                best_frame_x = disp_x;
+            }
         }
         else
         {
-            best_delta_x = abs (disp_max_x - frame_x2);
-            best_frame_x = disp_max_x - frame_width;
+            if (!screen_info->params->snap_resist || ((frame_x2 >= disp_max_x) && (c->x > prev_x))) 
+            {
+                best_delta_x = abs (disp_max_x - frame_x2);
+                best_frame_x = disp_max_x - frame_width;
+            }
         }
 
         if (abs (disp_y - frame_y) < abs (disp_max_y - frame_y2))
         {
-            best_delta_y = abs (disp_y - frame_y);
-            best_frame_y = disp_y;
+            if (!screen_info->params->snap_resist || ((frame_y <= disp_y) && (c->y < prev_y)))
+            {
+                best_delta_y = abs (disp_y - frame_y);
+                best_frame_y = disp_y;
+            }
         }
         else
         {
-            best_delta_y = abs (disp_max_y - frame_y2);
-            best_frame_y = disp_max_y - frame_height;
+            if (!screen_info->params->snap_resist || ((frame_y2 >= disp_max_y) && (c->y > prev_y)))
+            {
+                best_delta_y = abs (disp_max_y - frame_y2);
+                best_frame_y = disp_max_y - frame_height;
+            }
         }
     }
 
@@ -3029,15 +3041,21 @@ clientSnapPosition (Client * c)
                 delta = abs (c_frame_x2 - frame_x);
                 if (delta < best_delta_x)
                 {
-                    best_delta_x = delta;
-                    best_frame_x = c_frame_x2;
+                    if (!screen_info->params->snap_resist || ((frame_x <= c_frame_x2) && (c->x < prev_x)))
+                    {
+                        best_delta_x = delta;
+                        best_frame_x = c_frame_x2;
+                    }
                 }
 
                 delta = abs (c_frame_x1 - frame_x2);
                 if (delta < best_delta_x)
                 {
-                    best_delta_x = delta;
-                    best_frame_x = c_frame_x1 - frame_width;
+                    if (!screen_info->params->snap_resist || ((frame_x2 >= c_frame_x1) && (c->x > prev_x)))
+                    {
+                        best_delta_x = delta;
+                        best_frame_x = c_frame_x1 - frame_width;
+                    }
                 }
             }
 
@@ -3046,15 +3064,21 @@ clientSnapPosition (Client * c)
                 delta = abs (c_frame_y2 - frame_y);
                 if (delta < best_delta_y)
                 {
-                    best_delta_y = delta;
-                    best_frame_y = c_frame_y2;
+                    if (!screen_info->params->snap_resist || ((frame_y <= c_frame_y2) && (c->y < prev_y)))
+                    {
+                        best_delta_y = delta;
+                        best_frame_y = c_frame_y2;
+                    }
                 }
 
                 delta = abs (c_frame_y1 - frame_y2);
                 if (delta < best_delta_y)
                 {
-                    best_delta_y = delta;
-                    best_frame_y = c_frame_y1 - frame_height;
+                    if (!screen_info->params->snap_resist || ((frame_y2 >= c_frame_y1) && (c->y > prev_y)))
+                    {
+                        best_delta_y = delta;
+                        best_frame_y = c_frame_y1 - frame_height;
+                    }
                 }
             }
         }
@@ -3085,10 +3109,13 @@ clientMove_event_filter (XEvent * xevent, gpointer data)
     gboolean moving = TRUE;
     gboolean warp_pointer = FALSE;
     XWindowChanges wc;
+    int prev_x, prev_y;
 
     TRACE ("entering clientMove_event_filter");
 
     c = passdata->c;
+    prev_x=c->x;
+    prev_y=c->y;
     screen_info = c->screen_info;
     display_info = screen_info->display_info;
 
@@ -3126,7 +3153,7 @@ clientMove_event_filter (XEvent * xevent, gpointer data)
                 c->y = c->y + 16;
             }
             clientConstrainPos (c, FALSE);
-            clientSnapPosition (c);
+            clientSnapPosition (c, prev_x, prev_y);
 
 #ifdef SHOW_POSITION
             if (passdata->poswin)
@@ -3347,7 +3374,7 @@ clientMove_event_filter (XEvent * xevent, gpointer data)
         {
             clientConstrainPos(c, FALSE);
         }
-        clientSnapPosition (c);
+        clientSnapPosition (c, prev_x, prev_y);
 
 #ifdef SHOW_POSITION
         if (passdata->poswin)
diff --git a/src/settings.c b/src/settings.c
index c72ac5ca4..ac88af13f 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -389,6 +389,10 @@ notify_cb (const char *name, const char *channel_name, McsAction action, McsSett
                         screen_info->params->show_popup_shadow = setting->data.v_int;
                         reloadScreenSettings (screen_info, UPDATE_FRAME);
                     }
+                    else if (!strcmp (name, "Xfwm/SnapResist"))
+                    {
+                        screen_info->params->snap_resist = setting->data.v_int;
+                    }
                     else if (!strcmp (name, "Xfwm/PreventFocusStealing"))
                     {
                         screen_info->params->prevent_focus_stealing = setting->data.v_int;
@@ -734,6 +738,12 @@ loadMcsData (ScreenInfo *screen_info, Settings *rc)
             setBooleanValueFromInt ("show_popup_shadow", setting->data.v_int, rc);
             mcs_setting_free (setting);
         }
+        if (mcs_client_get_setting (screen_info->mcs_client, "Xfwm/SnapResist", CHANNEL5,
+                &setting) == MCS_SUCCESS)
+        {
+            setBooleanValueFromInt ("snap_resist", setting->data.v_int, rc);
+            mcs_setting_free (setting);
+        }
         if (mcs_client_get_setting (screen_info->mcs_client, "Xfwm/PreventFocusStealing", CHANNEL5,
                 &setting) == MCS_SUCCESS)
         {
@@ -1206,6 +1216,7 @@ loadSettings (ScreenInfo *screen_info)
         {"raise_with_any_button", NULL, TRUE},
         {"snap_to_border", NULL, TRUE},
         {"snap_to_windows", NULL, TRUE},
+        {"snap_resist", NULL, TRUE},
         {"snap_width", NULL, TRUE},
         {"shadow_delta_x", NULL, TRUE},
         {"shadow_delta_y", NULL, TRUE},
@@ -1351,6 +1362,8 @@ loadSettings (ScreenInfo *screen_info)
         !g_ascii_strcasecmp ("true", getValue ("snap_to_border", rc));
     screen_info->params->snap_to_windows =
         !g_ascii_strcasecmp ("true", getValue ("snap_to_windows", rc));
+    screen_info->params->snap_resist =
+        !g_ascii_strcasecmp ("true", getValue ("snap_resist", rc));
     screen_info->params->snap_width = abs (TOINT (getValue ("snap_width", rc)));
 
     set_settings_margin (screen_info, LEFT,   TOINT (getValue ("margin_left", rc)));
diff --git a/src/settings.h b/src/settings.h
index 2722984b3..05d15b2a0 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -181,6 +181,7 @@ struct _XfwmParams
     gboolean show_popup_shadow;
     gboolean snap_to_border;
     gboolean snap_to_windows;
+    gboolean snap_resist;
     gboolean title_vertical_offset_active;
     gboolean title_vertical_offset_inactive;
     gboolean toggle_workspaces;
-- 
GitLab