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;
gchar *buttonstr;
gchar *contextstr;
gchar *cxstr;
ObMouseAction mact;
mouse_unbind_all();
@ -482,37 +482,52 @@ static void parse_mouse(xmlNodePtr node, gpointer d)
n = obt_xml_find_node(node, "context");
while (n) {
if (!obt_xml_attr_string(n, "name", &contextstr))
goto next_n;
nbut = obt_xml_find_node(n->children, "mousebind");
while (nbut) {
if (!obt_xml_attr_string(nbut, "button", &buttonstr))
goto next_nbut;
if (obt_xml_attr_contains(nbut, "action", "press")) {
mact = OB_MOUSE_ACTION_PRESS;
} else if (obt_xml_attr_contains(nbut, "action", "release")) {
mact = OB_MOUSE_ACTION_RELEASE;
} else if (obt_xml_attr_contains(nbut, "action", "click")) {
mact = OB_MOUSE_ACTION_CLICK;
} else if (obt_xml_attr_contains(nbut, "action","doubleclick")) {
mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
} else if (obt_xml_attr_contains(nbut, "action", "drag")) {
mact = OB_MOUSE_ACTION_MOTION;
} else
goto next_nbut;
nact = obt_xml_find_node(nbut->children, "action");
while (nact) {
ObActionsAct *action;
gchar *modcxstr;
ObFrameContext cx;
if ((action = actions_parse(nact)))
mouse_bind(buttonstr, contextstr, mact, action);
nact = obt_xml_find_node(nact->next, "action");
if (!obt_xml_attr_string(n, "name", &cxstr))
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");
while (nbut) {
if (!obt_xml_attr_string(nbut, "button", &buttonstr))
goto next_nbut;
if (obt_xml_attr_contains(nbut, "action", "press"))
mact = OB_MOUSE_ACTION_PRESS;
else if (obt_xml_attr_contains(nbut, "action", "release"))
mact = OB_MOUSE_ACTION_RELEASE;
else if (obt_xml_attr_contains(nbut, "action", "click"))
mact = OB_MOUSE_ACTION_CLICK;
else if (obt_xml_attr_contains(nbut, "action","doubleclick"))
mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
else if (obt_xml_attr_contains(nbut, "action", "drag"))
mact = OB_MOUSE_ACTION_MOTION;
else
goto next_nbut;
nact = obt_xml_find_node(nbut->children, "action");
while (nact) {
ObActionsAct *action;
if ((action = actions_parse(nact)))
mouse_bind(buttonstr, cx, mact, action);
nact = obt_xml_find_node(nact->next, "action");
}
next_nbut:
g_free(buttonstr);
next_nbut:
nbut = obt_xml_find_node(nbut->next, "mousebind");
}
}
g_free(contextstr);
g_free(modcxstr);
g_free(cxstr);
next_n:
n = obt_xml_find_node(n->next, "context");
}
@ -959,8 +974,8 @@ static void bind_default_mouse(void)
};
for (it = binds; it->button; ++it)
mouse_bind(it->button, it->context, it->mact,
actions_parse_string(it->actname));
mouse_bind(it->button, frame_context_from_string(it->context),
it->mact, actions_parse_string(it->actname));
}
void config_startup(ObtXmlInst *i)

View file

@ -1281,6 +1281,50 @@ static void layout_title(ObFrame *self)
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)
{
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);
/*! 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,
gint x, gint y);

View file

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

View file

@ -29,7 +29,7 @@ struct _ObActionsAct;
void mouse_startup(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);
void mouse_unbind_all(void);