summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser.c43
-rw-r--r--src/sxwm.c76
2 files changed, 64 insertions, 55 deletions
diff --git a/src/parser.c b/src/parser.c
index 6b3185a..d6d35c2 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -378,38 +378,31 @@ found:
}
}
else if (!strcmp(key, "exec")) {
- char *comment = strchr(rest, '#');
- size_t len = comment ? (size_t)(comment - rest) : strlen(rest);
- char win[len + 1];
- strncpy(win, rest, len);
- win[len] = '\0';
-
- char *final = strip(win);
- char *cmd = strip(final);
- if (*cmd == '"') {
- cmd++;
- }
- else {
- fprintf(stderr, "sxwmrc:%d: exec not enclosed in quotes", lineno);
+ if (torun >= 256) {
+ fprintf(stderr, "sxwmrc:%d: too many exec commands\n", lineno);
+ continue;
}
- char *end = cmd + strlen(cmd) - 1;
- if (*end == '"') {
- *end = '\0';
- }
- else {
- fprintf(stderr, "sxwmrc:%d: exec not enclosed in quotes", lineno);
+ char *comment = strchr(rest, '#');
+ if (comment) {
+ *comment = '\0';
}
- printf("DEBUG: exec command '%s'\n", cmd);
- cfg->torun[torun] = strdup(cmd);
+ char *cmd = strip(rest);
+ cmd = strip_quotes(cmd);
- if (torun > 254) {
- fprintf(stderr, "sxwmrc:%d: too many execs", lineno);
+ if (!*cmd) {
+ fprintf(stderr, "sxwmrc:%d: empty exec command\n", lineno);
+ continue;
}
- else {
- torun++;
+
+ cfg->torun[torun] = strdup(cmd);
+ if (!cfg->torun[torun]) {
+ fprintf(stderr, "sxwmrc:%d: failed to allocate memory for exec command\n", lineno);
+ continue;
}
+
+ torun++;
}
else {
fprintf(stderr, "sxwmrc:%d: unknown option '%s'\n", lineno, key);
diff --git a/src/sxwm.c b/src/sxwm.c
index c76a6c5..4b25d62 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -41,6 +41,7 @@ void change_workspace(int ws);
int clean_mask(int mask);
/* void close_focused(void); */
/* void dec_gaps(void); */
+void startup_exec(void);
/* void focus_next(void); */
/* void focus_prev(void); */
int get_monitor_for(Client *c);
@@ -166,7 +167,8 @@ Client *add_client(Window w, int ws)
open_windows++;
XSelectInput(dpy, w,
- EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask);
+ EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask |
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
Atom protos[] = {atom_wm_delete};
XSetWMProtocols(dpy, w, protos, 1);
@@ -299,6 +301,22 @@ void dec_gaps(void)
}
}
+void startup_exec(void)
+{
+ for (int i = 0; i < 256; i++) {
+ if (user_config.torun[i]) {
+ const char **argv = build_argv(user_config.torun[i]);
+ if (argv) {
+ spawn(argv);
+ for (int j = 0; argv[j]; j++) {
+ free((char *)argv[j]);
+ }
+ free(argv);
+ }
+ }
+ }
+}
+
void focus_next(void)
{
if (!focused || !workspaces[current_ws]) {
@@ -553,7 +571,8 @@ void grab_keys(void)
void hdl_button(XEvent *xev)
{
XButtonEvent *e = &xev->xbutton;
- Window w = e->subwindow;
+ Window w = (e->subwindow != None) ? e->subwindow : e->window;
+ XAllowEvents(dpy, ReplayPointer, e->time);
if (!w) {
return;
}
@@ -588,6 +607,16 @@ void hdl_button(XEvent *xev)
toggle_floating();
}
+ if ((!(e->state & user_config.modkey) && e->button == Button1) ||
+ ((e->state & user_config.modkey) && e->button == Button2)) {
+ focused = c;
+ XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+ send_wm_take_focus(c->win);
+ XRaiseWindow(dpy, c->win);
+ update_borders();
+ return;
+ }
+
if (!c->floating) {
return;
}
@@ -951,7 +980,7 @@ void hdl_map_req(XEvent *xev)
for (Client *c = workspaces[current_ws]; c; c = c->next) {
if (c->win == w) {
c->mapped = True;
- }
+ }
}
if (user_config.new_win_focus) {
focused = c;
@@ -1361,6 +1390,9 @@ void reload_config(void)
}
grab_keys();
XUngrabButton(dpy, AnyButton, AnyModifier, root);
+
+ XGrabButton(dpy, Button1, 0, root, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync,
+ GrabModeAsync, None, None);
XGrabButton(dpy, Button1, user_config.modkey, root, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(dpy, Button1, user_config.modkey | ShiftMask, root, True,
@@ -1497,36 +1529,11 @@ void setup(void)
other_wm();
init_defaults();
if (parser(&user_config)) {
- fprintf(stderr, "sxrc: error parsing config file\n");
+ fprintf(stderr, "sxwmrc: error parsing config file\n");
init_defaults();
}
-
- for (int i = 0; i < 256; i++) {
- if (user_config.torun[i]) {
- printf("[DEBUG] executing %s\n", user_config.torun[i]);
- pid_t pid = fork();
- if (pid == 0) {
- char *argv[256];
- int j = 0;
- char *arg = strtok(user_config.torun[i], " ");
- while (arg && j < 256) {
- argv[j++] = arg;
- arg = strtok(NULL, " ");
- }
- argv[j] = NULL;
- execvp(argv[0], argv);
- perror("execvp");
- _exit(127);
- }
- else if (pid > 0) {
- // parent: don’t wait, just continue (background)
- }
- else {
- perror("fork");
- }
- }
- }
grab_keys();
+ startup_exec();
c_normal = XcursorLibraryLoadCursor(dpy, "left_ptr");
c_move = XcursorLibraryLoadCursor(dpy, "fleur");
@@ -1541,6 +1548,15 @@ void setup(void)
StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask | KeyPressMask |
PropertyChangeMask);
+ /* this is to grab the buttons for:
+ * focusing,
+ * moving,
+ * swapping,
+ * resizing
+ * windows in that order.
+ */
+ XGrabButton(dpy, Button1, 0, root, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync,
+ GrabModeAsync, None, None);
XGrabButton(dpy, Button1, user_config.modkey, root, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(dpy, Button1, user_config.modkey | ShiftMask, root, True,