#include "kernel/client.h"
#include "kernel/prop.h"
#include "kernel/grab.h"
-#include "kernel/parse.h"
#include "kernel/frame.h"
+#include "parser/parse.h"
#include "translate.h"
#include "mouse.h"
-#include "mouseparse.h"
#include <glib.h>
static int threshold;
static int dclicktime;
+/*
-static void parse_assign(char *name, ParseToken *value)
+<context name="Titlebar">
+ <mousebind button="Left" action="Press">
+ <action name="Raise"></action>
+ </mousebind>
+</context>
+
+*/
+
+static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d)
{
- if (!g_ascii_strcasecmp(name, "dragthreshold")) {
- if (value->type != TOKEN_INTEGER)
- yyerror("invalid value");
- else {
- if (value->data.integer >= 0)
- threshold = value->data.integer;
- }
- } else if (!g_ascii_strcasecmp(name, "doubleclicktime")) {
- if (value->type != TOKEN_INTEGER)
- yyerror("invalid value");
- else {
- if (value->data.integer >= 0)
- dclicktime = value->data.integer;
+ xmlNodePtr n, nbut, nact;
+ char *buttonstr;
+ char *contextstr;
+ MouseAction mact;
+ Action *action;
+
+ node = node->xmlChildrenNode;
+
+ if ((n = parse_find_node("dragThreshold", node)))
+ threshold = parse_int(doc, n);
+ if ((n = parse_find_node("doubleClickTime", node)))
+ dclicktime = parse_int(doc, n);
+
+ n = parse_find_node("context", node);
+ while (n) {
+ if (!parse_attr_string("name", n, &contextstr))
+ goto next_n;
+ nbut = parse_find_node("mousebind", n->xmlChildrenNode);
+ while (nbut) {
+ if (!parse_attr_string("button", nbut, &buttonstr))
+ goto next_nbut;
+ if (parse_attr_contains("press", nbut, "action"))
+ mact = MouseAction_Press;
+ else if (parse_attr_contains("release", nbut, "action"))
+ mact = MouseAction_Release;
+ else if (parse_attr_contains("click", nbut, "action"))
+ mact = MouseAction_Click;
+ else if (parse_attr_contains("doubleclick", nbut,"action"))
+ mact = MouseAction_DClick;
+ else if (parse_attr_contains("drag", nbut, "action"))
+ mact = MouseAction_Motion;
+ else
+ goto next_nbut;
+ nact = parse_find_node("action", nbut->xmlChildrenNode);
+ while (nact) {
+ if ((action = action_parse(doc, nact))) {
+ /* validate that its okay for a mouse binding*/
+ if (mact == MouseAction_Motion) {
+ if (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->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)
+ mbind(buttonstr, contextstr, mact, action);
+ }
+ nact = parse_find_node("action", nact->next);
+ }
+ g_free(buttonstr);
+ next_nbut:
+ nbut = parse_find_node("mousebind", nbut->next);
}
- } else
- yyerror("invalid option");
- parse_free_token(value);
+ g_free(contextstr);
+ next_n:
+ n = parse_find_node("context", n->next);
+ }
}
void plugin_setup_config()
{
threshold = 3;
dclicktime = 200;
- parse_reg_section("mouse", mouseparse, parse_assign);
+ parse_register("mouse", parse_xml, NULL);
}
/* Array of GSList*s of PointerBinding*s. */
-static GSList *bound_contexts[NUM_CONTEXTS];
+static GSList *bound_contexts[OB_FRAME_NUM_CONTEXTS];
-static void grab_for_client(Client *client, gboolean grab)
+static void grab_for_client(ObClient *client, gboolean grab)
{
int i;
GSList *it;
- for (i = 0; i < NUM_CONTEXTS; ++i)
+ for (i = 0; i < OB_FRAME_NUM_CONTEXTS; ++i)
for (it = bound_contexts[i]; it != NULL; it = it->next) {
/* grab/ungrab the button */
MouseBinding *b = it->data;
int mode;
unsigned int mask;
- if (i == Context_Frame) {
+ if (i == OB_FRAME_CONTEXT_FRAME) {
win = client->frame->window;
mode = GrabModeAsync;
mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask;
- } else if (i == Context_Client) {
+ } else if (i == OB_FRAME_CONTEXT_CLIENT) {
win = client->frame->plate;
mode = GrabModeSync; /* this is handled in event */
mask = ButtonPressMask; /* can't catch more than this with Sync
int i;
GSList *it;
- for(i = 0; i < NUM_CONTEXTS; ++i) {
+ for(i = 0; i < OB_FRAME_NUM_CONTEXTS; ++i) {
for (it = bound_contexts[i]; it != NULL; it = it->next) {
int j;
}
}
-static void fire_button(MouseAction a, Context context, Client *c, guint state,
+static void fire_button(MouseAction a, ObFrameContext context,
+ ObClient *c, guint state,
guint button, int x, int y)
{
GSList *it;
}
}
-static void fire_motion(MouseAction a, Context context, Client *c,
+static void fire_motion(MouseAction a, ObFrameContext context, ObClient *c,
guint state, guint button, int x_root, int y_root,
guint32 corner)
{
{
static Time ltime;
static guint button = 0, state = 0, lbutton = 0;
+ static lwindow = None;
static int px, py;
gboolean click = FALSE;
gboolean dclick = FALSE;
- Context context;
+ ObFrameContext context;
switch (e->type) {
case Event_Client_Mapped:
context = frame_context(e->data.x.client,
e->data.x.e->xbutton.window);
- if (!button) {
- 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;
- }
+ 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;
fire_button(MouseAction_Press, context,
e->data.x.client, e->data.x.e->xbutton.state,
e->data.x.e->xbutton.button,
e->data.x.e->xbutton.x_root, e->data.x.e->xbutton.y_root);
- if (context == Context_Client) {
+ if (context == OB_FRAME_CONTEXT_CLIENT) {
/* Replay the event, so it goes to the client*/
XAllowEvents(ob_display, ReplayPointer, event_lasttime);
/* Fall through to the release case! */
e->data.x.e->xbutton.window);
if (e->data.x.e->xbutton.button == button) {
/* clicks are only valid if its released over the window */
- int junk;
+ int junk1, junk2;
Window wjunk;
guint ujunk, b, w, h;
XGetGeometry(ob_display, e->data.x.e->xbutton.window,
- &wjunk, &junk, &junk, &w, &h, &b, &ujunk);
+ &wjunk, &junk1, &junk2, &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) &&
click = TRUE;
/* double clicks happen if there were 2 in a row! */
if (lbutton == button &&
+ lwindow == e->data.x.e->xbutton.window &&
e->data.x.e->xbutton.time - dclicktime <= ltime) {
dclick = TRUE;
lbutton = 0;
- } else
+ } else {
lbutton = button;
- } else
+ lwindow = e->data.x.e->xbutton.window;
+ }
+ } else {
lbutton = 0;
+ lwindow = None;
+ }
button = 0;
state = 0;
ABS(e->data.x.e->xmotion.y_root - py) >= threshold) {
guint32 corner;
+ context = frame_context(e->data.x.client,
+ e->data.x.e->xmotion.window);
+
+ /* You can't drag on buttons */
+ if (context == OB_FRAME_CONTEXT_MAXIMIZE ||
+ context == OB_FRAME_CONTEXT_ALLDESKTOPS ||
+ context == OB_FRAME_CONTEXT_SHADE ||
+ context == OB_FRAME_CONTEXT_ICONIFY ||
+ context == OB_FRAME_CONTEXT_ICON ||
+ context == OB_FRAME_CONTEXT_CLOSE)
+ break;
+
if (!e->data.x.client)
corner = prop_atoms.net_wm_moveresize_size_bottomright;
else
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,
Action *action)
{
guint state, button;
- Context context;
+ ObFrameContext context;
MouseBinding *b;
GSList *it;