per app settings
authorMikael Magnusson <mikachu@comhem.se>
Thu, 8 Jun 2006 10:18:31 +0000 (10:18 +0000)
committerMikael Magnusson <mikachu@comhem.se>
Thu, 8 Jun 2006 10:18:31 +0000 (10:18 +0000)
Makefile.am
data/rc.xsd
openbox/client.c
openbox/config.c
openbox/config.h

index 7f40f68..7e21281 100644 (file)
@@ -202,7 +202,9 @@ openbox_openbox_SOURCES = \
        openbox/window.c \
        openbox/window.h \
        openbox/xerror.c \
-       openbox/xerror.h
+       openbox/xerror.h \
+       openbox/per_app_settings.c \
+       openbox/per_app_settings.h
 
 
 ## kdetrayproxy ##
index 4241add..85f72eb 100644 (file)
@@ -61,6 +61,7 @@
                 <xs:element name="keyboard" type="ob:keyboard"/>
                 <xs:element name="mouse" type="ob:mouse"/>
                 <xs:element name="menu" type="ob:menu"/>
+                <xs:element name="applications" type="ob:applications"/>
             </xs:sequence>
         </xs:complexType>
     </xs:element>
             <xs:element name="desktopMenuIcons" type="ob:yesorno"/>
         </xs:sequence>
     </xs:complexType>
+    <xs:complexType name="position">
+        <xs:sequence>
+            <xs:element name="x" type="xs:string"/>
+            <xs:element name="y" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="application">
+        <xs:sequence>
+            <xs:element name="decor" type="xs:string"/>
+            <xs:element name="focus" type="xs:string"/>
+            <xs:element name="position" type="ob:position"/>
+            <xs:element name="head" type="xs:string"/>
+            <xs:element name="layer" type="xs:string"/>
+            <xs:element name="desktop" type="xs:integer"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:string" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="applications">
+        <xs:sequence>
+            <xs:element maxOccurs="unboundd" name="application" type="ob:application"/>
+        </xs:sequence>
+    </xs:complexType>
     <!--
          simple types / restrictions
       -->
index 583f061..0cc393b 100644 (file)
@@ -40,6 +40,7 @@
 #include "keyboard.h"
 #include "mouse.h"
 #include "render/render.h"
+#include "per_app_settings.h"
 
 #include <glib.h>
 #include <X11/Xutil.h>
@@ -212,6 +213,7 @@ void client_manage(Window window)
     XSetWindowAttributes attrib_set;
     XWMHints *wmhint;
     gboolean activate = FALSE;
+    ObAppSetting *settings;
 
     grab_server(TRUE);
 
@@ -292,12 +294,29 @@ void client_manage(Window window)
 
     client_apply_startup_state(self);
 
+    /* get and set application level settings */
+    settings = (ObAppSetting *) get_client_settings(self);
+
+    if (settings) {
+        if (settings->shade && !settings->decor)
+            settings->decor = TRUE;
+        
+        client_shade(self, settings->shade);
+        client_set_undecorated(self, !settings->decor);
+        
+        if (settings->desktop != -1)
+            client_set_desktop(self, settings->desktop, FALSE);
+
+        client_set_layer(self, settings->layer);
+    }
+
     stacking_add(CLIENT_AS_WINDOW(self));
     client_restore_session_stacking(self);
 
     /* focus the new window? */
     if (ob_state() != OB_STATE_STARTING &&
-        (config_focus_new || client_search_focus_parent(self)) &&
+        (config_focus_new || client_search_focus_parent(self)) ||
+        (settings && settings->focus) &&
         /* note the check against Type_Normal/Dialog, not client_normal(self),
            which would also include other types. in this case we want more
            strict rules for focus */
@@ -344,6 +363,9 @@ void client_manage(Window window)
 
         place_client(self, &x, &y);
 
+        if (settings)
+            place_window_from_settings(settings, self, &x, &y);
+
         /* make sure the window is visible. */
         client_find_onscreen(self, &x, &y,
                              self->frame->area.width,
index 9109675..7f51c0f 100644 (file)
@@ -80,6 +80,108 @@ gint config_resist_edge;
 
 gboolean config_resist_layers_below;
 
+GSList *per_app_settings;
+
+/*
+  <applications>
+    <application name="aterm">
+      <decor>false</decor>
+    </application>
+    <application name="Rhythmbox">
+      <layer>above</layer>
+      <position>
+        <x>700</x>
+        <y>0</y>
+      </position>
+      <head>1</head>
+    </application>
+  </applications>
+*/
+
+/* Manages settings for individual applications.
+   Some notes: head is the screen number in a multi monitor
+   (Xinerama) setup (starting from 0) or mouse, meaning the
+   head the pointer is on. Default: mouse.
+   If decor is false and shade is true, the decor will be
+   set to true (otherwise we will have an invisible window).
+   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
+   center the window in the specified axis. Position is relative
+   from head, so <position><x>center</x></position><head>1</head>
+   will center the window on the second head.
+*/
+static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
+                                   xmlNodePtr node, gpointer d)
+{
+    xmlNodePtr app = parse_find_node("application", node->children);
+    gchar *name;
+
+
+    while (app) {
+        if (parse_attr_string("name", app, &name)) {
+            xmlNodePtr n, c;
+            ObAppSetting *setting = g_new0(ObAppSetting, 1);
+            setting->name = name;
+
+            setting->decor = TRUE;
+            if ((n = parse_find_node("decor", app->children)))
+                setting->decor = parse_bool(doc, n);
+
+            if ((n = parse_find_node("shade", app->children)))
+                setting->shade = parse_bool(doc, n);
+
+            setting->position.x = setting->position.y = -1;
+            if ((n = parse_find_node("position", app->children))) {
+                if ((c = parse_find_node("x", n->children))) {
+                    if (!strcmp(parse_string(doc, c), "center")) {
+                        setting->center_x = TRUE;
+                    }
+                    else
+                        setting->position.x = parse_int(doc, c);
+                }
+
+                if ((c = parse_find_node("y", n->children))) {
+                    if (!strcmp(parse_string(doc, c), "center")) {
+                        setting->center_y = TRUE;
+                    }
+                    else
+                        setting->position.y = parse_int(doc, c);
+                }
+            }
+
+            if ((n = parse_find_node("focus", app->children)))
+                setting->focus = parse_bool(doc, n);
+
+            if ((n = parse_find_node("desktop", app->children)))
+                setting->desktop = parse_int(doc, n);
+            else
+                setting->desktop = -1;
+
+            if ((n = parse_find_node("head", app->children))) {
+                if (!strcmp(parse_string(doc, n), "mouse"))
+                    setting->head = -1;
+                else
+                    setting->head = parse_int(doc, n);
+            }
+
+            if ((n = parse_find_node("layer", app->children))) {
+                if (!strcmp(parse_string(doc, n), "above"))
+                    setting->layer = 1;
+                else if (!strcmp(parse_string(doc, n), "below"))
+                    setting->layer = -1;
+                else
+                    setting->layer = 0;
+            }
+
+            per_app_settings = g_slist_append(per_app_settings,
+                                              (gpointer) setting);
+        }
+        
+        app = parse_find_node("application", app->next);
+    }
+}
+
 /*
 
 <keybind key="C-x">
@@ -625,6 +727,10 @@ void config_startup(ObParseInst *i)
     config_menu_files = NULL;
 
     parse_register(i, "menu", parse_menu, NULL);
+
+    per_app_settings = NULL;
+
+    parse_register(i, "applications", parse_per_app_settings, NULL);
 }
 
 void config_shutdown()
index a42e8a7..5abb7d8 100644 (file)
@@ -23,6 +23,7 @@
 #include "misc.h"
 #include "stacking.h"
 #include "place.h"
+#include "per_app_settings.h"
 
 #include <glib.h>