all repos — openbox @ 7886b797a36f5a035a75a19424e0b3cf7825baf8

openbox fork - make it a bit more like ryudo

move the move/resize functionality into moveresize.c, for use with the netwm atoms. use it from teh plugins. combine the two actions.
Dana Jansens danakj@orodu.net
commit

7886b797a36f5a035a75a19424e0b3cf7825baf8

parent

55c424d38bb119bd04199ed5e73b035b00474dd9

M openbox/Makefile.amopenbox/Makefile.am

@@ -23,12 +23,12 @@ openbox3_LDFLAGS=-export-dynamic

openbox3_SOURCES=parse.tab.c parse.lex.c action.c client.c config.c \ extensions.c focus.c frame.c grab.c menu.c openbox.c \ framerender.c parse.c plugin.c prop.c screen.c stacking.c \ - dispatch.c event.c group.c timer.c xerror.c + dispatch.c event.c group.c timer.c xerror.c moveresize.c noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \ focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \ menu.h openbox.h parse.h parse.tab.h plugin.h prop.h screen.h \ - stacking.h timer.h xerror.h + stacking.h timer.h xerror.h moveresize.h # kill the implicit .c.y rule %.c: %.y
M openbox/action.copenbox/action.c

@@ -1,7 +1,9 @@

#include "client.h" #include "grab.h" #include "focus.h" +#include "moveresize.h" #include "menu.h" +#include "prop.h" #include "stacking.h" #include "frame.h" #include "framerender.h"

@@ -151,10 +153,18 @@ a = action_new(action_previous_desktop_row);

a->data.nextprevdesktop.wrap = TRUE; } else if (!g_ascii_strcasecmp(name, "toggledecorations")) { a = action_new(action_toggle_decorations); + } else if (!g_ascii_strcasecmp(name, "keyboardmove")) { + a = action_new(action_moveresize); + a->data.moveresize.corner = prop_atoms.net_wm_moveresize_move_keyboard; } else if (!g_ascii_strcasecmp(name, "move")) { - a = action_new(action_move); + a = action_new(action_moveresize); + a->data.moveresize.corner = prop_atoms.net_wm_moveresize_move; } else if (!g_ascii_strcasecmp(name, "resize")) { - a = action_new(action_resize); + a = action_new(action_moveresize); + a->data.moveresize.corner = prop_atoms.net_wm_moveresize_size_topleft; + } else if (!g_ascii_strcasecmp(name, "keyboardresize")) { + a = action_new(action_moveresize); + a->data.moveresize.corner = prop_atoms.net_wm_moveresize_size_keyboard; } else if (!g_ascii_strcasecmp(name, "restart")) { a = action_new(action_restart); } else if (!g_ascii_strcasecmp(name, "exit")) {

@@ -628,92 +638,14 @@ c->disabled_decorations = c->disabled_decorations ? 0 : ~0;

client_setup_decor_and_functions(c); } -static void popup_coords(char *format, Cursor cur, int a, int b, gboolean hide) +void action_moveresize(union ActionData *data) { - XSetWindowAttributes attrib; - static Window coords = None; - - if (coords == None) { - attrib.override_redirect = TRUE; - coords = XCreateWindow(ob_display, ob_root, - 0, 0, 1, 1, 0, render_depth, InputOutput, - render_visual, CWOverrideRedirect, &attrib); - g_assert(coords != None); - - grab_pointer(TRUE, cur); - - XMapWindow(ob_display, coords); - } - - if (hide) { - XDestroyWindow(ob_display, coords); - coords = None; - - grab_pointer(FALSE, None); - } else { - Size s; - char *text; - - text = g_strdup_printf(format, a, b); - framerender_size_popup_label(text, &s); - XMoveResizeWindow(ob_display, coords, - 10, 10, s.width, s.height); - framerender_popup_label(coords, &s, text); - g_free(text); - } -} - -void action_move(union ActionData *data) -{ - Client *c = data->move.c; - int x = data->move.x; - int y = data->move.y; + Client *c = data->moveresize.c; if (!c || !client_normal(c)) return; - dispatch_move(c, &x, &y); - - popup_coords("X: %d Y: %d", ob_cursors.move, x, y, data->move.final); - - frame_frame_gravity(c->frame, &x, &y); /* get where the client should be */ - client_configure(c, Corner_TopLeft, x, y, c->area.width, c->area.height, - TRUE, data->move.final); -} - -void action_resize(union ActionData *data) -{ - Client *c = data->resize.c; - Cursor cur; - int w = data->resize.x; - int h = data->resize.y; - - if (!c || c->shaded || !client_normal(c)) return; - - dispatch_resize(c, &w, &h, data->resize.corner); - - w -= c->frame->size.left + c->frame->size.right; - h -= c->frame->size.top + c->frame->size.bottom; - - client_configure(c, data->resize.corner, c->area.x, c->area.y, w, h, - TRUE, data->resize.final); - - switch (data->resize.corner) { - case Corner_TopLeft: - cur = ob_cursors.br; - break; - case Corner_TopRight: - cur = ob_cursors.bl; - break; - case Corner_BottomLeft: - cur = ob_cursors.tr; - break; - case Corner_BottomRight: - cur = ob_cursors.tl; - break; - } - - popup_coords("W: %d H: %d", cur, c->logical_size.width, - c->logical_size.height, data->move.final); + moveresize_start(c, data->moveresize.x, data->moveresize.y, + data->moveresize.button, data->moveresize.corner); } void action_restart(union ActionData *data)
M openbox/action.hopenbox/action.h

@@ -48,19 +48,12 @@ Client *c;

gboolean wrap; }; -struct Move { +struct MoveResize { Client *c; int x; int y; - gboolean final; -}; - -struct Resize { - Client *c; - int x; - int y; - gboolean final; - Corner corner; + guint32 corner; /* prop_atoms.net_wm_moveresize_* */ + guint button; }; struct ShowMenu {

@@ -87,8 +80,7 @@ struct SendToDesktop sendto;

struct SendToNextPreviousDesktop sendtonextprev; struct Desktop desktop; struct NextPreviousDesktop nextprevdesktop; - struct Move move; - struct Resize resize; + struct MoveResize moveresize; struct ShowMenu showmenu; struct CycleWindows cycle; };

@@ -195,10 +187,8 @@ /* NextPreviousDesktop */

void action_previous_desktop_row(union ActionData *data); /* ClientAction */ void action_toggle_decorations(union ActionData *data); -/* Move */ -void action_move(union ActionData *data); -/* Resize */ -void action_resize(union ActionData *data); +/* MoveResize */ +void action_moveresize(union ActionData *data); /* Execute */ void action_restart(union ActionData *data); /* Any */
M openbox/event.copenbox/event.c

@@ -8,6 +8,7 @@ #include "frame.h"

#include "menu.h" #include "framerender.h" #include "focus.h" +#include "moveresize.h" #include "stacking.h" #include "extensions.h" #include "timer.h"

@@ -358,6 +359,14 @@ XConfigureWindow(ob_display, window,

e->xconfigurerequest.value_mask, &xwc); xerror_set_ignore(FALSE); } + + if (moveresize_in_progress) + if (e->type == MotionNotify || e->type == ButtonRelease || + e->type == ButtonPress || + e->type == KeyPress || e->type == KeyRelease) { + moveresize_event(e); + return; /* no dispatch! */ + } /* user input (action-bound) events */ /*
A openbox/moveresize.c

@@ -0,0 +1,192 @@

+#include "grab.h" +#include "framerender.h" +#include "prop.h" +#include "client.h" +#include "dispatch.h" +#include "openbox.h" + +#include <X11/Xlib.h> +#include <glib.h> + +gboolean moveresize_in_progress = FALSE; +static gboolean moving = FALSE; /* TRUE - moving, FALSE - resizing */ + +static Window coords = None; +static int start_x, start_y, start_cx, start_cy, start_cw, start_ch; +static int cur_x, cur_y; +static Client *client; +static guint button; +static guint32 corner; +static Corner lockcorner; + +#define POPUP_X (10) +#define POPUP_Y (10) + +static void popup_coords(char *format, int a, int b) +{ + XSetWindowAttributes attrib; + Size s; + char *text; + + if (coords == None) { + attrib.override_redirect = TRUE; + coords = XCreateWindow(ob_display, ob_root, + 0, 0, 1, 1, 0, render_depth, InputOutput, + render_visual, CWOverrideRedirect, &attrib); + g_assert(coords != None); + + XMapWindow(ob_display, coords); + } + + text = g_strdup_printf(format, a, b); + framerender_size_popup_label(text, &s); + XMoveResizeWindow(ob_display, coords, + POPUP_X, POPUP_Y, s.width, s.height); + framerender_popup_label(coords, &s, text); + g_free(text); +} + +void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr) +{ + Cursor cur; + + g_assert(!moveresize_in_progress); + + client = c; + start_cx = c->frame->area.x; + start_cy = c->frame->area.y; + start_cw = c->area.width; + start_ch = c->area.height; + start_x = x; + start_y = y; + button = b; + corner = cnr; + + moveresize_in_progress = TRUE; + moving = (corner == prop_atoms.net_wm_moveresize_move || + corner == prop_atoms.net_wm_moveresize_move_keyboard); + + if (corner == prop_atoms.net_wm_moveresize_size_topleft) + cur = ob_cursors.tl; + else if (corner == prop_atoms.net_wm_moveresize_size_top) + cur = ob_cursors.tl; + else if (corner == prop_atoms.net_wm_moveresize_size_topright) + cur = ob_cursors.tr; + else if (corner == prop_atoms.net_wm_moveresize_size_right) + cur = ob_cursors.tr; + else if (corner == prop_atoms.net_wm_moveresize_size_bottomright) + cur = ob_cursors.br; + else if (corner == prop_atoms.net_wm_moveresize_size_bottom) + cur = ob_cursors.br; + else if (corner == prop_atoms.net_wm_moveresize_size_bottomleft) + cur = ob_cursors.bl; + else if (corner == prop_atoms.net_wm_moveresize_size_left) + cur = ob_cursors.bl; + else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) + cur = ob_cursors.br; + else if (corner == prop_atoms.net_wm_moveresize_move) + cur = ob_cursors.move; + else if (corner == prop_atoms.net_wm_moveresize_move_keyboard) + cur = ob_cursors.move; + else + g_assert_not_reached(); + + grab_keyboard(TRUE); + grab_pointer(TRUE, cur); +} + +void moveresize_event(XEvent *e) +{ + g_assert(moveresize_in_progress); + + if (e->type == MotionNotify) { + if (moving) { + cur_x = start_cx + e->xmotion.x_root - start_x; + cur_y = start_cy + e->xmotion.y_root - start_y; + + dispatch_move(client, &cur_x, &cur_y); + + popup_coords("X: %d Y: %d", cur_x, cur_y); + + /* get where the client should be */ + frame_frame_gravity(client->frame, &cur_x, &cur_y); + client_configure(client, Corner_TopLeft, cur_x, cur_y, + start_cw, start_ch, TRUE, FALSE); + } else { + if (corner == prop_atoms.net_wm_moveresize_size_topleft) { + cur_x = start_cw - (e->xmotion.x_root - start_x); + cur_y = start_ch - (e->xmotion.y_root - start_y); + lockcorner = Corner_BottomRight; + } else if (corner == prop_atoms.net_wm_moveresize_size_top) { + cur_x = start_cw; + cur_y = start_ch - (e->xmotion.y_root - start_y); + lockcorner = Corner_BottomRight; + } else if (corner == prop_atoms.net_wm_moveresize_size_topright) { + cur_x = start_cw + (e->xmotion.x_root - start_x); + cur_y = start_ch - (e->xmotion.y_root - start_y); + lockcorner = Corner_BottomLeft; + } else if (corner == prop_atoms.net_wm_moveresize_size_right) { + cur_x = start_cw + (e->xmotion.x_root - start_x); + cur_y = start_ch; + lockcorner = Corner_BottomLeft; + } else if (corner == + prop_atoms.net_wm_moveresize_size_bottomright) { + cur_x = start_cw + (e->xmotion.x_root - start_x); + cur_y = start_ch + (e->xmotion.y_root - start_y); + lockcorner = Corner_TopLeft; + } else if (corner == prop_atoms.net_wm_moveresize_size_bottom) { + cur_x = start_cw; + cur_y = start_ch + (e->xmotion.y_root - start_y); + lockcorner = Corner_TopLeft; + } else if (corner == + prop_atoms.net_wm_moveresize_size_bottomleft) { + cur_x = start_cw - (e->xmotion.x_root - start_x); + cur_y = start_ch + (e->xmotion.y_root - start_y); + lockcorner = Corner_TopRight; + } else if (corner == prop_atoms.net_wm_moveresize_size_left) { + cur_x = start_cw - (e->xmotion.x_root - start_x); + cur_y = start_ch; + lockcorner = Corner_TopRight; + } else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) { + cur_x = start_cw + (e->xmotion.x_root - start_x); + cur_y = start_ch + (e->xmotion.y_root - start_y); + lockcorner = Corner_TopLeft; + } else + g_assert_not_reached(); + + /* dispatch_resize needs the frame size */ + cur_x += client->frame->size.left + client->frame->size.right; + cur_y += client->frame->size.top + client->frame->size.bottom; + + dispatch_resize(client, &cur_x, &cur_y, lockcorner); + + cur_x -= client->frame->size.left + client->frame->size.right; + cur_y -= client->frame->size.top + client->frame->size.bottom; + + client_configure(client, lockcorner, client->area.x, + client->area.y, cur_x, cur_y, TRUE, FALSE); + + popup_coords("W: %d H: %d", client->logical_size.width, + client->logical_size.height); + } + } else if (e->type == ButtonRelease) { + if (e->xbutton.button == button) { + grab_keyboard(FALSE); + grab_pointer(FALSE, None); + + XDestroyWindow(ob_display, coords); + coords = None; + + moveresize_in_progress = FALSE; + + if (moving) { + client_configure(client, Corner_TopLeft, cur_x, cur_y, + start_cw, start_ch, TRUE, TRUE); + } else { + client_configure(client, lockcorner, client->area.x, + client->area.y, cur_x, cur_y, TRUE, TRUE); + } + } + } else if (e->type == KeyPress) { + } +}
A openbox/moveresize.h

@@ -0,0 +1,14 @@

+#ifndef __moveresize_h +#define __moveresize_h + +#include "client.h" + +#include <glib.h> + +extern gboolean moveresize_in_progress; + +void moveresize_start(Client *c, int x, int y, guint b, guint32 corner); + +void moveresize_event(XEvent *e); + +#endif
M openbox/prop.copenbox/prop.c

@@ -69,15 +69,18 @@ CREATE(net_wm_window_type_splash, "_NET_WM_WINDOW_TYPE_SPLASH");

CREATE(net_wm_window_type_dialog, "_NET_WM_WINDOW_TYPE_DIALOG"); CREATE(net_wm_window_type_normal, "_NET_WM_WINDOW_TYPE_NORMAL"); - CREATE(net_wm_moveresize_size_topleft, "_NET_WM_MOVERESIZE_SIZE_TOPLEFT"); - CREATE(net_wm_moveresize_size_topright, - "_NET_WM_MOVERESIZE_SIZE_TOPRIGHT"); - CREATE(net_wm_moveresize_size_bottomleft, - "_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT"); - CREATE(net_wm_moveresize_size_bottomright, - "_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT"); - CREATE(net_wm_moveresize_move, "_NET_WM_MOVERESIZE_MOVE"); - + prop_atoms.net_wm_moveresize_size_topleft = 0; + prop_atoms.net_wm_moveresize_size_top = 1; + prop_atoms.net_wm_moveresize_size_topright = 2; + prop_atoms.net_wm_moveresize_size_right = 3; + prop_atoms.net_wm_moveresize_size_bottomright = 4; + prop_atoms.net_wm_moveresize_size_bottom = 5; + prop_atoms.net_wm_moveresize_size_bottomleft = 6; + prop_atoms.net_wm_moveresize_size_left = 7; + prop_atoms.net_wm_moveresize_move = 8; + prop_atoms.net_wm_moveresize_size_keyboard = 9; + prop_atoms.net_wm_moveresize_move_keyboard = 10; + CREATE(net_wm_action_move, "_NET_WM_ACTION_MOVE"); CREATE(net_wm_action_resize, "_NET_WM_ACTION_RESIZE"); CREATE(net_wm_action_minimize, "_NET_WM_ACTION_MINIMIZE");
M openbox/prop.hopenbox/prop.h

@@ -73,11 +73,17 @@ Atom net_wm_window_type_splash;

Atom net_wm_window_type_dialog; Atom net_wm_window_type_normal; - Atom net_wm_moveresize_size_topleft; + Atom net_wm_moveresize_size_topleft; + Atom net_wm_moveresize_size_top; Atom net_wm_moveresize_size_topright; - Atom net_wm_moveresize_size_bottomleft; + Atom net_wm_moveresize_size_right; Atom net_wm_moveresize_size_bottomright; + Atom net_wm_moveresize_size_bottom; + Atom net_wm_moveresize_size_bottomleft; + Atom net_wm_moveresize_size_left; Atom net_wm_moveresize_move; + Atom net_wm_moveresize_size_keyboard; + Atom net_wm_moveresize_move_keyboard; Atom net_wm_action_move; Atom net_wm_action_resize;
M plugins/keyboard/keyboard.cplugins/keyboard/keyboard.c

@@ -143,9 +143,6 @@ } else {

if (p->action->func != NULL) { p->action->data.any.c = focus_client; - g_assert(!(p->action->func == action_move || - p->action->func == action_resize)); - if (p->action->func == action_cycle_windows) { p->action->data.cycle.final = FALSE; p->action->data.cycle.cancel = FALSE;
M plugins/keyboard/keyparse.cplugins/keyboard/keyparse.c

@@ -1,4 +1,5 @@

#include "kernel/parse.h" +#include "kernel/prop.h" #include "keyboard.h" void keyparse(ParseToken *token)

@@ -44,9 +45,11 @@ if (token->type == TOKEN_IDENTIFIER) {

action = action_from_string(token->data.identifier); /* no move/resize with the keyboard */ - if (action && - (action->func == action_move || - action->func == action_resize)) { + if (action && action->func == action_moveresize && + action->data.moveresize.corner != + prop_atoms.net_wm_moveresize_move_keyboard && + action->data.moveresize.corner != + prop_atoms.net_wm_moveresize_size_keyboard) { action_free(action); action = NULL; }
M plugins/mouse/mouse.cplugins/mouse/mouse.c

@@ -3,6 +3,7 @@ #include "kernel/dispatch.h"

#include "kernel/action.h" #include "kernel/event.h" #include "kernel/client.h" +#include "kernel/prop.h" #include "kernel/grab.h" #include "kernel/parse.h" #include "kernel/frame.h"

@@ -121,8 +122,7 @@

if (b->action[a] != NULL && b->action[a]->func != NULL) { b->action[a]->data.any.c = c; - g_assert(!(b->action[a]->func == action_move || - b->action[a]->func == action_resize)); + g_assert(b->action[a]->func != action_moveresize); if (b->action[a]->func == action_showmenu) { b->action[a]->data.showmenu.x = x;

@@ -133,14 +133,9 @@ b->action[a]->func(&b->action[a]->data);

} } -/* corner should be the opposite corner of the window in which the pointer - clicked, Corner_TopLeft if a good default if there is no client - Returns True or False for if a binding existed for the action or not. -*/ -static gboolean fire_motion(MouseAction a, Context context, Client *c, - guint state, guint button, int cx, int cy, - int cw, int ch, int dx, int dy, - gboolean final, Corner corner) +static void fire_motion(MouseAction a, Context context, Client *c, + guint state, guint button, int x_root, int y_root, + guint32 corner) { GSList *it; MouseBinding *b;

@@ -151,68 +146,49 @@ if (b->state == state && b->button == button)

break; } /* if not bound, then nothing to do! */ - if (it == NULL) return FALSE; + if (it == NULL) return; if (b->action[a] != NULL && b->action[a]->func != NULL) { b->action[a]->data.any.c = c; - if (b->action[a]->func == action_move) { - b->action[a]->data.move.x = cx + dx; - b->action[a]->data.move.y = cy + dy; - b->action[a]->data.move.final = final; - } else if (b->action[a]->func == action_resize) { - b->action[a]->data.resize.corner = corner; - switch (corner) { - case Corner_TopLeft: - b->action[a]->data.resize.x = cw + dx; - b->action[a]->data.resize.y = ch + dy; - break; - case Corner_TopRight: - b->action[a]->data.resize.x = cw - dx; - b->action[a]->data.resize.y = ch + dy; - break; - case Corner_BottomLeft: - b->action[a]->data.resize.x = cw + dx; - b->action[a]->data.resize.y = ch - dy; - break; - case Corner_BottomRight: - b->action[a]->data.resize.x = cw - dx; - b->action[a]->data.resize.y = ch - dy; - break; - } - b->action[a]->data.resize.final = final; + if (b->action[a]->func == action_moveresize) { + b->action[a]->data.moveresize.x = x_root; + b->action[a]->data.moveresize.y = y_root; + b->action[a]->data.moveresize.button = button; + if (!(b->action[a]->data.moveresize.corner == + prop_atoms.net_wm_moveresize_move || + b->action[a]->data.moveresize.corner == + prop_atoms.net_wm_moveresize_move_keyboard || + b->action[a]->data.moveresize.corner == + prop_atoms.net_wm_moveresize_size_keyboard)) + b->action[a]->data.moveresize.corner = corner; } else g_assert_not_reached(); + b->action[a]->func(&b->action[a]->data); - return TRUE; } - return FALSE; } -static Corner pick_corner(int x, int y, int cx, int cy, int cw, int ch) +static guint32 pick_corner(int x, int y, int cx, int cy, int cw, int ch) { if (x - cx < cw / 2) { if (y - cy < ch / 2) - return Corner_BottomRight; + return prop_atoms.net_wm_moveresize_size_topleft; else - return Corner_TopRight; + return prop_atoms.net_wm_moveresize_size_bottomleft; } else { if (y - cy < ch / 2) - return Corner_BottomLeft; + return prop_atoms.net_wm_moveresize_size_topright; else - return Corner_TopLeft; + return prop_atoms.net_wm_moveresize_size_bottomright; } } static void event(ObEvent *e, void *foo) { static Time ltime; - static int px, py, cx, cy, cw, ch, dx, dy; static guint button = 0, state = 0, lbutton = 0; - static gboolean drag = FALSE, drag_used = FALSE; - static Corner corner = Corner_TopLeft; - static Client *drag_client = NULL; - static Context drag_context = Context_None; + static int px, py; gboolean click = FALSE; gboolean dclick = FALSE; Context context;

@@ -231,26 +207,10 @@ context = frame_context(e->data.x.client,

e->data.x.e->xbutton.window); if (!button) { - if (e->data.x.client != NULL) { - cx = e->data.x.client->frame->area.x; - cy = e->data.x.client->frame->area.y; - /* use the client size because the frame can be differently - sized (shaded windows) and we want this based on the clients - size */ - cw = e->data.x.client->area.width + - e->data.x.client->frame->size.left + - e->data.x.client->frame->size.right; - ch = e->data.x.client->area.height + - e->data.x.client->frame->size.top + - e->data.x.client->frame->size.bottom; - px = e->data.x.e->xbutton.x_root; - py = e->data.x.e->xbutton.y_root; - corner = pick_corner(px, py, cx, cy, cw, ch); - } + px = e->data.x.e->xbutton.x_root; + py = e->data.x.e->xbutton.y_root; button = e->data.x.e->xbutton.button; state = e->data.x.e->xbutton.state; - drag_context = context; - drag_client = e->data.x.client; } fire_button(MouseAction_Press, context,

@@ -269,38 +229,26 @@ case Event_X_ButtonRelease:

context = frame_context(e->data.x.client, e->data.x.e->xbutton.window); if (e->data.x.e->xbutton.button == button) { - /* end drags */ - if (drag_used) { - fire_motion(MouseAction_Motion, drag_context, - drag_client, state, button, - cx, cy, cw, ch, dx, dy, TRUE, corner); - drag = drag_used = FALSE; - drag_context = Context_None; - drag_client = NULL; - - lbutton = 0; - } else { - /* clicks are only valid if its released over the window */ - int junk; - Window wjunk; - guint ujunk, b, w, h; - XGetGeometry(ob_display, e->data.x.e->xbutton.window, - &wjunk, &junk, &junk, &w, &h, &b, &ujunk); - if (e->data.x.e->xbutton.x >= (signed)-b && - e->data.x.e->xbutton.y >= (signed)-b && - e->data.x.e->xbutton.x < (signed)(w+b) && - e->data.x.e->xbutton.y < (signed)(h+b)) { - click = TRUE; - /* double clicks happen if there were 2 in a row! */ - if (lbutton == button && - e->data.x.e->xbutton.time - dclicktime <= ltime) { - dclick = TRUE; - lbutton = 0; - } else - lbutton = button; - } else + /* clicks are only valid if its released over the window */ + int junk; + Window wjunk; + guint ujunk, b, w, h; + XGetGeometry(ob_display, e->data.x.e->xbutton.window, + &wjunk, &junk, &junk, &w, &h, &b, &ujunk); + if (e->data.x.e->xbutton.x >= (signed)-b && + e->data.x.e->xbutton.y >= (signed)-b && + e->data.x.e->xbutton.x < (signed)(w+b) && + e->data.x.e->xbutton.y < (signed)(h+b)) { + click = TRUE; + /* double clicks happen if there were 2 in a row! */ + if (lbutton == button && + e->data.x.e->xbutton.time - dclicktime <= ltime) { + dclick = TRUE; lbutton = 0; - } + } else + lbutton = button; + } else + lbutton = 0; button = 0; state = 0;

@@ -326,17 +274,30 @@ break;

case Event_X_MotionNotify: if (button) { - dx = e->data.x.e->xmotion.x_root - px; - dy = e->data.x.e->xmotion.y_root - py; - if (!drag && - (ABS(dx) >= threshold || ABS(dy) >= threshold)) { - drag = TRUE; - } - if (drag) { - drag_used = fire_motion(MouseAction_Motion, drag_context, - drag_client, - state, button, cx, cy, cw, ch, dx, dy, - FALSE, corner); + if (ABS(e->data.x.e->xmotion.x_root - px) >= threshold || + ABS(e->data.x.e->xmotion.y_root - py) >= threshold) { + guint32 corner = + pick_corner(e->data.x.e->xmotion.x_root, + e->data.x.e->xmotion.y_root, + e->data.x.client->frame->area.x, + e->data.x.client->frame->area.y, + /* use the client size because the frame can be + differently sized (shaded windows) and we + want this based on the clients size */ + e->data.x.client->area.width + + e->data.x.client->frame->size.left + + e->data.x.client->frame->size.right, + e->data.x.client->area.height + + e->data.x.client->frame->size.top + + e->data.x.client->frame->size.bottom); + context = frame_context(e->data.x.client, + e->data.x.e->xmotion.window); + fire_motion(MouseAction_Motion, context, + e->data.x.client, state, button, + e->data.x.e->xmotion.x_root, + e->data.x.e->xmotion.y_root, corner); + button = 0; + state = 0; } } break;
M plugins/mouse/mouseparse.cplugins/mouse/mouseparse.c

@@ -1,5 +1,6 @@

#include "kernel/action.h" #include "kernel/parse.h" +#include "kernel/prop.h" #include "mouse.h" void mouseparse(ParseToken *token)

@@ -68,12 +69,26 @@ if (token->type == TOKEN_IDENTIFIER) {

action = action_from_string(token->data.identifier); /* check for valid actions for motion events */ - if ((event == MouseAction_Motion) ^ - (action && - (action->func == action_move || - action->func == action_resize))) { - action_free(action); - action = NULL; + if (action->func == action_moveresize) + g_message("%d", action->data.moveresize.corner); + if (event == MouseAction_Motion) { + if (action && (action->func != action_moveresize || + action->data.moveresize.corner == + prop_atoms.net_wm_moveresize_move_keyboard || + action->data.moveresize.corner == + prop_atoms.net_wm_moveresize_size_keyboard)) { + action_free(action); + action = NULL; + } + } else { + if (action && action->func == action_moveresize && + action->data.moveresize.corner != + prop_atoms.net_wm_moveresize_move_keyboard && + action->data.moveresize.corner != + prop_atoms.net_wm_moveresize_size_keyboard) { + action_free(action); + action = NULL; + } } if (action != NULL) {