xfwm4 feature request / patch

Damon Harper dl+xfce4-dev at usrbin.ca
Mon Feb 13 09:02:16 CET 2006


hello xfce devs!

i started using xfce about half a year ago, but missed too much about
my former window manager (windowmaker) to migrate to xfwm4.  but the
mix of windowmaker and the other xfce components is an uneasy one, so
i'm trying to make the switch now.

in the interests of making all window managers the same, i decided to
try duplicating some of the functionality i missed.  i started small.
i love windowmaker's `edge resist' feature, where the edges of the
screen and/or other windows resist movement beyond them for a certain
number of pixels, but don't `pull' a nearby window towards them on
approach.  xfwm4 has the `snap' behaviour, but i don't like the way it
works as an attractor.  subtle difference but one that bothered me no
end.

so attached are two copies of a patch (one against xfwm4 4.2.3.2 and
one against SVN) that adds another toggle option to the advanced tab
in xfwm4_plugin, to turn `snap' into `resist' instead.

i'm not sure what the xfce project's policy is on feature creep, but
i'm hoping someone might like this enough to merge it into the main
sources.  i see that a lot of options are now going in a `wmtweaks'
config panel in SVN, but since this one is so closely related to the
snap feature, i suspect it should remain with the other snap settings.
maybe all of the `advanced' tab in xfwm4_plugin is going to move to
wmtweaks_plugin eventually?

-damon
-------------- next part --------------
diff -urN xfwm4-4.2.3.2.orig/defaults/defaults xfwm4-4.2.3.2/defaults/defaults
--- xfwm4-4.2.3.2.orig/defaults/defaults	2005-11-15 03:55:31.000000000 -0800
+++ xfwm4-4.2.3.2/defaults/defaults	2006-02-04 10:21:17.000000000 -0800
@@ -27,6 +27,7 @@
 shadow_delta_y=0
 snap_to_border=true
 snap_to_windows=false
+snap_resist=false
 snap_width=10
 theme=Default
 title_alignment=left
diff -urN xfwm4-4.2.3.2.orig/mcs-plugin/xfwm4_plugin.c xfwm4-4.2.3.2/mcs-plugin/xfwm4_plugin.c
--- xfwm4-4.2.3.2.orig/mcs-plugin/xfwm4_plugin.c	2005-11-15 03:58:23.000000000 -0800
+++ xfwm4-4.2.3.2/mcs-plugin/xfwm4_plugin.c	2006-02-04 10:24:41.000000000 -0800
@@ -113,6 +113,7 @@
 static gboolean raise_on_click = TRUE;
 static gboolean snap_to_border = TRUE;
 static gboolean snap_to_windows = FALSE;
+static gboolean snap_resist = FALSE;
 static gboolean wrap_workspaces = FALSE;
 static gboolean wrap_windows = TRUE;
 static gboolean box_move = FALSE;
@@ -1180,6 +1181,7 @@
 
     snap_to_border = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->snap_to_border_check));
     gtk_widget_set_sensitive (itf->snap_width_scale, snap_to_windows || snap_to_border);
+    gtk_widget_set_sensitive (itf->snap_resist_check, snap_to_windows || snap_to_border);
 
     mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapToBorder", CHANNEL1, snap_to_border ? 1 : 0);
     mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
@@ -1194,6 +1196,7 @@
 
     snap_to_windows = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->snap_to_windows_check));
     gtk_widget_set_sensitive (itf->snap_width_scale, snap_to_windows || snap_to_border);
+    gtk_widget_set_sensitive (itf->snap_resist_check, snap_to_windows || snap_to_border);
 
     mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapToWindows", CHANNEL1, snap_to_windows ? 1 : 0);
     mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
@@ -1201,6 +1204,19 @@
 }
 
 static void
+cb_snap_resist_changed (GtkWidget * dialog, gpointer user_data)
+{
+    Itf *itf = (Itf *) user_data;
+    McsPlugin *mcs_plugin = itf->mcs_plugin;
+
+    snap_resist = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->snap_resist_check));
+
+    mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapResist", CHANNEL1, snap_resist ? 1 : 0);
+    mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
+    write_options (mcs_plugin);
+}
+
+static void
 cb_snap_width_changed (GtkWidget * dialog, gpointer user_data)
 {
     Itf *itf = (Itf *) user_data;
@@ -1718,6 +1734,12 @@
     gtk_box_pack_start (GTK_BOX (vbox5), dialog->snap_to_windows_check, FALSE, FALSE, 0);
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->snap_to_windows_check), snap_to_windows);
 
+    dialog->snap_resist_check = gtk_check_button_new_with_mnemonic (_("Resist only, do not snap on approach"));
+    gtk_widget_show (dialog->snap_resist_check);
+    gtk_box_pack_start (GTK_BOX (vbox5), dialog->snap_resist_check, FALSE, FALSE, 0);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->snap_resist_check), snap_resist);
+    gtk_widget_set_sensitive (dialog->snap_resist_check, snap_to_border || snap_to_windows);
+
     table3 = gtk_table_new (2, 3, FALSE);
     gtk_widget_show (table3);
     gtk_box_pack_start (GTK_BOX (vbox5), table3, TRUE, TRUE, 0);
@@ -1916,6 +1938,7 @@
     g_signal_connect (G_OBJECT (itf->click_raise_check), "toggled", G_CALLBACK (cb_raise_on_click_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_to_border_check), "toggled", G_CALLBACK (cb_snap_to_border_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_to_windows_check), "toggled", G_CALLBACK (cb_snap_to_windows_changed), itf);
+    g_signal_connect (G_OBJECT (itf->snap_resist_check), "toggled", G_CALLBACK (cb_snap_resist_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_width_scale), "value_changed", (GCallback) cb_snap_width_changed, itf);
     g_signal_connect (G_OBJECT (itf->wrap_workspaces_check), "toggled", G_CALLBACK (cb_wrap_workspaces_changed), itf);
     g_signal_connect (G_OBJECT (itf->wrap_windows_check), "toggled", G_CALLBACK (cb_wrap_windows_changed), itf);
@@ -2122,6 +2145,17 @@
         mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapToWindows", CHANNEL1, snap_to_windows ? 1 : 0);
     }
 
+    setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Xfwm/SnapResist", CHANNEL1);
+    if (setting)
+    {
+        snap_resist = (setting->data.v_int ? TRUE : FALSE);
+    }
+    else
+    {
+        snap_resist = FALSE;
+        mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapResist", CHANNEL1, snap_resist ? 1 : 0);
+    }
+
     setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Xfwm/SnapWidth", CHANNEL1);
     if (setting)
     {
diff -urN xfwm4-4.2.3.2.orig/mcs-plugin/xfwm4_plugin.h xfwm4-4.2.3.2/mcs-plugin/xfwm4_plugin.h
--- xfwm4-4.2.3.2.orig/mcs-plugin/xfwm4_plugin.h	2005-11-15 03:55:32.000000000 -0800
+++ xfwm4-4.2.3.2/mcs-plugin/xfwm4_plugin.h	2006-02-04 09:29:19.000000000 -0800
@@ -93,6 +93,7 @@
     GtkWidget *scrolledwindow4;
     GtkWidget *snap_to_border_check;
     GtkWidget *snap_to_windows_check;
+    GtkWidget *snap_resist_check;
     GtkWidget *snap_width_scale;
     GtkWidget *treeview1;
     GtkWidget *treeview2;
diff -urN xfwm4-4.2.3.2.orig/src/client.c xfwm4-4.2.3.2/src/client.c
--- xfwm4-4.2.3.2.orig/src/client.c	2005-11-15 03:55:19.000000000 -0800
+++ xfwm4-4.2.3.2/src/client.c	2006-02-04 11:53:02.000000000 -0800
@@ -2708,7 +2708,7 @@
 }
 
 static void
-clientSnapPosition (Client * c)
+clientSnapPosition (Client * c, int prev_x, int prev_y)
 {
     Client *c2 = NULL;
     ScreenInfo *screen_info = NULL;
@@ -2760,24 +2760,32 @@
     {
         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;
+            }
         }
     }
 
@@ -2799,15 +2807,19 @@
                 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;
+                    }
                 }
             }
 
@@ -2816,15 +2828,19 @@
                 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;
+                    }
                 }
             }
         }
@@ -2852,10 +2868,13 @@
     Client *c = NULL;
     gboolean moving = TRUE;
     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;
 
@@ -3023,7 +3042,7 @@
         c->x = passdata->ox + (xevent->xmotion.x_root - passdata->mx);
         c->y = passdata->oy + (xevent->xmotion.y_root - passdata->my);
 
-        clientSnapPosition (c);
+        clientSnapPosition (c, prev_x, prev_y);
         clientConstrainPos (c, FALSE);
 
 #ifdef SHOW_POSITION
diff -urN xfwm4-4.2.3.2.orig/src/settings.c xfwm4-4.2.3.2/src/settings.c
--- xfwm4-4.2.3.2.orig/src/settings.c	2005-11-15 03:55:19.000000000 -0800
+++ xfwm4-4.2.3.2/src/settings.c	2006-02-04 12:05:51.000000000 -0800
@@ -210,6 +206,10 @@
                     {
                         screen_info->params->snap_to_windows = setting->data.v_int;
                     }
+                    else if (!strcmp (name, "Xfwm/SnapResist"))
+                    {
+                        screen_info->params->snap_resist = setting->data.v_int;
+                    }
                     else if (!strcmp (name, "Xfwm/SnapWidth"))
                     {
                         screen_info->params->snap_width = setting->data.v_int;
@@ -509,6 +509,13 @@
                 rc);
             mcs_setting_free (setting);
         }
+        if (mcs_client_get_setting (screen_info->mcs_client, "Xfwm/SnapResist", CHANNEL1,
+                &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/SnapWidth", CHANNEL1,
                 &setting) == MCS_SUCCESS)
         {
@@ -1124,6 +1131,7 @@
         {"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},
@@ -1266,6 +1274,8 @@
         !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 -urN xfwm4-4.2.3.2.orig/src/settings.h xfwm4-4.2.3.2/src/settings.h
--- xfwm4-4.2.3.2.orig/src/settings.h	2005-11-15 03:55:19.000000000 -0800
+++ xfwm4-4.2.3.2/src/settings.h	2006-02-04 09:24:45.000000000 -0800
@@ -179,6 +179,7 @@
     gboolean scroll_workspaces;
     gboolean snap_to_border;
     gboolean snap_to_windows;
+    gboolean snap_resist;
     gboolean title_vertical_offset_active;
     gboolean title_vertical_offset_inactive;
     gboolean toggle_workspaces;
-------------- next part --------------
diff -urN xfwm4-svn.orig/defaults/defaults xfwm4-svn/defaults/defaults
--- xfwm4-svn.orig/defaults/defaults	2006-02-11 13:12:36.000000000 -0800
+++ xfwm4-svn/defaults/defaults	2006-02-11 13:15:08.000000000 -0800
@@ -31,6 +31,7 @@
 shadow_delta_y=0
 snap_to_border=true
 snap_to_windows=false
+snap_resist=false
 snap_width=10
 theme=Default
 title_alignment=left
diff -urN xfwm4-svn.orig/mcs-plugin/xfwm4_plugin.c xfwm4-svn/mcs-plugin/xfwm4_plugin.c
--- xfwm4-svn.orig/mcs-plugin/xfwm4_plugin.c	2006-02-11 13:12:43.000000000 -0800
+++ xfwm4-svn/mcs-plugin/xfwm4_plugin.c	2006-02-11 14:05:57.000000000 -0800
@@ -106,6 +106,7 @@
 static gboolean raise_on_click = TRUE;
 static gboolean snap_to_border = TRUE;
 static gboolean snap_to_windows = FALSE;
+static gboolean snap_resist = FALSE;
 static gboolean wrap_workspaces = FALSE;
 static gboolean wrap_windows = TRUE;
 static gboolean box_move = FALSE;
@@ -1170,6 +1171,7 @@
 
     snap_to_border = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->snap_to_border_check));
     gtk_widget_set_sensitive (itf->snap_width_scale, snap_to_windows || snap_to_border);
+    gtk_widget_set_sensitive (itf->snap_resist_check, snap_to_windows || snap_to_border);
 
     mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapToBorder", CHANNEL1, snap_to_border ? 1 : 0);
     mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
@@ -1184,6 +1186,7 @@
 
     snap_to_windows = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->snap_to_windows_check));
     gtk_widget_set_sensitive (itf->snap_width_scale, snap_to_windows || snap_to_border);
+    gtk_widget_set_sensitive (itf->snap_resist_check, snap_to_windows || snap_to_border);
 
     mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapToWindows", CHANNEL1, snap_to_windows ? 1 : 0);
     mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
@@ -1191,6 +1194,19 @@
 }
 
 static void
+cb_snap_resist_changed (GtkWidget * dialog, gpointer user_data)
+{
+    Itf *itf = (Itf *) user_data;
+    McsPlugin *mcs_plugin = itf->mcs_plugin;
+
+    snap_resist = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (itf->snap_resist_check));
+
+    mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapResist", CHANNEL1, snap_resist ? 1 : 0);
+    mcs_manager_notify (mcs_plugin->manager, CHANNEL1);
+    xfwm4_plugin_write_options (mcs_plugin);
+}
+
+static void
 cb_snap_width_changed (GtkWidget * dialog, gpointer user_data)
 {
     Itf *itf = (Itf *) user_data;
@@ -1668,6 +1684,12 @@
     gtk_box_pack_start (GTK_BOX (vbox), dialog->snap_to_windows_check, FALSE, FALSE, 0);
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->snap_to_windows_check), snap_to_windows);
 
+    dialog->snap_resist_check = gtk_check_button_new_with_mnemonic (_("Resist only, do not snap on approach"));
+    gtk_widget_show (dialog->snap_resist_check);
+    gtk_box_pack_start (GTK_BOX (vbox), dialog->snap_resist_check, FALSE, FALSE, 0);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->snap_resist_check), snap_resist);
+    gtk_widget_set_sensitive (dialog->snap_resist_check, snap_to_border || snap_to_windows);
+
     table = gtk_table_new (2, 3, FALSE);
     gtk_widget_show (table);
     gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
@@ -1863,6 +1885,7 @@
     g_signal_connect (G_OBJECT (itf->click_raise_check), "toggled", G_CALLBACK (cb_raise_on_click_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_to_border_check), "toggled", G_CALLBACK (cb_snap_to_border_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_to_windows_check), "toggled", G_CALLBACK (cb_snap_to_windows_changed), itf);
+    g_signal_connect (G_OBJECT (itf->snap_resist_check), "toggled", G_CALLBACK (cb_snap_resist_changed), itf);
     g_signal_connect (G_OBJECT (itf->snap_width_scale), "value_changed", (GCallback) cb_snap_width_changed, itf);
     g_signal_connect (G_OBJECT (itf->wrap_workspaces_check), "toggled", G_CALLBACK (cb_wrap_workspaces_changed), itf);
     g_signal_connect (G_OBJECT (itf->wrap_windows_check), "toggled", G_CALLBACK (cb_wrap_windows_changed), itf);
@@ -2069,6 +2092,17 @@
         mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapToWindows", CHANNEL1, snap_to_windows ? 1 : 0);
     }
 
+    setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Xfwm/SnapResist", CHANNEL1);
+    if (setting)
+    {
+        snap_resist = (setting->data.v_int ? TRUE : FALSE);
+    }
+    else
+    {
+        snap_resist = FALSE;
+        mcs_manager_set_int (mcs_plugin->manager, "Xfwm/SnapResist", CHANNEL1, snap_resist ? 1 : 0);
+    }
+
     setting = mcs_manager_setting_lookup (mcs_plugin->manager, "Xfwm/SnapWidth", CHANNEL1);
     if (setting)
     {
diff -urN xfwm4-svn.orig/mcs-plugin/xfwm4_plugin.h xfwm4-svn/mcs-plugin/xfwm4_plugin.h
--- xfwm4-svn.orig/mcs-plugin/xfwm4_plugin.h	2006-02-11 13:12:43.000000000 -0800
+++ xfwm4-svn/mcs-plugin/xfwm4_plugin.h	2006-02-11 13:15:08.000000000 -0800
@@ -93,6 +93,7 @@
     GtkWidget *scrolledwindow4;
     GtkWidget *snap_to_border_check;
     GtkWidget *snap_to_windows_check;
+    GtkWidget *snap_resist_check;
     GtkWidget *snap_width_scale;
     GtkWidget *treeview1;
     GtkWidget *treeview2;
diff -urN xfwm4-svn.orig/src/client.c xfwm4-svn/src/client.c
--- xfwm4-svn.orig/src/client.c	2006-02-11 13:12:24.000000000 -0800
+++ xfwm4-svn/src/client.c	2006-02-11 14:05:10.000000000 -0800
@@ -2920,7 +2920,7 @@
 }
 
 static void
-clientSnapPosition (Client * c)
+clientSnapPosition (Client * c, int prev_x, int prev_y)
 {
     Client *c2 = NULL;
     ScreenInfo *screen_info = NULL;
@@ -2972,24 +2972,32 @@
     {
         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;
+            }
         }
     }
 
@@ -3011,15 +3019,19 @@
                 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;
+                    }
                 }
             }
 
@@ -3028,15 +3040,19 @@
                 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;
+                    }
                 }
             }
         }
@@ -3067,10 +3083,13 @@
     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;
 
@@ -3108,7 +3127,7 @@
                 c->y = c->y + 16;
             }
             clientConstrainPos (c, FALSE);
-            clientSnapPosition (c);
+            clientSnapPosition (c, prev_x, prev_y);
 
 #ifdef SHOW_POSITION
             if (passdata->poswin)
@@ -3329,7 +3348,7 @@
         {
             clientConstrainPos(c, FALSE);
         }
-        clientSnapPosition (c);
+        clientSnapPosition (c, prev_x, prev_y);
 
 #ifdef SHOW_POSITION
         if (passdata->poswin)
diff -urN xfwm4-svn.orig/src/settings.c xfwm4-svn/src/settings.c
--- xfwm4-svn.orig/src/settings.c	2006-02-11 13:12:25.000000000 -0800
+++ xfwm4-svn/src/settings.c	2006-02-11 13:15:08.000000000 -0800
@@ -190,6 +190,10 @@
                     {
                         screen_info->params->snap_to_windows = setting->data.v_int;
                     }
+                    else if (!strcmp (name, "Xfwm/SnapResist"))
+                    {
+                        screen_info->params->snap_resist = setting->data.v_int;
+                    }
                     else if (!strcmp (name, "Xfwm/SnapWidth"))
                     {
                         screen_info->params->snap_width = setting->data.v_int;
@@ -558,6 +562,13 @@
                 rc);
             mcs_setting_free (setting);
         }
+        if (mcs_client_get_setting (screen_info->mcs_client, "Xfwm/SnapResist", CHANNEL1,
+                &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/SnapWidth", CHANNEL1,
                 &setting) == MCS_SUCCESS)
         {
@@ -1206,6 +1217,7 @@
         {"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 +1363,8 @@
         !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 -urN xfwm4-svn.orig/src/settings.h xfwm4-svn/src/settings.h
--- xfwm4-svn.orig/src/settings.h	2006-02-11 13:12:26.000000000 -0800
+++ xfwm4-svn/src/settings.h	2006-02-11 13:15:08.000000000 -0800
@@ -181,6 +181,7 @@
     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;


More information about the Xfce4-dev mailing list