move the move/resize functionality into moveresize.c, for use with the netwm atoms. use it from teh plugins. combine the two actions.

This commit is contained in:
Dana Jansens 2003-04-17 05:28:35 +00:00
parent 55c424d38b
commit 7886b797a3
12 changed files with 355 additions and 233 deletions

View file

@ -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

View file

@ -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 @@ Action *action_from_string(char *name)
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 @@ void action_toggle_decorations(union ActionData *data)
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)

View file

@ -48,19 +48,12 @@ struct NextPreviousDesktop {
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 @@ union ActionData {
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 @@ void action_next_desktop_row(union ActionData *data);
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 */

View file

@ -8,6 +8,7 @@
#include "menu.h"
#include "framerender.h"
#include "focus.h"
#include "moveresize.h"
#include "stacking.h"
#include "extensions.h"
#include "timer.h"
@ -359,6 +360,14 @@ static void event_process(XEvent *e)
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 */
/*
if (e->type == ButtonPress || e->type == ButtonRelease ||

192
openbox/moveresize.c Normal file
View file

@ -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) {
}
}

14
openbox/moveresize.h Normal file
View file

@ -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

View file

@ -69,15 +69,18 @@ void prop_startup()
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");

View file

@ -73,11 +73,17 @@ typedef struct Atoms {
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;

View file

@ -143,9 +143,6 @@ static void event(ObEvent *e, void *foo)
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;

View file

@ -1,4 +1,5 @@
#include "kernel/parse.h"
#include "kernel/prop.h"
#include "keyboard.h"
void keyparse(ParseToken *token)
@ -44,9 +45,11 @@ void keyparse(ParseToken *token)
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;
}

View file

@ -3,6 +3,7 @@
#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 @@ static void fire_button(MouseAction a, Context context, Client *c, guint state,
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 @@ static void fire_button(MouseAction a, Context context, Client *c, guint state,
}
}
/* 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 @@ static gboolean fire_motion(MouseAction a, Context context, Client *c,
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 @@ static void event(ObEvent *e, void *foo)
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 @@ static void event(ObEvent *e, void *foo)
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 @@ static void event(ObEvent *e, void *foo)
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;

View file

@ -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 @@ void mouseparse(ParseToken *token)
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) {