Patch to movehandle widget to make window snap to corners and edge centers
Jasper Huijsmans
jasper at moongroup.com
Sat Mar 8 20:30:20 CET 2003
On 07 Mar 2003 20:52:22 +0100
Olivier Fourdan <fourdan at xfce.org> wrote:
> Hi Jasper,
>
> I guess you can forget about struts awareness, but Xinerama would be
> definitly usefull.
>
So, how about this. I haven't actually tested this with Xinerama, so it
would be helpful if somebody could do that for me.
Index: xfce_movehandler.c
===================================================================
RCS file:
/cvsroot/xfce/xfce-devel/libxfcegui4/libxfcegui4/xfce_movehandler.c,v
retrieving revision 1.5
diff -u -r1.5 xfce_movehandler.c
--- xfce_movehandler.c 18 Oct 2002 13:00:52 -0000 1.5
+++ xfce_movehandler.c 8 Mar 2003 18:52:39 -0000
@@ -24,9 +24,12 @@
#include <stdlib.h>
#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
#include <gdk/gdkcursor.h>
#include <gtk/gtkwindow.h>
#include "xfce_movehandler.h"
+#include "xinerama.h"
+#include "debug.h"
#define DECOR_WIDTH 6
#define DECOR_HEIGHT 6
@@ -286,6 +289,65 @@
}
}
+static void update_snap_coordinates(XfceMovehandler *movehandler)
+{
+ GtkWidget *win;
+ int x, y;
+ Display *dpy;
+ int scr;
+
+ win = movehandler->gtk_window;
+
+ /* TODO: for gtk 2.2 we could use gtk_widget_get_display() et al.
*/
+ dpy = gdk_display;
+ scr = DefaultScreen(dpy);
+
+ x = win->allocation.x + win->allocation.width / 2;
+ y = win->allocation.y + win->allocation.height / 2;
+
+ movehandler->screen_x = MyDisplayX(x, y);
+ movehandler->screen_maxx = MyDisplayMaxX(dpy, scr, x, y);
+ movehandler->screen_y = MyDisplayY(x, y);
+ movehandler->screen_maxy = MyDisplayMaxY(dpy, scr, x, y);
+
+ /* Snap coordinates: 4 corners + 4 edge centers */
+ /* top left */
+ movehandler->snapx[0] = movehandler->screen_x;
+ movehandler->snapy[0] = movehandler->screen_y;
+
+ /* top right */
+ movehandler->snapx[1] = movehandler->screen_maxx -
win->allocation.width;
+ movehandler->snapy[1] = movehandler->screen_y;
+
+ /* bottom left */
+ movehandler->snapx[2] = movehandler->screen_x;
+ movehandler->snapy[2] = movehandler->screen_maxy -
win->allocation.height;
+
+ /* bottom right */
+ movehandler->snapx[3] = movehandler->snapx[1];
+ movehandler->snapy[3] = movehandler->snapy[2];
+
+ /* top center */
+ movehandler->snapx[4] =
+ (movehandler->screen_maxy - movehandler->screen_y) / 2
+ - win->allocation.width / 2;
+ movehandler->snapy[4] = movehandler->screen_y;
+
+ /* bottom center */
+ movehandler->snapx[5] = movehandler->snapx[4];
+ movehandler->snapy[5] = movehandler->snapy[2];
+
+ /* left center */
+ movehandler->snapx[6] = movehandler->screen_x;
+ movehandler->snapy[6] =
+ (movehandler->screen_maxy - movehandler->screen_y)/ 2
+ - win->allocation.height / 2;
+
+ /* right center */
+ movehandler->snapx[7] = movehandler->snapx[1];
+ movehandler->snapy[7] = movehandler->snapy[6];
+}
+
static gint xfce_movehandler_button_changed (GtkWidget *widget,
GdkEventButton *event)
{
XfceMovehandler *movehandler;
@@ -320,6 +382,8 @@
movehandler->deskoff_x = desk_x - root_x;
movehandler->deskoff_y = desk_y - root_y;
+ update_snap_coordinates(movehandler);
+
movehandler->in_drag = TRUE;
fleur = gdk_cursor_new (GDK_FLEUR);
if (gdk_pointer_grab (widget->window, FALSE,
(GDK_BUTTON1_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON_RELEASE_MASK), NULL, fleur, GDK_CURRENT_TIME) != 0)
@@ -344,6 +408,54 @@
return event_handled;
}
+#define SNAP_DISTANCE 20
+
+static void snap_to_corners(XfceMovehandler *movehandler, int *x, int
*y)
+{
+ int i, center_x, center_y;
+ int *snapx, *snapy;
+ GtkWidget *win;
+
+ win = movehandler->gtk_window;
+
+ center_x = win->allocation.x + win->allocation.width / 2;
+ center_y = win->allocation.y + win->allocation.height / 2;
+
+#if defined(HAVE_LIBXINERAMA) || defined(EMULATE_XINERAMA)
+ if (center_x < movehandler->screen_x ||
+ center_x > movehandler->screen_maxx ||
+ center_y < movehandler->screen_y ||
+ center_y > movehandler->screen_maxy)
+ {
+ update_snap_coordinates(movehandler);
+ }
+#endif
+
+ snapx = movehandler->snapx;
+ snapy = movehandler->snapy;
+
+ /* snap to corners or edge centers (8 snap positions) */
+ for (i = 0; i < 8; i++)
+ {
+ int minx, maxx, miny, maxy;
+
+ minx = snapx[i] - SNAP_DISTANCE;
+ maxx = snapx[i] + SNAP_DISTANCE;
+ miny = snapy[i] - SNAP_DISTANCE;
+ maxy = snapy[i] + SNAP_DISTANCE;
+
+ if (*x > minx && *x < maxx && *y > miny && *y < maxy)
+ {
+ *x = snapx[i];
+ *y = snapy[i];
+
+ DBG("snap: (x,y) = (%d,%d)\n", *x, *y);
+
+ break;
+ }
+ }
+}
+
static gint xfce_movehandler_motion (GtkWidget *widget, GdkEventMotion
*event)
{
XfceMovehandler *movehandler;
@@ -367,6 +479,8 @@
new_x += movehandler->float_allocation.x + movehandler->deskoff_x;
new_y += movehandler->float_allocation.y + movehandler->deskoff_y;
+ snap_to_corners(movehandler, &new_x, &new_y);
+
gdk_window_move (movehandler->float_window, new_x, new_y);
gdk_window_raise (movehandler->float_window);
Index: xfce_movehandler.h
===================================================================
RCS file:
/cvsroot/xfce/xfce-devel/libxfcegui4/libxfcegui4/xfce_movehandler.h,v
retrieving revision 1.4
diff -u -r1.4 xfce_movehandler.h
--- xfce_movehandler.h 8 Oct 2002 19:56:37 -0000 1.4
+++ xfce_movehandler.h 8 Mar 2003 18:52:39 -0000
@@ -51,6 +51,9 @@
GdkBitmap *dark_bmap;
GdkBitmap *mid_bmap;
GdkBitmap *light_bmap;
+
+ gint screen_x, screen_maxx, screen_y, screen_maxy;
+ gint snapx[8], snapy[8];
};
struct _XfceMovehandlerClass
More information about the Xfce4-dev
mailing list