Add "active" and "primary" options to the <monitor> placement option for per-app...
[dana/openbox.git] / openbox / config.c
index 00309d8..857255f 100644 (file)
@@ -111,6 +111,7 @@ ObAppSettings* config_create_app_settings(void)
     settings->type = -1;
     settings->decor = -1;
     settings->shade = -1;
+    settings->monitor_type = 0;
     settings->monitor = -1;
     settings->focus = -1;
     settings->desktop = 0;
@@ -135,6 +136,7 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
     copy_if(type, (ObClientType)-1);
     copy_if(decor, -1);
     copy_if(shade, -1);
+    copy_if(monitor_type, 0);
     copy_if(monitor, -1);
     copy_if(focus, -1);
     copy_if(desktop, 0);
@@ -200,8 +202,8 @@ void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
 
 /* Manages settings for individual applications.
    Some notes: monitor is the screen number in a multi monitor
-   (Xinerama) setup (starting from 0) or mouse, meaning the
-   monitor the pointer is on. Default: mouse.
+   (Xinerama) setup (starting from 0), or mouse: the monitor the pointer
+   is on, active: the active monitor, primary: the primary monitor.
    Layer can be three values, above (Always on top), below
    (Always on bottom) and everything else (normal behaviour).
    Positions can be an integer value or center, which will
@@ -294,7 +296,14 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
                     if (!obt_xml_node_contains(c, "default")) {
                         gchar *s = obt_xml_node_string(c);
                         if (!g_ascii_strcasecmp(s, "mouse"))
-                            settings->monitor = 0;
+                            settings->monitor_type =
+                                    OB_APP_SETTINGS_MONITOR_MOUSE;
+                        else if (!g_ascii_strcasecmp(s, "active"))
+                            settings->monitor_type =
+                                    OB_APP_SETTINGS_MONITOR_ACTIVE;
+                        else if (!g_ascii_strcasecmp(s, "primary"))
+                            settings->monitor_type =
+                                    OB_APP_SETTINGS_MONITOR_PRIMARY;
                         else
                             settings->monitor = obt_xml_node_int(c);
                         g_free(s);
@@ -370,7 +379,8 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
             g_free(class);
             g_free(role);
             g_free(title);
-            name = class = role = title = NULL;
+            g_free(type_str);
+            name = class = role = title = type_str = NULL;
         }
 
         app = obt_xml_find_node(app->next, "application");
@@ -389,39 +399,44 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
 
 static void parse_key(xmlNodePtr node, GList *keylist)
 {
-    gchar *key;
+    gchar *keystring, **keys, **key;
     xmlNodePtr n;
     gboolean is_chroot = FALSE;
 
-    if (!obt_xml_attr_string(node, "key", &key))
+    if (!obt_xml_attr_string(node, "key", &keystring))
         return;
 
     obt_xml_attr_bool(node, "chroot", &is_chroot);
 
-    keylist = g_list_append(keylist, key);
+    keys = g_strsplit(keystring, " ", 0);
+    for (key = keys; *key; ++key) {
+        keylist = g_list_append(keylist, *key);
 
-    if ((n = obt_xml_find_node(node->children, "keybind"))) {
-        while (n) {
-            parse_key(n, keylist);
-            n = obt_xml_find_node(n->next, "keybind");
+        if ((n = obt_xml_find_node(node->children, "keybind"))) {
+            while (n) {
+                parse_key(n, keylist);
+                n = obt_xml_find_node(n->next, "keybind");
+            }
         }
-    }
-    else if ((n = obt_xml_find_node(node->children, "action"))) {
-        while (n) {
-            ObActionsAct *action;
+        else if ((n = obt_xml_find_node(node->children, "action"))) {
+            while (n) {
+                ObActionsAct *action;
 
-            action = actions_parse(n);
-            if (action)
-                keyboard_bind(keylist, action);
-            n = obt_xml_find_node(n->next, "action");
+                action = actions_parse(n);
+                if (action)
+                    keyboard_bind(keylist, action);
+                n = obt_xml_find_node(n->next, "action");
+            }
         }
-    }
 
-    if (is_chroot)
-        keyboard_chroot(keylist);
 
-    g_free(key);
-    keylist = g_list_delete_link(keylist, g_list_last(keylist));
+        if (is_chroot)
+            keyboard_chroot(keylist);
+        keylist = g_list_delete_link(keylist, g_list_last(keylist));
+    }
+
+    g_strfreev(keys);
+    g_free(keystring);
 }
 
 static void parse_keyboard(xmlNodePtr node, gpointer d)
@@ -459,7 +474,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 +497,57 @@ 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;
-        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, contextstr, mact, action);
-                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) {
+                gchar *s = strchr(modcxstr, ' ');
+                if (s) {
+                    *s = '\0';
+                    g_message(_("Invalid context \"%s\" in mouse binding"),
+                              modcxstr);
+                    *s = ' ';
+                }
+                continue;
             }
+
+            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");
+                }
             g_free(buttonstr);
-        next_nbut:
+            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");
     }
@@ -556,6 +591,8 @@ static void parse_placement(xmlNodePtr node, gpointer d)
             config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
         else if (obt_xml_node_contains(n, "mouse"))
             config_place_monitor = OB_PLACE_MONITOR_MOUSE;
+        else if (obt_xml_node_contains(n, "any"))
+            config_place_monitor = OB_PLACE_MONITOR_ANY;
     }
     if ((n = obt_xml_find_node(node, "primaryMonitor"))) {
         config_primary_monitor_index = obt_xml_node_int(n);
@@ -959,8 +996,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)
@@ -977,7 +1014,7 @@ void config_startup(ObtXmlInst *i)
 
     config_place_policy = OB_PLACE_POLICY_SMART;
     config_place_center = TRUE;
-    config_place_monitor = OB_PLACE_MONITOR_ANY;
+    config_place_monitor = OB_PLACE_MONITOR_PRIMARY;
 
     config_primary_monitor_index = 1;
     config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
@@ -1042,7 +1079,7 @@ void config_startup(ObtXmlInst *i)
     obt_xml_register(i, "keyboard", parse_keyboard, NULL);
 
     config_mouse_threshold = 8;
-    config_mouse_dclicktime = 200;
+    config_mouse_dclicktime = 500;
     config_mouse_screenedgetime = 400;
     config_mouse_screenedgewarp = FALSE;