summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOlivier Fourdan <fourdan.olivier@wanadoo.fr>2008-06-01 21:24:07 +0000
committerOlivier Fourdan <fourdan.olivier@wanadoo.fr>2008-06-01 21:24:07 +0000
commit4d1bc970fbc1dc433d00489cfde6acdc3062686f (patch)
treec4adf551887c92e16549a136e2b1b6329a557bb9 /src
parentbcb1260fc8c770f3f29df52468d6973df8cf8c7e (diff)
downloadxfwm4-4d1bc970fbc1dc433d00489cfde6acdc3062686f.tar.gz
Rework move/resize, better keyboard operations, allow move/resize from menu and from taskbar - TODO: Change keyboard shortcuts accordingly
(Old svn revision: 27007)
Diffstat (limited to 'src')
-rw-r--r--src/client.c12
-rw-r--r--src/display.c2
-rw-r--r--src/display.h4
-rw-r--r--src/events.c27
-rw-r--r--src/menu.c3
-rw-r--r--src/menu.h28
-rw-r--r--src/moveresize.c493
-rw-r--r--src/netwm.c36
-rw-r--r--src/screen.c18
-rw-r--r--src/screen.h4
10 files changed, 344 insertions, 283 deletions
diff --git a/src/client.c b/src/client.c
index 72fac503f..8d8054d0f 100644
--- a/src/client.c
+++ b/src/client.c
@@ -68,6 +68,8 @@
#define FRAME_EVENT_MASK \
SubstructureNotifyMask|\
SubstructureRedirectMask|\
+ PointerMotionMask|\
+ ButtonMotionMask|\
FocusChangeMask|\
EnterWindowMask|\
PropertyChangeMask
@@ -1685,7 +1687,6 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture)
}
clientAddToList (c);
- clientSetNetActions (c);
clientGrabButtons(c);
/* Initialize per client menu button pixmap */
@@ -1763,6 +1764,8 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture)
{
clientRaise (c, None);
clientInitFocusFlag (c);
+ clientSetNetState (c);
+ clientSetNetActions (c);
}
}
else
@@ -1770,6 +1773,7 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture)
clientRaise (c, None);
setWMState (display_info, c->window, IconicState);
clientSetNetState (c);
+ clientSetNetActions (c);
}
if (!grabbed)
@@ -2113,6 +2117,7 @@ clientShowSingle (Client * c, gboolean deiconify)
setWMState (display_info, c->window, NormalState);
}
clientSetNetState (c);
+ clientSetNetActions (c);
}
void
@@ -2171,6 +2176,7 @@ clientHideSingle (Client * c, gboolean iconify)
setWMState (display_info, c->window, IconicState);
}
clientSetNetState (c);
+ clientSetNetActions (c);
}
void
@@ -2720,6 +2726,7 @@ clientRemoveMaximizeFlag (Client * c)
FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
frameQueueDraw (c, FALSE);
clientSetNetState (c);
+ clientSetNetActions (c);
}
static void
@@ -2890,6 +2897,9 @@ clientToggleMaximized (Client * c, int mode, gboolean restore_position)
frameRight (c),
frameBottom (c));
+ /* Maximized windows w/out border cannot be resized, update allowed actions */
+ clientSetNetActions (c);
+
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED) && (restore_position))
{
/*
diff --git a/src/display.c b/src/display.c
index d7f469807..aaecc76be 100644
--- a/src/display.c
+++ b/src/display.c
@@ -97,6 +97,8 @@ myDisplayInitAtoms (DisplayInfo *display_info)
"_NET_SUPPORTED",
"_NET_SUPPORTING_WM_CHECK",
"_NET_SYSTEM_TRAY_OPCODE",
+ "_NET_WM_ACTION_ABOVE",
+ "_NET_WM_ACTION_BELOW",
"_NET_WM_ACTION_CHANGE_DESKTOP",
"_NET_WM_ACTION_CLOSE",
"_NET_WM_ACTION_FULLSCREEN",
diff --git a/src/display.h b/src/display.h
index 7f6cd14f5..28702287b 100644
--- a/src/display.h
+++ b/src/display.h
@@ -113,6 +113,8 @@ enum
SIDE_TOP,
SIDE_COUNT
};
+#define NO_HANDLE -1
+#define HANDLES_COUNT (CORNER_COUNT + SIDE_COUNT - 1)
enum
{
@@ -189,6 +191,8 @@ enum
NET_SUPPORTED,
NET_SUPPORTING_WM_CHECK,
NET_SYSTEM_TRAY_OPCODE,
+ NET_WM_ACTION_ABOVE,
+ NET_WM_ACTION_BELOW,
NET_WM_ACTION_CHANGE_DESKTOP,
NET_WM_ACTION_CLOSE,
NET_WM_ACTION_FULLSCREEN,
diff --git a/src/events.c b/src/events.c
index da10f6f94..eca05478b 100644
--- a/src/events.c
+++ b/src/events.c
@@ -2599,6 +2599,12 @@ menu_callback (Menu * menu, MenuOp op, Window xid, gpointer menu_data, gpointer
}
frameQueueDraw (c, FALSE);
break;
+ case MENU_OP_MOVE:
+ clientMove (c, NULL);
+ break;
+ case MENU_OP_RESIZE:
+ clientResize (c, CORNER_BOTTOM_RIGHT, NULL);
+ break;
case MENU_OP_MINIMIZE_ALL:
clientHideAll (c, c->win_workspace);
frameQueueDraw (c, FALSE);
@@ -2667,13 +2673,16 @@ show_window_menu (Client *c, gint px, gint py, guint button, guint32 time)
return;
}
+ screen_info = c->screen_info;
+ display_info = screen_info->display_info;
+
x = px;
y = py;
c->button_status[MENU_BUTTON] = BUTTON_STATE_PRESSED;
frameQueueDraw (c, FALSE);
y = (gdouble) c->y;
- ops = MENU_OP_DELETE | MENU_OP_MINIMIZE_ALL | MENU_OP_WORKSPACES;
+ ops = MENU_OP_DELETE | MENU_OP_MINIMIZE_ALL | MENU_OP_WORKSPACES | MENU_OP_MOVE | MENU_OP_RESIZE;
insensitive = 0;
if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_CLOSE))
@@ -2698,6 +2707,18 @@ show_window_menu (Client *c, gint px, gint py, guint button, guint32 time)
}
}
+ if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
+ {
+ insensitive |= MENU_OP_MOVE;
+ }
+
+ if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE) ||
+ ((FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
+ && (screen_info->params->borderless_maximize))))
+ {
+ insensitive |= MENU_OP_RESIZE;
+ }
+
if (FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
{
ops |= MENU_OP_UNMINIMIZE;
@@ -2774,10 +2795,6 @@ show_window_menu (Client *c, gint px, gint py, guint button, guint32 time)
insensitive |= MENU_OP_WORKSPACES;
}
- /* c is not null here */
- screen_info = c->screen_info;
- display_info = screen_info->display_info;
-
if (screen_info->button_handler_id)
{
g_signal_handler_disconnect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)), screen_info->button_handler_id);
diff --git a/src/menu.c b/src/menu.c
index 87f0bf399..4663dc249 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -44,6 +44,9 @@ static MenuItem menuitems[] = {
{MENU_OP_MINIMIZE, "gtk-undo", N_("_Hide")},
{MENU_OP_MINIMIZE_ALL, "gtk-clear", N_("Hide _all others")},
{MENU_OP_UNMINIMIZE, "gtk-add", N_("S_how")},
+ {MENU_OP_MOVE, NULL, N_("Move")},
+ {MENU_OP_RESIZE, NULL, N_("Resize")},
+ {0, NULL, NULL},
{MENU_OP_SHADE, "gtk-goto-top", N_("_Shade")},
{MENU_OP_UNSHADE, "gtk-goto-bottom", N_("Un_shade")},
{MENU_OP_STICK, "gtk-add", N_("S_tick")},
diff --git a/src/menu.h b/src/menu.h
index ac1039e26..05a5545d2 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -42,19 +42,21 @@ typedef enum
MENU_OP_MINIMIZE = 1 << 2,
MENU_OP_MINIMIZE_ALL = 1 << 3,
MENU_OP_UNMINIMIZE = 1 << 4,
- MENU_OP_SHADE = 1 << 5,
- MENU_OP_UNSHADE = 1 << 6,
- MENU_OP_STICK = 1 << 7,
- MENU_OP_UNSTICK = 1 << 8,
- MENU_OP_DELETE = 1 << 9,
- MENU_OP_DESTROY = 1 << 10,
- MENU_OP_WORKSPACES = 1 << 11,
- MENU_OP_QUIT = 1 << 12,
- MENU_OP_RESTART = 1 << 13,
- MENU_OP_ABOVE = 1 << 14,
- MENU_OP_NORMAL = 1 << 15,
- MENU_OP_CONTEXT_HELP = 1 << 16,
- MENU_OP_OTHER = 1 << 17
+ MENU_OP_MOVE = 1 << 5,
+ MENU_OP_RESIZE = 1 << 6,
+ MENU_OP_SHADE = 1 << 7,
+ MENU_OP_UNSHADE = 1 << 8,
+ MENU_OP_STICK = 1 << 9,
+ MENU_OP_UNSTICK = 1 << 10,
+ MENU_OP_DELETE = 1 << 11,
+ MENU_OP_DESTROY = 1 << 12,
+ MENU_OP_WORKSPACES = 1 << 13,
+ MENU_OP_QUIT = 1 << 14,
+ MENU_OP_RESTART = 1 << 15,
+ MENU_OP_ABOVE = 1 << 16,
+ MENU_OP_NORMAL = 1 << 17,
+ MENU_OP_CONTEXT_HELP = 1 << 18,
+ MENU_OP_OTHER = 1 << 19
}
MenuOp;
diff --git a/src/moveresize.c b/src/moveresize.c
index 8d7ea54d7..b3d18a569 100644
--- a/src/moveresize.c
+++ b/src/moveresize.c
@@ -46,6 +46,12 @@
#include "event_filter.h"
#include "xsync.h"
+#define MOVERESIZE_EVENT_MASK \
+ PointerMotionMask | \
+ ButtonMotionMask | \
+ ButtonReleaseMask | \
+ LeaveWindowMask
+
typedef struct _MoveResizeData MoveResizeData;
struct _MoveResizeData
{
@@ -56,12 +62,14 @@ struct _MoveResizeData
gboolean move_resized;
gboolean released;
int button;
- int cancel_x, cancel_y; /* for cancellation (either position or size) */
+ int cancel_x, cancel_y;
+ int cancel_w, cancel_h;
int cancel_workspace;
int mx, my;
int ox, oy;
+ int ow, oh;
int oldw, oldh;
- int corner;
+ int handle;
Poswin *poswin;
};
@@ -174,6 +182,79 @@ clientSetHeight (Client * c, int h)
c->height = temp;
}
+static void
+clientMovePointer (DisplayInfo *display_info, gint dx, gint dy, guint repeat)
+{
+ gint i;
+ for (i = 0; i < repeat; ++i)
+ {
+ XWarpPointer (display_info->dpy, None, None, 0, 0, 0, 0, dx, dy);
+ }
+}
+
+static void
+clientSetHandle(MoveResizeData *passdata, int handle)
+{
+ ScreenInfo *screen_info;
+ DisplayInfo *display_info;
+ Client *c;
+ int px, py;
+
+ c = passdata->c;
+ screen_info = c->screen_info;
+ display_info = screen_info->display_info;
+
+ switch (handle)
+ {
+ case CORNER_BOTTOM_LEFT:
+ px = frameX(c) + frameLeft(c) / 2;
+ py = frameY(c) + frameHeight(c) - frameBottom(c) / 2;
+ break;
+ case CORNER_BOTTOM_RIGHT:
+ px = frameX(c) + frameWidth(c) - frameRight(c) / 2;
+ py = frameY(c) + frameHeight(c) - frameBottom(c) / 2;
+ break;
+ case CORNER_TOP_LEFT:
+ px = frameX(c) + frameLeft(c) / 2;
+ py = frameY(c);
+ break;
+ case CORNER_TOP_RIGHT:
+ px = frameX(c) + frameWidth(c) - frameRight(c) / 2;
+ py = frameY(c);
+ break;
+ case CORNER_COUNT + SIDE_LEFT:
+ px = frameX(c) + frameLeft(c) / 2;
+ py = frameY(c) + frameHeight(c) / 2;
+ break;
+ case CORNER_COUNT + SIDE_RIGHT:
+ px = frameX(c) + frameWidth(c) - frameRight(c) / 2;
+ py = frameY(c) + frameHeight(c) / 2;
+ break;
+ case CORNER_COUNT + SIDE_TOP:
+ px = frameX(c) + frameWidth(c) / 2;
+ py = frameY(c);
+ break;
+ case CORNER_COUNT + SIDE_BOTTOM:
+ px = frameX(c) + frameWidth(c) / 2;
+ py = frameY(c) + frameHeight(c) - frameBottom(c) / 2;
+ break;
+ default:
+ px = frameX(c) + frameWidth(c) / 2;
+ py = frameY(c) + frameHeight(c) / 2;
+ break;
+ }
+
+ XWarpPointer (display_info->dpy, None, screen_info->xroot, 0, 0, 0, 0, px, py);
+ /* Update internal data */
+ passdata->handle = handle;
+ passdata->mx = px;
+ passdata->my = py;
+ passdata->ox = c->x;
+ passdata->oy = c->y;
+ passdata->ow = c->width;
+ passdata->oh = c->height;
+}
+
/* clientConstrainRatio - adjust the given width and height to account for
the constraints imposed by size hints
@@ -182,7 +263,7 @@ clientSetHeight (Client * c, int h)
#define MAKE_MULT(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
void
-clientConstrainRatio (Client * c, int *w, int *h, int corner)
+clientConstrainRatio (Client * c, int *w, int *h, int handle)
{
g_return_if_fail (c != NULL);
@@ -201,7 +282,7 @@ clientConstrainRatio (Client * c, int *w, int *h, int corner)
maxy = c->size->max_aspect.y;
if ((minx * *h > miny * *w) && (miny) &&
- ((corner == CORNER_COUNT + SIDE_TOP) || (corner == CORNER_COUNT + SIDE_BOTTOM)))
+ ((handle == CORNER_COUNT + SIDE_TOP) || (handle == CORNER_COUNT + SIDE_BOTTOM)))
{
/* Change width to match */
delta = MAKE_MULT (minx * *h / miny - *w, xinc);
@@ -229,7 +310,7 @@ clientConstrainRatio (Client * c, int *w, int *h, int corner)
}
if ((maxx * *h < maxy * *w) && (maxx) &&
- ((corner == CORNER_COUNT + SIDE_LEFT) || (corner == CORNER_COUNT + SIDE_RIGHT)))
+ ((handle == CORNER_COUNT + SIDE_LEFT) || (handle == CORNER_COUNT + SIDE_RIGHT)))
{
delta = MAKE_MULT (*w * maxy / maxx - *h, yinc);
if (!(c->size->flags & PMaxSize) ||
@@ -480,117 +561,36 @@ clientMoveEventFilter (XEvent * xevent, gpointer data)
if (xevent->type == KeyPress)
{
+ int key_move;
+
while (XCheckMaskEvent (display_info->dpy, KeyPressMask, xevent))
{
/* Update the display time */
myDisplayUpdateCurrentTime (display_info, xevent);
}
- if ((passdata->use_keys) && !FLAG_TEST_ALL(c->flags, CLIENT_FLAG_MAXIMIZED))
+ key_move = 16;
+ if ((screen_info->params->snap_to_border) || (screen_info->params->snap_to_windows))
{
- int key_move = 16;
- unsigned int edge;
- int direction = 0;
-
- if ((screen_info->params->snap_to_border) || (screen_info->params->snap_to_windows))
- {
- key_move = MAX (16, screen_info->params->snap_width + 1);
- }
-
- if (!passdata->grab && screen_info->params->box_move)
- {
- myDisplayGrabServer (display_info);
- passdata->grab = TRUE;
- clientDrawOutline (c);
- }
- if (screen_info->params->box_move)
- {
- clientDrawOutline (c);
- }
- if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_LEFT].keycode)
- {
- direction = KEY_MOVE_LEFT;
- c->x = c->x - key_move;
- }
- else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_RIGHT].keycode)
- {
- direction = KEY_MOVE_RIGHT;
- c->x = c->x + key_move;
- }
- else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_UP].keycode)
- {
- direction = KEY_MOVE_UP;
- c->y = c->y - key_move;
- }
- else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_DOWN].keycode)
- {
- direction = KEY_MOVE_DOWN;
- c->y = c->y + key_move;
- }
-
- clientSnapPosition (c, prev_x, prev_y);
- edge = clientConstrainPos (c, FALSE);
- if ((edge) && (screen_info->params->wrap_windows))
- {
- int maxx, maxy, maxw, maxh;
-
- maxx = 0;
- maxy = 0;
- maxw = screen_info->width;
- maxh = screen_info->height;
- clientMaxSpace (screen_info, &maxx, &maxy, &maxw, &maxh);
-
- if ((edge & CLIENT_CONSTRAINED_TOP) && (direction == KEY_MOVE_UP))
- {
- if (workspaceMove (screen_info, -1, 0, c, xevent->xkey.time))
- {
- c->y = maxy + maxh;
- }
- }
- else if ((edge & CLIENT_CONSTRAINED_BOTTOM) && (direction == KEY_MOVE_DOWN))
- {
- if (workspaceMove (screen_info, 1, 0, c, xevent->xkey.time))
- {
- c->y = maxy + frameTop (c);
- }
- }
-
- if ((edge & CLIENT_CONSTRAINED_LEFT) && (direction == KEY_MOVE_LEFT))
- {
- if (workspaceMove (screen_info, 0, -1, c, xevent->xkey.time))
- {
- c->x = maxx + maxw - frameWidth (c) + frameRight (c);
- }
- }
- else if ((edge & CLIENT_CONSTRAINED_RIGHT) && (direction == KEY_MOVE_RIGHT))
- {
- if (workspaceMove (screen_info, 0, 1, c, xevent->xkey.time))
- {
- c->x = maxx + frameLeft (c);
- }
- }
- }
-#ifdef SHOW_POSITION
- if (passdata->poswin)
- {
- poswinSetPosition (passdata->poswin, c);
- }
-#endif /* SHOW_POSITION */
- if (screen_info->params->box_move)
- {
- clientDrawOutline (c);
- }
- else
- {
- wc.x = c->x;
- wc.y = c->y;
- clientConfigure (c, &wc, CWX | CWY, configure_flags);
- }
+ key_move = MAX (key_move, screen_info->params->snap_width + 1);
}
- }
- else if (xevent->type == KeyRelease)
- {
- if (xevent->xkey.keycode == screen_info->params->keys[KEY_CANCEL].keycode)
+ if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_LEFT].keycode)
+ {
+ clientMovePointer (display_info, -1, 0, key_move);
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_RIGHT].keycode)
+ {
+ clientMovePointer (display_info, 1, 0, key_move);
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_UP].keycode)
+ {
+ clientMovePointer (display_info, 0, -1, key_move);
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_DOWN].keycode)
+ {
+ clientMovePointer (display_info, 0, 1, key_move);
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_CANCEL].keycode)
{
moving = FALSE;
passdata->released = passdata->use_keys;
@@ -625,25 +625,19 @@ clientMoveEventFilter (XEvent * xevent, gpointer data)
passdata->move_resized = TRUE;
}
}
- else if (passdata->use_keys)
+ else
{
- if (IsModifierKey (XLookupKeysym (&xevent->xkey, 0)))
- {
- moving = FALSE;
- }
+ moving = FALSE;
}
}
else if (xevent->type == ButtonRelease)
{
- if (!passdata->use_keys)
- {
- moving = FALSE;
- passdata->released = (xevent->xbutton.button == passdata->button);
- }
+ moving = FALSE;
+ passdata->released = passdata->use_keys || (xevent->xbutton.button == passdata->button);
}
else if (xevent->type == MotionNotify)
{
- while (XCheckMaskEvent (display_info->dpy, ButtonMotionMask, xevent))
+ while (XCheckMaskEvent (display_info->dpy, PointerMotionMask | ButtonMotionMask, xevent))
{
/* Update the display time */
myDisplayUpdateCurrentTime (display_info, xevent);
@@ -907,31 +901,27 @@ clientMove (Client * c, XEvent * ev)
passdata.use_keys = FALSE;
passdata.grab = FALSE;
passdata.released = FALSE;
- passdata.button = ev->xbutton.button;
+ passdata.button = 0;
passdata.is_transient = clientIsValidTransientOrModal (c);
passdata.move_resized = FALSE;
- if (ev->type == KeyPress)
- {
- passdata.released = passdata.use_keys = TRUE;
- passdata.mx = ev->xkey.x_root;
- passdata.my = ev->xkey.y_root;
- }
- else if (ev->type == ButtonPress)
+ if (ev && (ev->type == ButtonPress))
{
+ passdata.button = ev->xbutton.button;
passdata.mx = ev->xbutton.x_root;
passdata.my = ev->xbutton.y_root;
}
else
{
- getMouseXY (screen_info, screen_info->xroot, &passdata.mx, &passdata.my);
+ clientSetHandle(&passdata, NO_HANDLE);
+ passdata.released = passdata.use_keys = TRUE;
}
g1 = myScreenGrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
- g2 = myScreenGrabPointer (screen_info, ButtonMotionMask | ButtonReleaseMask | LeaveWindowMask,
+ g2 = myScreenGrabPointer (screen_info, MOVERESIZE_EVENT_MASK,
myDisplayGetCursorMove (display_info),
myDisplayGetCurrentTime (display_info));
- if ((passdata.use_keys && !g1) || (!g2))
+ if (!g1 || !g2)
{
TRACE ("grab failed in clientMove");
@@ -949,7 +939,7 @@ clientMove (Client * c, XEvent * ev)
poswinShow (passdata.poswin);
#endif /* SHOW_POSITION */
- /* Set window translucent while moving, looks nice */
+ /* Set window translucent while moving */
if ((screen_info->params->move_opacity < 100) &&
!(screen_info->params->box_move) &&
!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED))
@@ -966,10 +956,6 @@ clientMove (Client * c, XEvent * ev)
FLAG_SET (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING);
TRACE ("entering move loop");
eventFilterPush (display_info->xfilter, clientMoveEventFilter, &passdata);
- if (passdata.use_keys)
- {
- XPutBackEvent (display_info->dpy, ev);
- }
gtk_main ();
eventFilterPop (display_info->xfilter);
TRACE ("leaving move loop");
@@ -1019,6 +1005,34 @@ clientMove (Client * c, XEvent * ev)
}
}
+static gboolean
+clientChangeHandle(MoveResizeData *passdata, int handle)
+{
+ ScreenInfo *screen_info;
+ DisplayInfo *display_info;
+ Client *c;
+ Cursor cursor;
+ gboolean grab;
+
+ c = passdata->c;
+ screen_info = c->screen_info;
+ display_info = screen_info->display_info;
+
+ clientSetHandle(passdata, handle);
+ if ((handle > NO_HANDLE) && (handle <= HANDLES_COUNT))
+ {
+ cursor = myDisplayGetCursorResize (display_info, handle);
+ }
+ else
+ {
+ cursor = myDisplayGetCursorMove (display_info);
+ }
+ grab = myScreenChangeGrabPointer (screen_info, MOVERESIZE_EVENT_MASK,
+ cursor, myDisplayGetCurrentTime (display_info));
+
+ return (grab);
+}
+
static void
clientResizeConfigure (Client *c, int px, int py, int pw, int ph)
{
@@ -1112,21 +1126,21 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
cx = frame_x + (frame_width / 2);
cy = frame_y + (frame_height / 2);
- move_top = ((passdata->corner == CORNER_TOP_RIGHT)
- || (passdata->corner == CORNER_TOP_LEFT)
- || (passdata->corner == CORNER_COUNT + SIDE_TOP)) ?
+ move_top = ((passdata->handle == CORNER_TOP_RIGHT)
+ || (passdata->handle == CORNER_TOP_LEFT)
+ || (passdata->handle == CORNER_COUNT + SIDE_TOP)) ?
1 : 0;
- move_bottom = ((passdata->corner == CORNER_BOTTOM_RIGHT)
- || (passdata->corner == CORNER_BOTTOM_LEFT)
- || (passdata->corner == CORNER_COUNT + SIDE_BOTTOM)) ?
+ move_bottom = ((passdata->handle == CORNER_BOTTOM_RIGHT)
+ || (passdata->handle == CORNER_BOTTOM_LEFT)
+ || (passdata->handle == CORNER_COUNT + SIDE_BOTTOM)) ?
1 : 0;
- move_right = ((passdata->corner == CORNER_TOP_RIGHT)
- || (passdata->corner == CORNER_BOTTOM_RIGHT)
- || (passdata->corner == CORNER_COUNT + SIDE_RIGHT)) ?
+ move_right = ((passdata->handle == CORNER_TOP_RIGHT)
+ || (passdata->handle == CORNER_BOTTOM_RIGHT)
+ || (passdata->handle == CORNER_COUNT + SIDE_RIGHT)) ?
1 : 0;
- move_left = ((passdata->corner == CORNER_TOP_LEFT)
- || (passdata->corner == CORNER_BOTTOM_LEFT)
- || (passdata->corner == CORNER_COUNT + SIDE_LEFT)) ?
+ move_left = ((passdata->handle == CORNER_TOP_LEFT)
+ || (passdata->handle == CORNER_BOTTOM_LEFT)
+ || (passdata->handle == CORNER_COUNT + SIDE_LEFT)) ?
1 : 0;
monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
@@ -1148,92 +1162,75 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
if (xevent->type == KeyPress)
{
+ int key_width_inc, key_height_inc;
+
while (XCheckMaskEvent (display_info->dpy, KeyPressMask, xevent))
{
/* Update the display time */
myDisplayUpdateCurrentTime (display_info, xevent);
}
- if (passdata->use_keys)
- {
- int key_width_inc, key_height_inc;
- int corner = -1;
-
- key_width_inc = c->size->width_inc;
- key_height_inc = c->size->height_inc;
+ key_width_inc = c->size->width_inc;
+ key_height_inc = c->size->height_inc;
- if (key_width_inc < 10)
- {
- key_width_inc = ((int) (10 / key_width_inc)) * key_width_inc;
- }
- if (key_height_inc < 10)
- {
- key_height_inc = ((int) (10 / key_height_inc)) * key_height_inc;
- }
- if (!passdata->grab && screen_info->params->box_resize)
- {
- myDisplayGrabServer (display_info);
- passdata->grab = TRUE;
- clientDrawOutline (c);
- }
- if (screen_info->params->box_resize)
- {
- clientDrawOutline (c);
- }
+ if (key_width_inc < 10)
+ {
+ key_width_inc = ((int) (10 / key_width_inc)) * key_width_inc;
+ }
+ if (key_height_inc < 10)
+ {
+ key_height_inc = ((int) (10 / key_height_inc)) * key_height_inc;
+ }
- if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)
- && (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_UP].keycode))
- {
- c->height = c->height - key_height_inc;
- corner = CORNER_COUNT + SIDE_BOTTOM;
- }
- else if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)
- && (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_DOWN].keycode))
- {
- c->height = c->height + key_height_inc;
- corner = CORNER_COUNT + SIDE_BOTTOM;
- }
- else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_LEFT].keycode)
+ if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_UP].keycode)
+ {
+ if ((passdata->handle == CORNER_COUNT + SIDE_BOTTOM) ||
+ (passdata->handle == CORNER_COUNT + SIDE_TOP))
{
- c->width = c->width - key_width_inc;
- corner = CORNER_COUNT + SIDE_RIGHT;
+ clientMovePointer (display_info, 0, -1, key_height_inc);
}
- else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_RIGHT].keycode)
+ else
{
- c->width = c->width + key_width_inc;
- corner = CORNER_COUNT + SIDE_RIGHT;
+ clientChangeHandle (passdata, CORNER_COUNT + SIDE_TOP);
}
- if (corner >= 0)
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_DOWN].keycode)
+ {
+ if ((passdata->handle == CORNER_COUNT + SIDE_BOTTOM) ||
+ (passdata->handle == CORNER_COUNT + SIDE_TOP))
{
- clientConstrainRatio (c, &c->width, &c->height, corner);
+ clientMovePointer (display_info, 0, 1, key_height_inc);
}
- if ((c->x + c->width < disp_x + min_visible)
- || (c->x + c->width < screen_info->margins [STRUTS_LEFT] + min_visible))
+ else
{
- c->width = prev_width;
+ clientChangeHandle (passdata, CORNER_COUNT + SIDE_BOTTOM);
}
- if ((c->y + c->height < disp_y + min_visible)
- || (c->y + c->height < screen_info->margins [STRUTS_TOP] + min_visible))
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_LEFT].keycode)
+ {
+ if ((passdata->handle == CORNER_COUNT + SIDE_LEFT) ||
+ (passdata->handle == CORNER_COUNT + SIDE_RIGHT))
{
- c->height = prev_height;
+ clientMovePointer (display_info, -1, 0, key_width_inc);
}
- if (passdata->poswin)
+ else
{
- poswinSetPosition (passdata->poswin, c);
+ clientChangeHandle (passdata, CORNER_COUNT + SIDE_LEFT);
}
- if (screen_info->params->box_resize)
+ }
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_MOVE_RIGHT].keycode)
+ {
+ if ((passdata->handle == CORNER_COUNT + SIDE_LEFT) ||
+ (passdata->handle == CORNER_COUNT + SIDE_RIGHT))
{
- clientDrawOutline (c);
+ clientMovePointer (display_info, 1, 0, key_width_inc);
}
else
{
- clientResizeConfigure (c, prev_x, prev_y, prev_width, prev_height);
+ clientChangeHandle (passdata, CORNER_COUNT + SIDE_RIGHT);
}
}
- }
- else if (xevent->type == KeyRelease)
- {
- if (xevent->xkey.keycode == screen_info->params->keys[KEY_CANCEL].keycode)
+ else if (xevent->xkey.keycode == screen_info->params->keys[KEY_CANCEL].keycode)
{
resizing = FALSE;
passdata->released = passdata->use_keys;
@@ -1244,16 +1241,10 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
}
/* restore the pre-resize position & size */
- if (move_left)
- {
- c->x += c->width - passdata->cancel_x;
- }
- if (move_top)
- {
- c->y += c->height - passdata->cancel_y;
- }
- c->width = passdata->cancel_x;
- c->height = passdata->cancel_y;
+ c->x = passdata->cancel_x;
+ c->y = passdata->cancel_y;
+ c->width = passdata->cancel_w;
+ c->height = passdata->cancel_h;
if (screen_info->params->box_resize)
{
clientDrawOutline (c);
@@ -1263,12 +1254,9 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
clientResizeConfigure (c, prev_x, prev_y, prev_width, prev_height);
}
}
- else if (passdata->use_keys)
+ else
{
- if (IsModifierKey (XLookupKeysym (&xevent->xkey, 0)))
- {
- resizing = FALSE;
- }
+ resizing = FALSE;
}
}
else if (xevent->type == MotionNotify)
@@ -1298,24 +1286,24 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
if (move_left)
{
- c->width = passdata->ox - (xevent->xmotion.x_root - passdata->mx);
+ c->width = passdata->ow - (xevent->xmotion.x_root - passdata->mx);
}
else if (move_right)
{
- c->width = passdata->ox + (xevent->xmotion.x_root - passdata->mx);
+ c->width = passdata->ow + (xevent->xmotion.x_root - passdata->mx);
}
if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
{
if (move_top)
{
- c->height = passdata->oy - (xevent->xmotion.y_root - passdata->my);
+ c->height = passdata->oh - (xevent->xmotion.y_root - passdata->my);
}
else if (move_bottom)
{
- c->height = passdata->oy + (xevent->xmotion.y_root - passdata->my);
+ c->height = passdata->oh + (xevent->xmotion.y_root - passdata->my);
}
}
- clientConstrainRatio (c, &c->width, &c->height, passdata->corner);
+ clientConstrainRatio (c, &c->width, &c->height, passdata->handle);
clientSetWidth (c, c->width);
if (move_left)
@@ -1393,11 +1381,8 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
}
else if (xevent->type == ButtonRelease)
{
- if (!passdata->use_keys)
- {
- resizing = FALSE;
- passdata->released = (xevent->xbutton.button == passdata->button);
- }
+ resizing = FALSE;
+ passdata->released = (passdata->use_keys || (xevent->xbutton.button == passdata->button));
}
else if ((xevent->type == UnmapNotify) && (xevent->xunmap.window == c->window))
{
@@ -1424,13 +1409,14 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
}
void
-clientResize (Client * c, int corner, XEvent * ev)
+clientResize (Client * c, int handle, XEvent * ev)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
XWindowChanges wc;
MoveResizeData passdata;
int w_orig, h_orig;
+ Cursor cursor;
gboolean g1, g2;
g_return_if_fail (c != NULL);
@@ -1447,38 +1433,43 @@ clientResize (Client * c, int corner, XEvent * ev)
}
passdata.c = c;
- passdata.cancel_x = passdata.ox = c->width;
- passdata.cancel_y = passdata.oy = c->height;
+ passdata.cancel_x = passdata.ox = c->x;
+ passdata.cancel_y = passdata.oy = c->y;
+ passdata.cancel_w = passdata.ow = c->width;
+ passdata.cancel_h = passdata.oh = c->height;
passdata.use_keys = FALSE;
passdata.grab = FALSE;
passdata.released = FALSE;
- passdata.button = ev->xbutton.button;
- passdata.corner = corner;
+ passdata.button = 0;
+ passdata.handle = handle;
w_orig = c->width;
h_orig = c->height;
- if (ev->type == KeyPress)
+ if (ev && (ev->type == ButtonPress))
+ {
+ passdata.button = ev->xbutton.button;
+ passdata.mx = ev->xbutton.x_root;
+ passdata.my = ev->xbutton.y_root;
+ }
+ else
{
+ clientSetHandle (&passdata, handle);
passdata.released = passdata.use_keys = TRUE;
- passdata.mx = ev->xkey.x_root;
- passdata.my = ev->xkey.y_root;
}
- else if (ev->type == ButtonPress)
+ if ((handle > NO_HANDLE) && (handle <= HANDLES_COUNT))
{
- passdata.mx = ev->xbutton.x_root;
- passdata.my = ev->xbutton.y_root;
+ cursor = myDisplayGetCursorResize (display_info, passdata.handle);
}
else
{
- getMouseXY (screen_info, screen_info->xroot, &passdata.mx, &passdata.my);
+ cursor = myDisplayGetCursorMove (display_info);
}
g1 = myScreenGrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
- g2 = myScreenGrabPointer (screen_info, ButtonMotionMask | ButtonReleaseMask | LeaveWindowMask,
- myDisplayGetCursorResize(display_info, passdata.corner),
- myDisplayGetCurrentTime (display_info));
+ g2 = myScreenGrabPointer (screen_info, MOVERESIZE_EVENT_MASK,
+ cursor, myDisplayGetCurrentTime (display_info));
- if ((passdata.use_keys && !g1) || (!g2))
+ if (!g1 || !g2)
{
TRACE ("grab failed in clientResize");
@@ -1503,7 +1494,7 @@ clientResize (Client * c, int corner, XEvent * ev)
clientXSyncEnable (c);
#endif /* HAVE_XSYNC */
- /* Set window translucent while resizing, doesn't looks too nice :( */
+ /* Set window translucent while resizing */
if ((screen_info->params->resize_opacity < 100) &&
!(screen_info->params->box_resize) &&
!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED))
@@ -1514,10 +1505,6 @@ clientResize (Client * c, int corner, XEvent * ev)
FLAG_SET (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING);
TRACE ("entering resize loop");
eventFilterPush (display_info->xfilter, clientResizeEventFilter, &passdata);
- if (passdata.use_keys)
- {
- XPutBackEvent (display_info->dpy, ev);
- }
gtk_main ();
eventFilterPop (display_info->xfilter);
TRACE ("leaving resize loop");
diff --git a/src/netwm.c b/src/netwm.c
index 25191e389..1bb31d6e1 100644
--- a/src/netwm.c
+++ b/src/netwm.c
@@ -597,8 +597,8 @@ clientNetMoveResize (Client * c, XClientMessageEvent * ev)
}
else
{
- g_warning ("Could not determine the mouse button used");
- return;
+ /* Fallback */
+ button = Button1;
}
}
@@ -1126,7 +1126,7 @@ clientSetNetActions (Client * c)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
- Atom atoms[12];
+ Atom atoms[16];
int i;
g_return_if_fail (c != NULL);
@@ -1137,11 +1137,29 @@ clientSetNetActions (Client * c)
i = 0;
atoms[i++] = display_info->atoms[NET_WM_ACTION_CLOSE];
- atoms[i++] = display_info->atoms[NET_WM_ACTION_FULLSCREEN];
- if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_ABOVE];
+ if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
{
- atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_HORZ];
- atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_VERT];
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_FULLSCREEN];
+ if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
+ {
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_MOVE];
+ }
+ if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE) &&
+ !((FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
+ && (screen_info->params->borderless_maximize))))
+ {
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_RESIZE];
+ }
+ if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
+ {
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_HORZ];
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_VERT];
+ }
+ if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER))
+ {
+ atoms[i++] = display_info->atoms[NET_WM_ACTION_SHADE];
+ }
}
if (CLIENT_CAN_HIDE_WINDOW (c))
{
@@ -1152,10 +1170,6 @@ clientSetNetActions (Client * c)
atoms[i++] = display_info->atoms[NET_WM_ACTION_CHANGE_DESKTOP];
atoms[i++] = display_info->atoms[NET_WM_ACTION_STICK];
}
- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER))
- {
- atoms[i++] = display_info->atoms[NET_WM_ACTION_SHADE];
- }
XChangeProperty (clientGetXDisplay (c), c->window, display_info->atoms[NET_WM_ALLOWED_ACTIONS],
XA_ATOM, 32, PropModeReplace, (unsigned char *) atoms, i);
}
diff --git a/src/screen.c b/src/screen.c
index 88310dce1..eb2d94ead 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -438,6 +438,24 @@ myScreenGrabPointer (ScreenInfo *screen_info, unsigned int event_mask, Cursor cu
return grab;
}
+gboolean
+myScreenChangeGrabPointer (ScreenInfo *screen_info, unsigned int event_mask, Cursor cursor, Time time)
+{
+ gboolean grab;
+
+ g_return_val_if_fail (screen_info, FALSE);
+ TRACE ("entering myScreenGrabPointer");
+
+ grab = FALSE;
+ if (screen_info->pointer_grabs > 0)
+ {
+ grab = (XChangeActivePointerGrab (myScreenGetXDisplay (screen_info),
+ event_mask, cursor, time) == GrabSuccess);
+ }
+
+ return grab;
+}
+
unsigned int
myScreenUngrabKeyboard (ScreenInfo *screen_info, Time time)
{
diff --git a/src/screen.h b/src/screen.h
index 8df75e693..122af074d 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -180,6 +180,10 @@ gboolean myScreenGrabPointer (ScreenInfo *,
unsigned int,
Cursor,
Time);
+gboolean myScreenChangeGrabPointer (ScreenInfo *,
+ unsigned int,
+ Cursor,
+ Time);
unsigned int myScreenUngrabKeyboard (ScreenInfo *,
Time);
unsigned int myScreenUngrabPointer (ScreenInfo *,