X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=plugins%2Fmouse%2Fmouse.c;h=4c19d2436a65800004e2c77b6602e81e85487a4e;hb=28a4456c46976ba5c58a300dfa67109227bc1583;hp=1f0a448288089eab81dcc867ad72290bebe36b6c;hpb=c3e80452f0fd387b894f36b27b1e2f75b95e06bc;p=chaz%2Fopenbox diff --git a/plugins/mouse/mouse.c b/plugins/mouse/mouse.c index 1f0a4482..4c19d243 100644 --- a/plugins/mouse/mouse.c +++ b/plugins/mouse/mouse.c @@ -6,6 +6,7 @@ #include "../../kernel/frame.h" #include "../../kernel/grab.h" #include "../../kernel/engine.h" +#include "../../kernel/config.h" #include "translate.h" #include "mouse.h" #include "mouserc_parse.h" @@ -13,10 +14,17 @@ void plugin_setup_config() { + config_def_set(config_def_new("mouse.dragThreshold", Config_Integer, + "Drag Threshold", + "The drag threshold in pixels before a Drag " + "event starts.")); + config_def_set(config_def_new("mouse.doubleClickTime", Config_Integer, + "Double Click Interval", + "The amount of time (in milliseconds) in " + "which two clicks must occur to cause a " + "DoubleClick event.")); } -static int drag_threshold = 3; - /* GData of GSList*s of PointerBinding*s. */ static GData *bound_contexts; @@ -113,10 +121,13 @@ static void fire_button(MouseAction a, GQuark 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 */ -static void fire_motion(MouseAction a, GQuark context, Client *c, guint state, - guint button, int cx, int cy, int cw, int ch, - int dx, int dy, gboolean final, Corner corner) + 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, GQuark context, Client *c, + guint state, guint button, int cx, int cy, + int cw, int ch, int dx, int dy, + gboolean final, Corner corner) { GSList *it; MouseBinding *b; @@ -128,7 +139,7 @@ static void fire_motion(MouseAction a, GQuark context, Client *c, guint state, break; } /* if not bound, then nothing to do! */ - if (it == NULL) return; + if (it == NULL) return FALSE; if (b->action[a] != NULL && b->action[a]->func != NULL) { b->action[a]->data.any.c = c; @@ -160,7 +171,9 @@ static void fire_motion(MouseAction a, GQuark context, Client *c, guint state, b->action[a]->data.resize.final = final; } 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) @@ -183,11 +196,18 @@ static void event(ObEvent *e, void *foo) static Time ltime; static int px, py, cx, cy, cw, ch, dx, dy; static guint button = 0, lbutton = 0; - static gboolean drag = FALSE; + static gboolean drag = FALSE, drag_used = FALSE; static Corner corner = Corner_TopLeft; + ConfigValue doubleclicktime; + ConfigValue dragthreshold; gboolean click = FALSE; gboolean dclick = FALSE; GQuark context; + + if (!config_get("mouse.dragThreshold", Config_Integer, &dragthreshold)) + dragthreshold.integer = 3; /* default */ + if (!config_get("mouse.doubleClickTime", Config_Integer, &doubleclicktime)) + doubleclicktime.integer = 200; /* default */ switch (e->type) { case Event_Client_Mapped: @@ -203,8 +223,15 @@ static void event(ObEvent *e, void *foo) if (e->data.x.client != NULL) { cx = e->data.x.client->frame->area.x; cy = e->data.x.client->frame->area.y; - cw = e->data.x.client->frame->area.width; - ch = e->data.x.client->frame->area.height; + /* 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); @@ -230,12 +257,12 @@ static void event(ObEvent *e, void *foo) e->data.x.e->xbutton.window); if (e->data.x.e->xbutton.button == button) { /* end drags */ - if (drag) { + if (drag_used) { fire_motion(MouseAction_Motion, context, e->data.x.client, e->data.x.e->xbutton.state, e->data.x.e->xbutton.button, cx, cy, cw, ch, dx, dy, TRUE, corner); - drag = FALSE; + drag = drag_used = FALSE; lbutton = 0; } else { @@ -249,10 +276,11 @@ static void event(ObEvent *e, void *foo) 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; + click = TRUE; /* double clicks happen if there were 2 in a row! */ if (lbutton == button && - e->data.x.e->xbutton.time - 300 <= ltime) { + e->data.x.e->xbutton.time - doubleclicktime.integer <= + ltime) { dclick = TRUE; lbutton = 0; } else @@ -264,7 +292,7 @@ static void event(ObEvent *e, void *foo) button = 0; ltime = e->data.x.e->xbutton.time; } - fire_button(MouseAction_Press, context, + fire_button(MouseAction_Release, context, e->data.x.client, e->data.x.e->xbutton.state, e->data.x.e->xbutton.button); if (click) @@ -281,14 +309,18 @@ static void event(ObEvent *e, void *foo) if (button) { dx = e->data.x.e->xmotion.x_root - px; dy = e->data.x.e->xmotion.y_root - py; - if (ABS(dx) >= drag_threshold || ABS(dy) >= drag_threshold) + if (!drag && + (ABS(dx) >= dragthreshold.integer || + ABS(dy) >= dragthreshold.integer)) drag = TRUE; if (drag) { context = engine_get_context(e->data.x.client, e->data.x.e->xbutton.window); - fire_motion(MouseAction_Motion, context, - e->data.x.client, e->data.x.e->xmotion.state, - button, cx, cy, cw, ch, dx, dy, FALSE, corner); + drag_used = fire_motion(MouseAction_Motion, context, + e->data.x.client, + e->data.x.e->xmotion.state, + button, cx, cy, cw, ch, dx, dy, + FALSE, corner); } } break;