summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/defs.h1
-rw-r--r--src/parser.c37
-rw-r--r--src/sxwm.c50
3 files changed, 87 insertions, 1 deletions
diff --git a/src/defs.h b/src/defs.h
index 18c7e2b..5476434 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -105,6 +105,7 @@ typedef struct {
char **can_swallow[256];
char **can_be_swallowed[256];
char **scratchpads[32];
+ char **open_in_workspace[256];
char *torun[256];
} Config;
diff --git a/src/parser.c b/src/parser.c
index b230fa6..eb0b1a8 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -484,6 +484,43 @@ found:
else if (!strcmp(key, "new_win_master")) {
cfg->new_win_master = !strcmp(rest, "true") ? True : False;
}
+ else if (!strcmp(key, "open_in_workspace")) {
+ char *mid = strchr(rest, ':');
+ if (!mid) {
+ fprintf(stderr, "sxwmrc:%d: open_in_workspace missing workspace number\n", lineno);
+ continue;
+ }
+ *mid = '\0';
+ char *class_name = strip(rest);
+ char *ws_str = strip(mid + 1);
+
+ class_name = strip_quotes(class_name);
+
+ int ws = atoi(ws_str);
+ if (ws < 1 || ws > NUM_WORKSPACES) {
+ fprintf(stderr, "sxwmrc:%d: invalid workspace number %d\n", lineno, ws);
+ continue;
+ }
+
+ /* find free slot in open_in_workspace */
+ int slot = -1;
+ for (int i = 0; i < 256; i++) {
+ if (!cfg->open_in_workspace[i]) {
+ slot = i;
+ break;
+ }
+ }
+
+ if (slot >= 0) {
+ cfg->open_in_workspace[slot] = malloc(2 * sizeof(char *));
+ if (cfg->open_in_workspace[slot]) {
+ cfg->open_in_workspace[slot][0] = strdup(class_name); /* class name */
+ char ws_buf[16];
+ snprintf(ws_buf, sizeof(ws_buf), "%d", ws - 1); /* 0-indexed workspace */
+ cfg->open_in_workspace[slot][1] = strdup(ws_buf); /* workspace number */
+ }
+ }
+ }
else {
fprintf(stderr, "sxwmrc:%d: unknown option '%s'\n", lineno, key);
}
diff --git a/src/sxwm.c b/src/sxwm.c
index 8e9b2c4..5e86c75 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -47,6 +47,7 @@ Window find_toplevel(Window w);
/* void focus_prev(void); */
int get_monitor_for(Client *c);
pid_t get_pid(Window w);
+int get_workspace_for_window(Window w);
void grab_keys(void);
void hdl_button(XEvent *xev);
void hdl_button_release(XEvent *xev);
@@ -667,6 +668,36 @@ pid_t get_pid(Window w)
return pid;
}
+int get_workspace_for_window(Window w)
+{
+ XClassHint ch;
+ if (!XGetClassHint(dpy, w, &ch)) {
+ return current_ws; /* default to current workspace */
+ }
+
+ for (int i = 0; i < 256; i++) {
+ if (!user_config.open_in_workspace[i]) {
+ break;
+ }
+
+ char *rule_class = user_config.open_in_workspace[i][0];
+ char *rule_ws = user_config.open_in_workspace[i][1];
+
+ if (rule_class && rule_ws) {
+ if ((ch.res_class && strcasecmp(ch.res_class, rule_class) == 0) ||
+ (ch.res_name && strcasecmp(ch.res_name, rule_class) == 0)) {
+ XFree(ch.res_class);
+ XFree(ch.res_name);
+ return atoi(rule_ws);
+ }
+ }
+ }
+
+ XFree(ch.res_class);
+ XFree(ch.res_name);
+ return current_ws; /* default to current workspace */
+}
+
void grab_keys(void)
{
const int guards[] = {0,
@@ -1117,7 +1148,8 @@ void hdl_map_req(XEvent *xev)
return;
}
- Client *c = add_client(w, current_ws);
+ int target_ws = get_workspace_for_window(w);
+ Client *c = add_client(w, target_ws);
if (!c) {
return;
}
@@ -1152,6 +1184,11 @@ void hdl_map_req(XEvent *xev)
XSetWindowBorderWidth(dpy, w, user_config.border_width);
}
+ if (target_ws != current_ws) {
+ update_net_client_list();
+ return;
+ }
+
/* map & borders */
update_net_client_list();
if (!global_floating && !c->floating) {
@@ -1457,6 +1494,7 @@ void init_defaults(void)
for (int i = 0; i < 256; i++) {
default_config.can_be_swallowed[i] = NULL;
default_config.can_swallow[i] = NULL;
+ default_config.open_in_workspace[i] = NULL;
}
default_config.motion_throttle = 60;
@@ -1707,6 +1745,16 @@ void reload_config(void)
free(user_config.can_be_swallowed[i]);
user_config.can_be_swallowed[i] = NULL;
}
+ if (user_config.open_in_workspace[i]) {
+ if (user_config.open_in_workspace[i][0]) {
+ free(user_config.open_in_workspace[i][0]);
+ }
+ if (user_config.open_in_workspace[i][1]) {
+ free(user_config.open_in_workspace[i][1]);
+ }
+ free(user_config.open_in_workspace[i]);
+ user_config.open_in_workspace[i] = NULL;
+ }
}
/* free should_float arrays */