diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | default_sxwmrc | 5 | ||||
| -rw-r--r-- | patches/README.md | 3 | ||||
| -rw-r--r-- | src/defs.h | 1 | ||||
| -rw-r--r-- | src/parser.c | 56 | ||||
| -rw-r--r-- | src/sxwm.c | 64 | ||||
| -rw-r--r-- | sxwm.1 | 6 |
8 files changed, 117 insertions, 26 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 821bdeb..9d0dd97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. #### v1.7 (git) - **ADD**: `_NET_FRAME_EXTENTS` support +- **ADD**: `start_fullscreen` which opens specified windows in fullscreen mode - **FIX**: Resizing bug on second monitor #### v1.6 (current) @@ -9,7 +9,9 @@ <img src="https://img.shields.io/github/license/uint23/sxwm?style=flat-square"> </div> ---- +> [!WARNING] +> From commit `7a7c6300`, `master_previous` binding has now been renamed to `master_prev`. +> Please update your `sxwmrc` accordingly. ## Table of Contents - [Launch Args](#launch-args) @@ -81,6 +83,7 @@ The file uses a `key : value` format. Lines starting with `#` are ignored. | `snap_distance` | Integer | `5` | Distance (px) before a floating window snaps to edge. | | `motion_throttle` | Integer | `60` | Target FPS for mouse drag actions. | | `should_float` | String | `"st"` | Always-float rule. Multiple entries should be comma-seperated. Optionally, entries can be enclosed in quotes.| +| `start_fullscreen` | String | `"st"` | Starts specified windows that should start fullscreened. Enclosed in quotes and comma-seperated| | `new_win_focus` | Bool | `true` | Whether openening new windows should also set focus to them or keep on current window.| | `warp_cursor` | Bool | `true` | Warp the cursor to the middle of newly focused windows | | `exec` | String | `Nothing` | Command to run on startup (e.g., `sxbar`, `picom`, "autostart", etc.). | @@ -259,7 +262,7 @@ sudo zypper install libX11-devel libXinerama-devel gcc make</code></pre> <details> <summary>Alpine Linux</summary> <pre><code>doas apk update -doas apk add libx11-dev libxinerama-dev gcc make musl-dev</code></pre> +doas apk add libx11-dev libxinerama-dev gcc make musl-dev linux-headers</code></pre> </details> <details> diff --git a/default_sxwmrc b/default_sxwmrc index e3c29b8..64959a7 100644 --- a/default_sxwmrc +++ b/default_sxwmrc @@ -11,12 +11,13 @@ resize_master_amount : 1 resize_stack_amt : 20 snap_distance : 5 motion_throttle : 60 # Set to screen refresh rate for smoothest motions -should_float : "pcmanfm" +should_float : "pcmanfm", "obs" new_win_focus : true warp_cursor : true can_swallow : "st" -can_be_swallowed : "mpv" +can_be_swallowed : "mpv", "sxiv" new_win_master : false +start_fullscreen : "mpv", "vlc" # Keybinds: # Commands must be surrounded with "" diff --git a/patches/README.md b/patches/README.md new file mode 100644 index 0000000..a5383bf --- /dev/null +++ b/patches/README.md @@ -0,0 +1,3 @@ +This is where community patches live. They will have the tested commit version and patch. +To make a patch please add author name, date, a description of the patch, and the commit version it applies to. +To add the patch to the repo, please create a pull request for the patch file. @@ -104,6 +104,7 @@ typedef struct { Bool new_win_master; Binding binds[256]; char **should_float[256]; + char **start_fullscreen[256]; char **can_swallow[256]; char **can_be_swallowed[256]; char **scratchpads[32]; diff --git a/src/parser.c b/src/parser.c index 9e82c08..f0cc0d5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -22,7 +22,7 @@ static const CommandEntry call_table[] = {{"close_window", close_focused}, {"focus_prev_mon", focus_prev_mon}, {"increase_gaps", inc_gaps}, {"master_next", move_master_next}, - {"master_previous", move_master_prev}, + {"master_prev", move_master_prev}, {"move_next_mon", move_next_mon}, {"move_prev_mon", move_prev_mon}, {"quit", quit}, @@ -529,6 +529,60 @@ found: } } } + else if (!strcmp(key, "start_fullscreen")) { + char *comment = strchr(rest, '#'); + size_t len = comment ? (size_t)(comment - rest) : strlen(rest); + if (len >= sizeof(line)) { + len = sizeof(line) - 1; + } + + char win[sizeof(line)]; + snprintf(win, sizeof(win), "%.*s", (int)len, rest); + + char *final = strip(win); + char *comma_ptr; + char *comma = strtok_r(final, ",", &comma_ptr); + + int start_fullscreen_idx = 0; + /* find first empty slot */ + for (int i = 0; i < 256; i++) { + if (!cfg->start_fullscreen[i]) { + start_fullscreen_idx = i; + break; + } + } + + /* store each comma separated value in a separate row */ + while (comma && start_fullscreen_idx < 256) { + comma = strip(comma); + if (*comma == '"') { + comma++; + } + char *end = comma + strlen(comma) - 1; + if (*end == '"') { + *end = '\0'; + } + + char *dup = strdup(comma); + if (!dup) { + fprintf(stderr, "sxwmrc:%d: failed to allocate memory\n", lineno); + goto cleanup_file; + } + + cfg->start_fullscreen[start_fullscreen_idx] = malloc(2 * sizeof(char *)); + if (!cfg->start_fullscreen[start_fullscreen_idx]) { + free(dup); + fprintf(stderr, "sxwmrc:%d: failed to allocate memory\n", lineno); + goto cleanup_file; + } + + /* store each program's name in its own row at index 0 */ + cfg->start_fullscreen[start_fullscreen_idx][0] = dup; + cfg->start_fullscreen[start_fullscreen_idx][1] = NULL; + start_fullscreen_idx++; + comma = strtok_r(NULL, ",", &comma_ptr); + } + } else { fprintf(stderr, "sxwmrc:%d: unknown option '%s'\n", lineno, key); } @@ -104,6 +104,7 @@ void update_struts(void); void update_workarea(void); void warp_cursor(Client *c); Bool window_should_float(Window w); +Bool window_should_start_fullscreen(Window w); int xerr(Display *dpy, XErrorEvent *ee); void xev_case(XEvent *xev); #include "config.h" @@ -112,7 +113,6 @@ Atom atom_net_active_window; Atom atom_net_current_desktop; Atom atom_net_supported; Atom atom_net_wm_state; -Atom atom_net_wm_state_fullscreen; Atom atom_wm_window_type; Atom atom_net_wm_window_type_dock; Atom atom_net_workarea; @@ -854,19 +854,6 @@ void hdl_client_msg(XEvent *xev) change_workspace(ws); return; } - if (xev->xclient.message_type == atom_net_wm_state) { - long action = xev->xclient.data.l[0]; - Atom target = xev->xclient.data.l[1]; - if (target == atom_net_wm_state_fullscreen) { - if (action == 1 || action == 2) { - toggle_fullscreen(); - } - else if (action == 0 && focused && focused->fullscreen) { - toggle_fullscreen(); - } - } - return; - } } void hdl_config_ntf(XEvent *xev) @@ -1190,6 +1177,11 @@ void hdl_map_req(XEvent *xev) c->floating = True; } + if (window_should_start_fullscreen(w)) { + c->fullscreen = True; + c->floating = False; + } + /* center floating windows & set border */ if (c->floating && !c->fullscreen) { int w_ = MAX(c->w, 64), h_ = MAX(c->h, 64); @@ -1281,6 +1273,11 @@ void hdl_map_req(XEvent *xev) XMapWindow(dpy, w); c->mapped = True; + if (c->fullscreen) { + int m = c->mon; + XSetWindowBorderWidth(dpy, w, 0); + XMoveResizeWindow(dpy, w, mons[m].x, mons[m].y, mons[m].w, mons[m].h); + } set_frame_extents(w); if (user_config.new_win_focus) { @@ -1540,6 +1537,7 @@ void init_defaults(void) default_config.can_be_swallowed[i] = NULL; default_config.can_swallow[i] = NULL; default_config.open_in_workspace[i] = NULL; + default_config.start_fullscreen[i] = NULL; } default_config.motion_throttle = 60; @@ -1730,9 +1728,8 @@ long parse_col(const char *hex) return WhitePixel(dpy, DefaultScreen(dpy)); } - /* return col.pixel |= 0xff << 24; */ - /* This is a fix for picom making the borders transparent. DANGEROUS */ - return col.pixel; + /* possibly unsafe BUT i dont think it can cause any problems */ + return col.pixel |= 0xff << 24; } void quit(void) @@ -1798,6 +1795,13 @@ void reload_config(void) free(user_config.open_in_workspace[i]); user_config.open_in_workspace[i] = NULL; } + if (user_config.start_fullscreen[i]) { + if (user_config.start_fullscreen[i][0]) { + free(user_config.start_fullscreen[i][0]); + } + free(user_config.start_fullscreen[i]); + user_config.start_fullscreen[i] = NULL; + } } /* free should_float arrays */ @@ -2062,9 +2066,7 @@ void setup_atoms(void) atom_net_wm_window_type_dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); atom_net_workarea = XInternAtom(dpy, "_NET_WORKAREA", False); atom_net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False); - atom_net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); atom_net_wm_state = XInternAtom(dpy, "_NET_WM_STATE", False); - atom_net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); atom_net_supporting_wm_check = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); atom_net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", False); @@ -2078,7 +2080,6 @@ void setup_atoms(void) atom_net_active_window, atom_net_supported, atom_net_wm_state, - atom_net_wm_state_fullscreen, atom_wm_window_type, atom_net_wm_window_type_dock, atom_net_workarea, @@ -2711,6 +2712,29 @@ void warp_cursor(Client *c) XSync(dpy, False); } +Bool window_should_start_fullscreen(Window w) +{ + XClassHint ch; + if (XGetClassHint(dpy, w, &ch)) { + for (int i = 0; i < 256; i++) { + if (!user_config.start_fullscreen[i] || !user_config.start_fullscreen[i][0]) { + break; + } + + if ((ch.res_class && !strcmp(ch.res_class, user_config.start_fullscreen[i][0])) || + (ch.res_name && !strcmp(ch.res_name, user_config.start_fullscreen[i][0]))) { + XFree(ch.res_class); + XFree(ch.res_name); + return True; + } + } + XFree(ch.res_class); + XFree(ch.res_name); + } + + return False; +} + int xerr(Display *dpy, XErrorEvent *ee) { /* ignore noise & non fatal errors */ @@ -90,7 +90,11 @@ Target updates per second for mouse drag operations (move, resize, swap). Defaul .TP .B should_float -Lets you change which windows should float by default when opening them. Multiple entries should be comma-separated. Optionally, entries can be enclosed in quotes. Default is "st". +Lets you change which windows should float by default when opening them. Multiple entries should be comma-separated. Optionally, entries can be enclosed in quotes. Default is "pcmanfm", "obs". + +.TP +.B start_fullscreen +Lets you specify which windows should start in fullscreen mode. Multiple entries should be comma-separated. Optionally, entries can be enclosed in quotes. Default is "mpv", "vlc". .TP .B new_win_focus |
