allow multiple contexts separated by space in a mouse binding

example: context="Top Left Right Bottom"
This commit is contained in:
Dana Jansens 2010-05-13 22:16:44 -04:00
parent 09d1d0434b
commit f307a3feab
5 changed files with 102 additions and 38 deletions

View file

@ -459,7 +459,7 @@ static void parse_mouse(xmlNodePtr node, gpointer d)
{ {
xmlNodePtr n, nbut, nact; xmlNodePtr n, nbut, nact;
gchar *buttonstr; gchar *buttonstr;
gchar *contextstr; gchar *cxstr;
ObMouseAction mact; ObMouseAction mact;
mouse_unbind_all(); mouse_unbind_all();
@ -482,37 +482,52 @@ static void parse_mouse(xmlNodePtr node, gpointer d)
n = obt_xml_find_node(node, "context"); n = obt_xml_find_node(node, "context");
while (n) { while (n) {
if (!obt_xml_attr_string(n, "name", &contextstr)) gchar *modcxstr;
ObFrameContext cx;
if (!obt_xml_attr_string(n, "name", &cxstr))
goto next_n; goto next_n;
modcxstr = g_strdup(cxstr); /* make a copy to mutilate */
while (frame_next_context_from_string(modcxstr, &cx)) {
if (!cx) {
g_message(_("Invalid context \"%s\" in mouse binding"),
cxstr);
break;
}
nbut = obt_xml_find_node(n->children, "mousebind"); nbut = obt_xml_find_node(n->children, "mousebind");
while (nbut) { while (nbut) {
if (!obt_xml_attr_string(nbut, "button", &buttonstr)) if (!obt_xml_attr_string(nbut, "button", &buttonstr))
goto next_nbut; goto next_nbut;
if (obt_xml_attr_contains(nbut, "action", "press")) { if (obt_xml_attr_contains(nbut, "action", "press"))
mact = OB_MOUSE_ACTION_PRESS; mact = OB_MOUSE_ACTION_PRESS;
} else if (obt_xml_attr_contains(nbut, "action", "release")) { else if (obt_xml_attr_contains(nbut, "action", "release"))
mact = OB_MOUSE_ACTION_RELEASE; mact = OB_MOUSE_ACTION_RELEASE;
} else if (obt_xml_attr_contains(nbut, "action", "click")) { else if (obt_xml_attr_contains(nbut, "action", "click"))
mact = OB_MOUSE_ACTION_CLICK; mact = OB_MOUSE_ACTION_CLICK;
} else if (obt_xml_attr_contains(nbut, "action","doubleclick")) { else if (obt_xml_attr_contains(nbut, "action","doubleclick"))
mact = OB_MOUSE_ACTION_DOUBLE_CLICK; mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
} else if (obt_xml_attr_contains(nbut, "action", "drag")) { else if (obt_xml_attr_contains(nbut, "action", "drag"))
mact = OB_MOUSE_ACTION_MOTION; mact = OB_MOUSE_ACTION_MOTION;
} else else
goto next_nbut; goto next_nbut;
nact = obt_xml_find_node(nbut->children, "action"); nact = obt_xml_find_node(nbut->children, "action");
while (nact) { while (nact) {
ObActionsAct *action; ObActionsAct *action;
if ((action = actions_parse(nact))) if ((action = actions_parse(nact)))
mouse_bind(buttonstr, contextstr, mact, action); mouse_bind(buttonstr, cx, mact, action);
nact = obt_xml_find_node(nact->next, "action"); nact = obt_xml_find_node(nact->next, "action");
} }
g_free(buttonstr);
next_nbut: next_nbut:
g_free(buttonstr);
nbut = obt_xml_find_node(nbut->next, "mousebind"); nbut = obt_xml_find_node(nbut->next, "mousebind");
} }
g_free(contextstr); }
g_free(modcxstr);
g_free(cxstr);
next_n: next_n:
n = obt_xml_find_node(n->next, "context"); n = obt_xml_find_node(n->next, "context");
} }
@ -959,8 +974,8 @@ static void bind_default_mouse(void)
}; };
for (it = binds; it->button; ++it) for (it = binds; it->button; ++it)
mouse_bind(it->button, it->context, it->mact, mouse_bind(it->button, frame_context_from_string(it->context),
actions_parse_string(it->actname)); it->mact, actions_parse_string(it->actname));
} }
void config_startup(ObtXmlInst *i) void config_startup(ObtXmlInst *i)

View file

@ -1281,6 +1281,50 @@ static void layout_title(ObFrame *self)
XUnmapWindow(obt_display, self->label); XUnmapWindow(obt_display, self->label);
} }
gboolean frame_next_context_from_string(gchar *names, ObFrameContext *cx)
{
gchar *p, *n;
if (!*names) /* empty string */
return FALSE;
/* find the first space */
for (p = names; *p; p = g_utf8_next_char(p)) {
const gunichar c = g_utf8_get_char(p);
if (g_unichar_isspace(c)) break;
}
if (p == names) {
/* leading spaces in the string */
n = g_utf8_next_char(names);
if (!frame_next_context_from_string(n, cx))
return FALSE;
} else {
n = p;
if (*p) {
/* delete the space with null zero(s) */
while (n < g_utf8_next_char(p))
*(n++) = '\0';
}
*cx = frame_context_from_string(names);
/* find the next non-space */
for (; *n; n = g_utf8_next_char(n)) {
const gunichar c = g_utf8_get_char(n);
if (!g_unichar_isspace(c)) break;
}
}
/* delete everything we just read (copy everything at n to the start of
the string */
for (p = names; *n; ++p, ++n)
*p = *n;
*p = *n;
return TRUE;
}
ObFrameContext frame_context_from_string(const gchar *name) ObFrameContext frame_context_from_string(const gchar *name)
{ {
if (!g_ascii_strcasecmp("Desktop", name)) if (!g_ascii_strcasecmp("Desktop", name))

View file

@ -221,6 +221,16 @@ void frame_release_client(ObFrame *self);
ObFrameContext frame_context_from_string(const gchar *name); ObFrameContext frame_context_from_string(const gchar *name);
/*! Parses a ObFrameContext from a string of space-separated context names.
@names The list of context names, the first of which is removed from the
string.
@cx The ObFrameContext is returned here. If an invalid name is found, this
is set to OB_FRAME_CONTEXT_NONE.
@return TRUE if there was something to read in @names, FALSE if it was an
empty input.
*/
gboolean frame_next_context_from_string(gchar *names, ObFrameContext *cx);
ObFrameContext frame_context(struct _ObClient *self, Window win, ObFrameContext frame_context(struct _ObClient *self, Window win,
gint x, gint y); gint x, gint y);

View file

@ -362,25 +362,20 @@ gboolean mouse_event(ObClient *client, XEvent *e)
return used; return used;
} }
gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr, gboolean mouse_bind(const gchar *buttonstr, ObFrameContext context,
ObMouseAction mact, ObActionsAct *action) ObMouseAction mact, ObActionsAct *action)
{ {
guint state, button; guint state, button;
ObFrameContext context;
ObMouseBinding *b; ObMouseBinding *b;
GSList *it; GSList *it;
g_assert(context != OB_FRAME_CONTEXT_NONE);
if (!translate_button(buttonstr, &state, &button)) { if (!translate_button(buttonstr, &state, &button)) {
g_message(_("Invalid button \"%s\" in mouse binding"), buttonstr); g_message(_("Invalid button \"%s\" in mouse binding"), buttonstr);
return FALSE; return FALSE;
} }
context = frame_context_from_string(contextstr);
if (!context) {
g_message(_("Invalid context \"%s\" in mouse binding"), contextstr);
return FALSE;
}
for (it = bound_contexts[context]; it; it = g_slist_next(it)) { for (it = bound_contexts[context]; it; it = g_slist_next(it)) {
b = it->data; b = it->data;
if (b->state == state && b->button == button) { if (b->state == state && b->button == button) {

View file

@ -29,7 +29,7 @@ struct _ObActionsAct;
void mouse_startup(gboolean reconfig); void mouse_startup(gboolean reconfig);
void mouse_shutdown(gboolean reconfig); void mouse_shutdown(gboolean reconfig);
gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr, gboolean mouse_bind(const gchar *buttonstr, ObFrameContext context,
ObMouseAction mact, struct _ObActionsAct *action); ObMouseAction mact, struct _ObActionsAct *action);
void mouse_unbind_all(void); void mouse_unbind_all(void);