allow multiple contexts separated by space in a mouse binding
example: context="Top Left Right Bottom"
This commit is contained in:
parent
09d1d0434b
commit
f307a3feab
5 changed files with 102 additions and 38 deletions
|
@ -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))
|
||||
gchar *modcxstr;
|
||||
ObFrameContext cx;
|
||||
|
||||
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")) {
|
||||
if (obt_xml_attr_contains(nbut, "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;
|
||||
} else if (obt_xml_attr_contains(nbut, "action", "click")) {
|
||||
else if (obt_xml_attr_contains(nbut, "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;
|
||||
} else if (obt_xml_attr_contains(nbut, "action", "drag")) {
|
||||
else if (obt_xml_attr_contains(nbut, "action", "drag"))
|
||||
mact = OB_MOUSE_ACTION_MOTION;
|
||||
} else
|
||||
else
|
||||
goto next_nbut;
|
||||
|
||||
nact = obt_xml_find_node(nbut->children, "action");
|
||||
while (nact) {
|
||||
ObActionsAct *action;
|
||||
|
||||
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");
|
||||
}
|
||||
g_free(buttonstr);
|
||||
next_nbut:
|
||||
g_free(buttonstr);
|
||||
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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue