allow application rules to place transient/dialog/splash windows, and allow applicati...
authorDana Jansens <danakj@orodu.net>
Fri, 8 Jan 2010 23:16:37 +0000 (18:16 -0500)
committerMikael Magnusson <mikachu@gmail.com>
Sun, 10 Jan 2010 21:15:27 +0000 (22:15 +0100)
data/rc.xml
openbox/client.c
openbox/config.c
openbox/place.c

index f5f3712..aa36192 100644 (file)
 <!--
   # this is an example with comments through out. use these to make your
   # own rules, but without the comments of course.
+  # you may use one or more of the name/class/role/type rules to specify
+  # windows to match
 
   <application name="the window's _OB_NAME property (see obxprop)"
               class="the window's _OB_CLASS property (see obxprop)"
                role="the window's _OB_ROLE property (see obxprop)"
                type="the window's _NET_WM_WINDOW_TYPE (see obxprob)..
-                      (if unspecified, then it is 'dialog' for child windows)">
+                      (if unspecified, then it is 'dialog' for child windows)
+                      one of: normal, dialog, splash, utility, menu, toolbar,
+                              dock, desktop">
   # the name or the class can be set, or both. this is used to match
   # windows when they appear. role can optionally be set as well, to
   # further restrict your matches.
index 98a27dc..4b70376 100644 (file)
@@ -327,9 +327,7 @@ void client_manage(Window window, ObPrompt *prompt)
                      "program + user specified" :
                      "BADNESS !?")))), place.width, place.height);
 
-        /* splash screens are also returned as TRUE for transient,
-           and so will be forced on screen below */
-        transient = place_client(self, &place.x, &place.y, settings);
+        place_client(self, &place.x, &place.y, settings);
 
         /* make sure the window is visible. */
         client_find_onscreen(self, &place.x, &place.y,
@@ -345,11 +343,13 @@ void client_manage(Window window, ObPrompt *prompt)
                                 it is up to the placement routines to avoid
                                 the xinerama divides)
 
-                                splash screens get "transient" set to TRUE by
-                                the place_client call
+                                children and splash screens are forced on
+                                screen, but i don't remember why i decided to
+                                do that.
                              */
                              ob_state() == OB_STATE_RUNNING &&
-                             (transient ||
+                             (self->type == OB_CLIENT_TYPE_DIALOG ||
+                              self->type == OB_CLIENT_TYPE_SPLASH ||
                               (!((self->positioned & USPosition) ||
                                  (settings && settings->pos_given)) &&
                                client_normal(self) &&
@@ -791,10 +791,9 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
         ObAppSettings *app = it->data;
         gboolean match = TRUE;
 
-        g_assert(app->name != NULL || app->class != NULL);
+        g_assert(app->name != NULL || app->class != NULL ||
+                 app->role != NULL || (signed)app->type >= 0);
 
-        /* we know that either name or class is not NULL so it will have to
-           match to use the rule */
         if (app->name &&
             !g_pattern_match(app->name, strlen(self->name), self->name, NULL))
             match = FALSE;
@@ -806,8 +805,9 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
                  !g_pattern_match(app->role,
                                   strlen(self->role), self->role, NULL))
             match = FALSE;
-        else if ((signed)app->type >= 0 && app->type != self->type)
+        else if ((signed)app->type >= 0 && app->type != self->type) {
             match = FALSE;
+        }
 
         if (match) {
             ob_debug("Window matching: %s", app->name);
index 6963559..6904759 100644 (file)
@@ -149,7 +149,7 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
         dst->pos_given = TRUE;
         dst->pos_force = src->pos_force;
         dst->position = src->position;
-        dst->monitor = src->monitor;
+        /* monitor is copied above */
     }
 }
 
@@ -200,8 +200,9 @@ static void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
 static void parse_per_app_settings(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr app = obt_xml_find_node(node->children, "application");
-    gchar *name = NULL, *class = NULL, *role = NULL, *type = NULL;
-    gboolean name_set, class_set, type_set;
+    gchar *name = NULL, *class = NULL, *role = NULL, *type_str = NULL;
+    gboolean name_set, class_set, type_set, role_set;
+    ObClientType type;
     gboolean x_pos_given;
 
     while (app) {
@@ -209,8 +210,32 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
 
         class_set = obt_xml_attr_string(app, "class", &class);
         name_set = obt_xml_attr_string(app, "name", &name);
-        type_set = obt_xml_attr_string(app, "type", &type);
-        if (class_set || name_set) {
+        type_set = obt_xml_attr_string(app, "type", &type_str);
+        role_set = obt_xml_attr_string(app, "role", &role);
+
+        /* validate the type tho */
+        if (type_set) {
+            if (!g_ascii_strcasecmp(type_str, "normal"))
+                type = OB_CLIENT_TYPE_NORMAL;
+            else if (!g_ascii_strcasecmp(type_str, "dialog"))
+                type = OB_CLIENT_TYPE_DIALOG;
+            else if (!g_ascii_strcasecmp(type_str, "splash"))
+                type = OB_CLIENT_TYPE_SPLASH;
+            else if (!g_ascii_strcasecmp(type_str, "utility"))
+                type = OB_CLIENT_TYPE_UTILITY;
+            else if (!g_ascii_strcasecmp(type_str, "menu"))
+                type = OB_CLIENT_TYPE_MENU;
+            else if (!g_ascii_strcasecmp(type_str, "toolbar"))
+                type = OB_CLIENT_TYPE_TOOLBAR;
+            else if (!g_ascii_strcasecmp(type_str, "dock"))
+                type = OB_CLIENT_TYPE_DOCK;
+            else if (!g_ascii_strcasecmp(type_str, "desktop"))
+                type = OB_CLIENT_TYPE_DESKTOP;
+            else
+                type_set = FALSE; /* not valid! */
+        }
+
+        if (class_set || name_set || role_set || type_set) {
             xmlNodePtr n, c;
             ObAppSettings *settings = config_create_app_settings();;
 
@@ -220,28 +245,12 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
             if (class_set)
                 settings->class = g_pattern_spec_new(class);
 
-            if (type_set) {
-                if (!g_ascii_strcasecmp(type, "normal"))
-                    settings->type = OB_CLIENT_TYPE_NORMAL;
-                else if (!g_ascii_strcasecmp(type, "dialog"))
-                    settings->type = OB_CLIENT_TYPE_DIALOG;
-                else if (!g_ascii_strcasecmp(type, "splash"))
-                    settings->type = OB_CLIENT_TYPE_SPLASH;
-                else if (!g_ascii_strcasecmp(type, "utility"))
-                    settings->type = OB_CLIENT_TYPE_UTILITY;
-                else if (!g_ascii_strcasecmp(type, "menu"))
-                    settings->type = OB_CLIENT_TYPE_MENU;
-                else if (!g_ascii_strcasecmp(type, "toolbar"))
-                    settings->type = OB_CLIENT_TYPE_TOOLBAR;
-                else if (!g_ascii_strcasecmp(type, "dock"))
-                    settings->type = OB_CLIENT_TYPE_DOCK;
-                else if (!g_ascii_strcasecmp(type, "desktop"))
-                    settings->type = OB_CLIENT_TYPE_DESKTOP;
-            }
-
-            if (obt_xml_attr_string(app, "role", &role))
+            if (role_set)
                 settings->role = g_pattern_spec_new(role);
 
+            if (type_set)
+                settings->type = type;
+
             if ((n = obt_xml_find_node(app->children, "decor")))
                 if (!obt_xml_node_contains(n, "default"))
                     settings->decor = obt_xml_node_bool(n);
@@ -339,7 +348,7 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
                 }
 
             config_per_app_settings = g_slist_append(config_per_app_settings,
-                                              (gpointer) settings);
+                                                     (gpointer) settings);
             g_free(name);
             g_free(class);
             g_free(role);
index ee8bf7e..36e977d 100644 (file)
@@ -484,8 +484,8 @@ gboolean place_client(ObClient *client, gint *x, gint *y,
         return FALSE;
 
     /* try a number of methods */
-    ret = place_transient_splash(client, x, y) ||
-        (userplaced = place_per_app_setting(client, x, y, settings)) ||
+    ret = (userplaced = place_per_app_setting(client, x, y, settings)) ||
+        place_transient_splash(client, x, y) ||
         (config_place_policy == OB_PLACE_POLICY_MOUSE &&
          place_under_mouse(client, x, y)) ||
         place_nooverlap(client, x, y) ||