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;
|
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;
|
||||||
goto next_n;
|
ObFrameContext cx;
|
||||||
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)))
|
if (!obt_xml_attr_string(n, "name", &cxstr))
|
||||||
mouse_bind(buttonstr, contextstr, mact, action);
|
goto next_n;
|
||||||
nact = obt_xml_find_node(nact->next, "action");
|
|
||||||
|
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);
|
g_free(buttonstr);
|
||||||
next_nbut:
|
|
||||||
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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue