#include "openbox/actions.h" #include "openbox/misc.h" #include "openbox/client.h" #include "openbox/frame.h" #include "openbox/screen.h" #include "openbox/focus.h" #include typedef struct { gboolean shaded_on; gboolean shaded_off; gboolean maxvert_on; gboolean maxvert_off; gboolean maxhorz_on; gboolean maxhorz_off; gboolean maxfull_on; gboolean maxfull_off; gboolean iconic_on; gboolean iconic_off; gboolean focused; gboolean unfocused; gboolean urgent_on; gboolean urgent_off; gboolean decor_off; gboolean decor_on; gboolean omnipresent_on; gboolean omnipresent_off; gboolean desktop_current; gboolean desktop_other; guint desktop_number; guint screendesktop_number; guint client_monitor; GPatternSpec *matchtitle; GRegex *regextitle; gchar *exacttitle; GSList *thenacts; GSList *elseacts; } Options; static gpointer setup_func(xmlNodePtr node); static void free_func(gpointer options); static gboolean run_func(ObActionsData *data, gpointer options); void action_if_startup(void) { actions_register("If", setup_func, free_func, run_func); } static inline set_bool(xmlNodePtr node, const char *name, gboolean *on, gboolean *off) { xmlNodePtr n; if ((n = obt_xml_find_node(node, name))) { if (obt_xml_node_bool(n)) *on = TRUE; else *off = TRUE; } } static gpointer setup_func(xmlNodePtr node) { xmlNodePtr n; Options *o; o = g_slice_new0(Options); set_bool(node, "shaded", &o->shaded_on, &o->shaded_off); set_bool(node, "maximized", &o->maxfull_on, &o->maxfull_off); set_bool(node, "maximizedhorizontal", &o->maxhorz_on, &o->maxhorz_off); set_bool(node, "maximizedvertical", &o->maxvert_on, &o->maxvert_off); set_bool(node, "iconified", &o->iconic_on, &o->iconic_off); set_bool(node, "focused", &o->focused, &o->unfocused); set_bool(node, "urgent", &o->urgent_on, &o->urgent_off); set_bool(node, "undecorated", &o->decor_off, &o->decor_on); set_bool(node, "omnipresent", &o->omnipresent_on, &o->omnipresent_off); if ((n = obt_xml_find_node(node, "desktop"))) { gchar *s; if ((s = obt_xml_node_string(n))) { if (!g_ascii_strcasecmp(s, "current")) o->desktop_current = TRUE; if (!g_ascii_strcasecmp(s, "other")) o->desktop_other = TRUE; else o->desktop_number = atoi(s); g_free(s); } } if ((n = obt_xml_find_node(node, "activedesktop"))) { o->screendesktop_number = obt_xml_node_int(n); } if ((n = obt_xml_find_node(node, "title"))) { gchar *s, *type = NULL; if ((s = obt_xml_node_string(n))) { if (!obt_xml_attr_string(n, "type", &type) || !g_ascii_strcasecmp(type, "pattern")) { o->matchtitle = g_pattern_spec_new(s); } else if (type && !g_ascii_strcasecmp(type, "regex")) { o->regextitle = g_regex_new(s, 0, 0, NULL); } else if (type && !g_ascii_strcasecmp(type, "exact")) { o->exacttitle = g_strdup(s); } g_free(s); } } if ((n = obt_xml_find_node(node, "monitor"))) { o->client_monitor = obt_xml_node_int(n); } if ((n = obt_xml_find_node(node, "then"))) { xmlNodePtr m; m = obt_xml_find_node(n->children, "action"); while (m) { ObActionsAct *action = actions_parse(m); if (action) o->thenacts = g_slist_append(o->thenacts, action); m = obt_xml_find_node(m->next, "action"); } } if ((n = obt_xml_find_node(node, "else"))) { xmlNodePtr m; m = obt_xml_find_node(n->children, "action"); while (m) { ObActionsAct *action = actions_parse(m); if (action) o->elseacts = g_slist_append(o->elseacts, action); m = obt_xml_find_node(m->next, "action"); } } return o; } static void free_func(gpointer options) { Options *o = options; while (o->thenacts) { actions_act_unref(o->thenacts->data); o->thenacts = g_slist_delete_link(o->thenacts, o->thenacts); } while (o->elseacts) { actions_act_unref(o->elseacts->data); o->elseacts = g_slist_delete_link(o->elseacts, o->elseacts); } if (o->matchtitle) g_pattern_spec_free(o->matchtitle); if (o->regextitle) g_regex_unref(o->regextitle); if (o->exacttitle) g_free(o->exacttitle); g_slice_free(Options, o); } /* Always return FALSE because its not interactive */ static gboolean run_func(ObActionsData *data, gpointer options) { Options *o = options; GSList *acts; ObClient *c = data->client; if (c && (!o->shaded_on || c->shaded) && (!o->shaded_off || !c->shaded) && (!o->iconic_on || c->iconic) && (!o->iconic_off || !c->iconic) && (!o->maxhorz_on || c->max_horz) && (!o->maxhorz_off || !c->max_horz) && (!o->maxvert_on || c->max_vert) && (!o->maxvert_off || !c->max_vert) && (!o->maxfull_on || (c->max_vert && c->max_horz)) && (!o->maxfull_off || !(c->max_vert && c->max_horz)) && (!o->focused || (c == focus_client)) && (!o->unfocused || !(c == focus_client)) && (!o->urgent_on || (c->urgent || c->demands_attention)) && (!o->urgent_off || !(c->urgent || c->demands_attention)) && (!o->decor_off || (c->undecorated || !(c->decorations & OB_FRAME_DECOR_TITLEBAR))) && (!o->decor_on || (!c->undecorated && (c->decorations & OB_FRAME_DECOR_TITLEBAR))) && (!o->omnipresent_on || (c->desktop == DESKTOP_ALL)) && (!o->omnipresent_off || (c->desktop != DESKTOP_ALL)) && (!o->desktop_current || ((c->desktop == screen_desktop) || (c->desktop == DESKTOP_ALL))) && (!o->desktop_other || ((c->desktop != screen_desktop) && (c->desktop != DESKTOP_ALL))) && (!o->desktop_number || ((c->desktop == o->desktop_number - 1) || (c->desktop == DESKTOP_ALL))) && (!o->screendesktop_number || screen_desktop == o->screendesktop_number - 1) && (!o->matchtitle || (g_pattern_match_string(o->matchtitle, c->original_title))) && (!o->regextitle || (g_regex_match(o->regextitle, c->original_title, 0, NULL))) && (!o->exacttitle || (!strcmp(o->exacttitle, c->original_title))) && (!o->client_monitor || (o->client_monitor == client_monitor(c) + 1))) { acts = o->thenacts; } else acts = o->elseacts; actions_run_acts(acts, data->uact, data->state, data->x, data->y, data->button, data->context, data->client); return FALSE; }