summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2007-05-21 03:42:25 +0000
committerDana Jansens <danakj@orodu.net>2007-05-21 03:42:25 +0000
commitfd8ce9414aa12028b26fd67082e843ea161e3b90 (patch)
treebc90ab00edd37f27e4649d7e20f53eb109098153 /openbox
parentadd9c3c1bbb2a9dca01d1bd79147f86328396e47 (diff)
use simple pattern matching for per-app settings. all rules that match are applied to a window rather than just the first
Diffstat (limited to 'openbox')
-rw-r--r--openbox/client.c57
-rw-r--r--openbox/client.h1
-rw-r--r--openbox/config.c89
-rw-r--r--openbox/config.h16
4 files changed, 112 insertions, 51 deletions
diff --git a/openbox/client.c b/openbox/client.c
index e77a4ea6..9b89b103 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -314,7 +314,8 @@ void client_manage(Window window)
grab_server(FALSE);
/* per-app settings override stuff from client_get_all, and return the
- settings for other uses too */
+ settings for other uses too. the returned settings is a shallow copy,
+ that needs to be freed with g_free(). */
settings = client_get_settings_state(self);
/* the session should get the last say thought */
client_restore_session_state(self);
@@ -506,6 +507,9 @@ void client_manage(Window window)
/* update the list hints */
client_set_list();
+ /* free the ObAppSettings shallow copy */
+ g_free(settings);
+
ob_debug("Managed window 0x%lx plate 0x%x (%s)\n",
window, self->frame->plate, self->class);
@@ -527,7 +531,7 @@ ObClient *client_fake_manage(Window window)
client_get_all(self, FALSE);
/* per-app settings override stuff, and return the settings for other
- uses too */
+ uses too. this returns a shallow copy that needs to be freed */
settings = client_get_settings_state(self);
client_setup_decor_and_functions(self);
@@ -535,6 +539,10 @@ ObClient *client_fake_manage(Window window)
/* create the decoration frame for the client window and adjust its size */
self->frame = frame_new(self);
frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
+
+ /* free the ObAppSettings shallow copy */
+ g_free(settings);
+
return self;
}
@@ -694,30 +702,39 @@ void client_fake_unmanage(ObClient *self)
g_free(self);
}
+/*! Returns a new structure containing the per-app settings for this client.
+ The returned structure needs to be freed with g_free. */
static ObAppSettings *client_get_settings_state(ObClient *self)
{
- ObAppSettings *settings = NULL;
+ ObAppSettings *settings;
GSList *it;
+ settings = config_create_app_settings();
+
for (it = config_per_app_settings; it; it = g_slist_next(it)) {
ObAppSettings *app = it->data;
-
- if ((app->name && !app->class && !strcmp(app->name, self->name))
- || (app->class && !app->name && !strcmp(app->class, self->class))
- || (app->class && app->name && !strcmp(app->class, self->class)
- && !strcmp(app->name, self->name)))
- {
- /* Match if no role was specified in the per app setting, or if the
- * string matches the beginning of the role, since apps like to set
- * the role to things like browser-window-23c4b2f */
- if (!app->role
- || !strncmp(app->role, self->role, strlen(app->role)))
- {
- ob_debug("Window matching: %s\n", app->name);
- /* use this one */
- settings = app;
- break;
- }
+ gboolean match = TRUE;
+
+ g_assert(app->name != NULL || app->class != NULL);
+
+ /* 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;
+ if (app->class &&
+ !g_pattern_match(app->class, strlen(self->class),self->class,NULL))
+ match = FALSE;
+ if (app->role &&
+ !g_pattern_match(app->role, strlen(self->role), self->role, NULL))
+ match = FALSE;
+
+ if (match) {
+ ob_debug("Window matching: %s\n", app->name);
+
+ /* copy the settings to our struct, overriding the existing
+ settings if they are not defaults */
+ config_app_settings_copy_non_defaults(app, settings);
}
}
diff --git a/openbox/client.h b/openbox/client.h
index 1467ecd1..e66cf9e8 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -35,7 +35,6 @@ struct _ObSessionState;
typedef struct _ObClient ObClient;
typedef struct _ObClientIcon ObClientIcon;
-typedef struct _ObAppSettings ObAppSettings;
/* The value in client.transient_for indicating it is a transient for its
group instead of for a single window */
diff --git a/openbox/config.c b/openbox/config.c
index c007de53..480308be 100644
--- a/openbox/config.c
+++ b/openbox/config.c
@@ -89,6 +89,54 @@ gint config_resist_edge;
GSList *config_per_app_settings;
+ObAppSettings* config_create_app_settings()
+{
+ ObAppSettings *settings = g_new0(ObAppSettings, 1);
+ settings->decor = -1;
+ settings->shade = -1;
+ settings->monitor = -1;
+ settings->focus = -1;
+ settings->desktop = 0;
+ settings->layer = -2;
+ settings->iconic = -1;
+ settings->skip_pager = -1;
+ settings->skip_taskbar = -1;
+ settings->fullscreen = -1;
+ settings->max_horz = -1;
+ settings->max_vert = -1;
+ return settings;
+}
+
+#define copy_if(setting, default) \
+ if (src->setting != default) dst->setting = src->setting
+void config_app_settings_copy_non_defaults(const ObAppSettings *src,
+ ObAppSettings *dst)
+{
+ g_assert(src != NULL);
+ g_assert(dst != NULL);
+
+ copy_if(decor, -1);
+ copy_if(shade, -1);
+ copy_if(focus, -1);
+ copy_if(desktop, 0);
+ copy_if(layer, -2);
+ copy_if(iconic, -1);
+ copy_if(skip_pager, -1);
+ copy_if(skip_taskbar, -1);
+ copy_if(fullscreen, -1);
+ copy_if(max_horz, -1);
+ copy_if(max_vert, -1);
+
+ if (src->pos_given) {
+ dst->pos_given = TRUE;
+ dst->center_x = src->center_x;
+ dst->center_y = src->center_y;
+ dst->position.x = src->position.x;
+ dst->position.y = src->position.y;
+ dst->monitor = src->monitor;
+ }
+}
+
/*
<applications>
<application name="aterm">
@@ -121,7 +169,7 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
xmlNodePtr node, gpointer d)
{
xmlNodePtr app = parse_find_node("application", node->children);
- gchar *name, *class;
+ gchar *name = NULL, *class = NULL, *role = NULL;
gboolean name_set, class_set;
gboolean x_pos_given;
@@ -132,33 +180,25 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
name_set = parse_attr_string("name", app, &name);
if (class_set || name_set) {
xmlNodePtr n, c;
- ObAppSettings *settings = g_new0(ObAppSettings, 1);
+ ObAppSettings *settings = config_create_app_settings();;
if (name_set)
- settings->name = name;
- else
- settings->name = NULL;
+ settings->name = g_pattern_spec_new(name);
if (class_set)
- settings->class = class;
- else
- settings->class = NULL;
+ settings->class = g_pattern_spec_new(class);
- if (!parse_attr_string("role", app, &settings->role))
- settings->role = NULL;
+ if (parse_attr_string("role", app, &role))
+ settings->role = g_pattern_spec_new(role);
- settings->decor = -1;
if ((n = parse_find_node("decor", app->children)))
if (!parse_contains("default", doc, n))
settings->decor = parse_bool(doc, n);
- settings->shade = -1;
if ((n = parse_find_node("shade", app->children)))
if (!parse_contains("default", doc, n))
settings->shade = parse_bool(doc, n);
- settings->position.x = settings->position.y = 0;
- settings->pos_given = FALSE;
if ((n = parse_find_node("position", app->children))) {
if ((c = parse_find_node("x", n->children)))
if (!parse_contains("default", doc, c)) {
@@ -198,7 +238,6 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
}
}
- settings->focus = -1;
if ((n = parse_find_node("focus", app->children)))
if (!parse_contains("default", doc, n))
settings->focus = parse_bool(doc, n);
@@ -214,11 +253,9 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
settings->desktop = i;
}
g_free(s);
- } else
- settings->desktop = 0;
+ }
}
- settings->layer = -2;
if ((n = parse_find_node("layer", app->children)))
if (!parse_contains("default", doc, n)) {
gchar *s = parse_string(doc, n);
@@ -231,28 +268,22 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
g_free(s);
}
- settings->iconic = -1;
if ((n = parse_find_node("iconic", app->children)))
if (!parse_contains("default", doc, n))
settings->iconic = parse_bool(doc, n);
- settings->skip_pager = -1;
if ((n = parse_find_node("skip_pager", app->children)))
if (!parse_contains("default", doc, n))
settings->skip_pager = parse_bool(doc, n);
- settings->skip_taskbar = -1;
if ((n = parse_find_node("skip_taskbar", app->children)))
if (!parse_contains("default", doc, n))
settings->skip_taskbar = parse_bool(doc, n);
- settings->fullscreen = -1;
if ((n = parse_find_node("fullscreen", app->children)))
if (!parse_contains("default", doc, n))
settings->fullscreen = parse_bool(doc, n);
- settings->max_horz = -1;
- settings->max_vert = -1;
if ((n = parse_find_node("maximized", app->children)))
if (!parse_contains("default", doc, n)) {
gchar *s = parse_string(doc, n);
@@ -274,6 +305,10 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
app = parse_find_node("application", app->next);
}
+
+ g_free(name);
+ g_free(class);
+ g_free(role);
}
/*
@@ -917,9 +952,9 @@ void config_shutdown()
for (it = config_per_app_settings; it; it = g_slist_next(it)) {
ObAppSettings *itd = (ObAppSettings *)it->data;
- g_free(itd->name);
- g_free(itd->role);
- g_free(itd->class);
+ if (itd->name) g_pattern_spec_free(itd->name);
+ if (itd->role) g_pattern_spec_free(itd->role);
+ if (itd->class) g_pattern_spec_free(itd->class);
g_free(it->data);
}
g_slist_free(config_per_app_settings);
diff --git a/openbox/config.h b/openbox/config.h
index a1598b8c..6a064fff 100644
--- a/openbox/config.h
+++ b/openbox/config.h
@@ -30,11 +30,13 @@
struct _ObParseInst;
+typedef struct _ObAppSettings ObAppSettings;
+
struct _ObAppSettings
{
- gchar *class;
- gchar *name;
- gchar *role;
+ GPatternSpec *class;
+ GPatternSpec *name;
+ GPatternSpec *role;
Point position;
gboolean center_x;
@@ -166,4 +168,12 @@ extern GSList *config_per_app_settings;
void config_startup(struct _ObParseInst *i);
void config_shutdown();
+/*! Create an ObAppSettings structure with the default values */
+ObAppSettings* config_create_app_settings();
+/*! Copies any settings in src to dest, if they are their default value in
+ src. */
+void config_app_settings_copy_non_defaults(const ObAppSettings *src,
+ ObAppSettings *dest);
+
+
#endif