Commit graph

174 commits

Author SHA1 Message Date
Ben Buhse
95425aa73f
Rename utils.allocator to utils.gpa
it seems like `gpa` has become pretty much the universally agreed upon
name for your... gpa, so we're renaming.
2026-02-12 14:10:28 -06:00
Ben Buhse
1df6820b1d
Implement per-tag primary_count and primary_ratio
By default, each tag mask will use the default count and ratio. If the
mask gets modified by any of the commands, it gets added to a hash map.
When changing tag masks, the current count and ratio are stored, and
they're used again later if you switch back to that mask.

This commit also adds primary_count and primary_ratio to the general
settings for the config, so users can set a default count/ratio to use.
2026-02-12 14:10:21 -06:00
Ben Buhse
8e93395360
Update README.md, add docs/CONFIGURATION.md
I've finally added a somewhat usable README and also explained
configuration in docs/CONFIGURATION.md
2026-02-11 20:22:41 -06:00
Ben Buhse
0970702263
Add some unit tests for a few functions
Mostly only testing the easily-testable helpers in utils and Config
2026-02-11 16:14:29 -06:00
Ben Buhse
3ceaf8a004
Move TODOs into separate file, update README
I still have lots to do for the README, but I'll do that once I actually
am able to daily-drive beansprout.
2026-02-11 15:15:48 -06:00
Ben Buhse
bb612c273e
Add REUSE licensing for non-code files
CC-BY-4.0 for documentation, CC0-1.0 for examples and .gitignore,
HPND for wlr-layer-shell protocol.

Also switch to GPL-3.0-only
2026-02-11 14:50:04 -06:00
Ben Buhse
604bf52150
Fix comment in README.md 2026-02-11 14:14:42 -06:00
Ben Buhse
bd74682096
Update input config to use "name=" property
This is to match behavior with how the new per-host configuration works
2026-02-11 14:12:23 -06:00
Ben Buhse
0b7e15d7ed
Add support for per-host user configuration
This uses KDL properties, i.e. "host=<hostname>" and can be applied to
any config type. An example is includes in examples/config.kdl.

```kdl
    wallpaper_image_path "~/Pictures/desktop.png" host="desktop"
    wallpaper_image_path "~/Pictures/laptop.png" host="laptop"
```
2026-02-11 13:59:37 -06:00
Ben Buhse
e29c4d01e1
Add support for 'None' modifier for keybinds
This is mostly useful for media and brightness keys, but could be used
for other stuff, too.
2026-02-11 13:01:12 -06:00
Ben Buhse
7f571da187 Merge pull request 'Implement input configuration' (#11) from input-config into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/11
2026-02-11 19:39:55 +01:00
Ben Buhse
6d62a7175d
Fix possible race in LibinputDevice.manage()
Only clear should_manage once the device is fully initialized (has an
associated input_device with a name). Previously, should_manage was
cleared unconditionally, so if manage_start fired before the device was
fully linked, configs would never be applied.
2026-02-11 12:30:35 -06:00
Ben Buhse
296f875993
Implement libinput device configuration
We need to defer config application to the first manage_start event
using a should_manage flag so that all *_support events have arrived
before we try applying the configs

This commit also has two other fixes
- fixes a potential use-after-free by telling InputDevice when a
 LibinputDevice is .removed.
- fix logFn (removed "if (scope != .default) return;")

I used kwm to help figure out the manage pattern for the input config.
Link to kwm: https://github.com/kewuaa/kwm
2026-02-10 20:06:17 -06:00
Ben Buhse
3ce98712df
Update zig-kdl
This uses the latest commit that includes my fix for integer underflow
and includes a license (MPL).
2026-02-09 16:46:12 -06:00
Ben Buhse
f84defc8e9
Add input configuration to Config
It's a new node "input" that, if taking a name, includes the specific
input device the block should apply to. If no name is supplied,
the block applies to all inputs. Order matters and later config blocks
can override previous ones.

The config isn't actually used yet.
2026-02-09 16:45:55 -06:00
Ben Buhse
72c1f33c28
Implement river-input-management-v1 and river-libinput-config-v1
Right now, the support is still incomplete (no way to set config) but
we get the devices and set them up and handle current/support events
for the river_libinput_device_v1 devices.
2026-02-09 12:55:47 -06:00
Ben Buhse
ec7474c9af
Implement some simple flags and runtime log-levels
I used flags.zig from Isaac Freund for parsing basic CLI arguments,
I don't need much else since most configuration is in Kdl.
e967499fb1/common/flags.zig

I also removed some of the duplicated bits for the exe_check step
since I realized I can just use the beansprout executable for all of it.
2026-02-08 16:25:30 -06:00
Ben Buhse
54421ef8f5
Fix Output.prevWindow/nextWindow
Before, they were ignoring tags, so you could cycle to windows on
other tags instead of only the same tag.
2026-02-08 15:49:05 -06:00
Ben Buhse
4d379a272c
Change many "orelse return" sections to log.err
Beansprout will still continue gracefully, but I added handling so that
they'll log errors so we should have some record of something beind
wrong.
2026-02-08 15:11:03 -06:00
Ben Buhse
6dec98ae09 Merge pull request 'Implement wallpapers for outputs' (#10) from wallpaper into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/10
2026-02-08 18:07:59 +01:00
Ben Buhse
225ddf0a53
Fix buffer pool race condition, pixman transform, and pixel conversion
Mark reused buffers as busy before returning from nextBuffer (before,
they only got marked busy on init).

Re-attach wl_buffer listener after re-initializing a buffer. This lets
the re-inited buffer still get a released event.

Combine scale and translate matrices with multiply instead of overwriting

Use appendAssumeCapacity for pixel conversion loop (since we already
initialized the list with the correct size).
2026-02-08 10:51:33 -06:00
Ben Buhse
3c16929a6a
Complete wallpaper support with new config
Load wallpaper_image_path from config with tilde expansion (environment
variables are not supported)

On the way for this commit, I also had to:
- Fix wallpaper not rendering on startup by triggering init from
the .wl_output handler, since wl_output.done is lost during the
initial roundtrip
- Re-render wallpapers on config reload when the path changes
- Fix crash in deinitWallpaperLayerSurface when wl_surface is null
2026-02-07 19:11:10 -06:00
Ben Buhse
00835cea08
Fix crash when wallpaper_image_path is missing
This makes the WM run fine even if wallpaper_image fails to load for any
other reason. Right now, it's still just a black background. At some
point, I plan to add the ability to also just set a color as a
background but that's a fairly low priority.
2026-02-07 17:56:05 -06:00
Ben Buhse
e186a2d017
Implement wallpaper rendering with multi-output support
This actually renders a wallpaper for each output using the newly added
Buffer and BufferPool for shared-memory surfaces and creates a
wlr-layer-shell surface per output. Right now, each wallpaper
shares the same wallpaper (though scaled to each).

wl_output globals get added to a HashMap that is used by Output when it
gets an output event.

Fix null-safety in WindowManager when no seats/outputs exist and route
Window dimensions through pending_manage.
2026-02-07 17:27:24 -06:00
Ben Buhse
fb8817ebf9
Begin work to add wallpaper support to beansprout
Added pixman and zigimg dependencies
Set up in build.zig, added to both exe and exe_check

Add new protocols:
     river-layer-shell-v1
     wlr-layer-shell-unstable-v1
     xdg-shell (dep of wlr-layer-shell-unstable-v1)

Update Context.zig to hold wl_output, wl_shm, and a WallpaperImage
Also re-ordered all of its fields into alphabetical order
Context.create() now takes a Context.Options struct so that it takes
     one arg instead of many smaller args.

Added new WallpaperImage.zig, but it's not yet actually used
2026-02-06 16:37:33 -06:00
Ben Buhse
e5d439e27d Merge pull request 'floating-windows' (#9) from floating-windows into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/9
2026-02-06 21:39:50 +01:00
Ben Buhse
07fbe91c13
Implement floating windows with pointer and keyboard controls
Add interactive move/resize operations using configurable pointer bindings
(Mod4+BTN_LEFT to move, Mod4+BTN_RIGHT to resize). Tiled windows
automatically float when dragged or resized.

Add keyboard commands for floating windows:
- move_up/down/left/right: move by pixel amount
- resize_width/height: resize by pixel amount
- swap_next/swap_prev: swap position in window stack

Fix float dimension initialization when windows first become floating,
and fix clamp crash when resizing windows larger than output bounds.

Update example config with documented keybinds and new pointer_binds block.
2026-02-06 14:36:12 -06:00
Ben Buhse
6d4352a217
Implement floating windows
As of this commit, there's not-yet a way to resize or move floating
windows, but it's possible to create one and focus through all windows.

Floating windows are always above tiled windows and, if floating window
is focused, that window is always above any another floating windows.

Windows have a separate float_{x, y, width, height} to remember their
floating location if they go from float=>tiled=>float again.
2026-02-05 17:14:46 -06:00
Ben Buhse
fba4a3d087 Merge pull request 'Implement changeable primary count' (#8) from primary-count into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/8
2026-02-04 22:49:39 +01:00
Ben Buhse
5ff05ab09e
Implement changeable primary count
There are new increment_primary_count and decrement_primary_count config options
2026-02-04 15:43:30 -06:00
Ben Buhse
26949d7b8a Merge pull request 'Add multi-output support' (#7) from multi-output-support into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/7
2026-02-04 03:12:41 +01:00
Ben Buhse
0f85278aea
Add multi-output support
Primary ratio is per-output.

If an output is disconnected/disabled, its windows get sent to the
previous output in the output list. If all outputs are disconnected,
windows are added to an orphan list in the WM. Once an output is
re-added, the orphans are all given to that output.

When a window is sent to a new output, it keeps the same tags as it
had before. I may add an option to take the new output's tags.

- Rename focus_next/focus_prev to focus_next_window/focus_prev_window
- Add focus_next_output/focus_prev_output
- Add send_to_next_output/send_to_prev_output commands to move windows
    between outputs

Split Seat.PendingManage.PendingFocus into separate pending output
and pending window structs

Fix window outputs when closing outputs
2026-02-03 20:10:33 -06:00
Ben Buhse
342c0fdf8f Merge pull request 'Add support for reloading config' (#6) from config-reload into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/6
2026-01-31 21:38:10 +01:00
Ben Buhse
4157dd67f6
Fix use-after-free by moving config-reload into the manage cycle 2026-01-31 14:08:46 -06:00
Ben Buhse
cd32463d52
Add a keybind to reload config; still needs more testing 2026-01-31 10:47:20 -06:00
Ben Buhse
365c000b6e
Add change_ratio keybind 2026-01-30 21:47:16 -06:00
Ben Buhse
4e02a07bf1
Implement zoom keybind 2026-01-30 21:09:02 -06:00
Ben Buhse
8ffbc3dbd1 Merge pull request 'Implement config' (#5) from config into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/5
2026-01-31 03:35:01 +01:00
Ben Buhse
fd8b6d0d41
Implement configuration for keybindings
Keybinds go in a "keybinds" block and follow the format

<command> <modifiers> <keysym> <options>

But there's also a special "tag_bind" command that just takes modifiers
and one of set_output_tags, set_window_tags, toggle_output_tags, and
toggle_window_tags. It will automatically be used to loop through the
1-9 keys on tags 1<<0 to 1<<9, however, you can still implement those
commands individually if you want.
2026-01-30 20:33:16 -06:00
Ben Buhse
9b524b810d
Add helper functions for logging in Config.zig
logWarnInvalidNodeArg() can be used for when a node has an invalid type
for its argument.

logDebugSettingNode() prints the configuration name and the value being
set.
2026-01-27 18:37:15 -06:00
Ben Buhse
676ca40891
Actually use focus_follows_pointer and pointer_warp_on_focus_change 2026-01-27 15:30:30 -06:00
Ben Buhse
c4d2c40f1a
Fix Config.skipChildBlock()
Before, there would be issues for nested child blocks
2026-01-27 15:13:02 -06:00
Ben Buhse
43e3d268c9
Implement initial config loading
Config goes in $XDG_CONFIG_HOME/beansprout/config.kdl or
$HOME/.config/beansprout/config.kdl

Config is in the kdl format. Right now, the supported options are

```zig
/// Width of window borders in pixels
border_width: u8 = 2,
/// Color of focused window's border in 0xRRGGBBAA or 0xRRGGBB form
border_color_focused: RiverColor = utils.parseRgbaComptime("0x89b4fa"),
/// Color of uffocused windows' borders in 0xRRGGBBAA or 0xRRGGBB form
border_color_unfocused: RiverColor = utils.parseRgbaComptime("0x1e1e2e"),

/// Where a new window should attach, top or bottom of the stack
attach_mode: AttachMode = .top,
/// Should focus change when the cursor moves onto a new window
focus_follows_pointer: bool = true,
/// Should the pointer warp to the center of newly-focused windows
pointer_warp_on_focus_change: bool = true,
```

I plan to add Keybinds shortly. If parsing the configuration fails,
the default config will be used and the WM will continue loading.
2026-01-27 14:54:27 -06:00
Ben Buhse
726d346015 Merge pull request 'Implement tags' (#4) from tag-implementation into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/4
2026-01-27 03:02:28 +01:00
Ben Buhse
9030de6b64
Get tags working with actual tag-switching support
I added 7 new Commands to XkbKeybinds.Commands, though 3 of them don't
work yet.

The new commands that *work* are

+    set_output_tags: u32,
+    set_window_tags: u32,
+    toggle_output_tags: u32,
+    toggle_window_tags: u32,

They each take a 32-bit value as a bitmask to set (or toggle) tags.

The 3 unimplemented commands are

+    spawn_tagmask: u32,
+    focus_previous_tags,
+    send_to_previous_tags,

and they will all panic if they're used.

For now, default keybinds are hardcoded as part of WindowManager's
initializing in the first \`manage_start\` event. Multi-output support
is not added yet, so this will still all happen on a single Output.
2026-01-26 17:44:34 -06:00
Ben Buhse
b8d31de3ef
Start adding tags
Right now, essentially nothing has changed, there is still no multi-
output support and not even a way to change/set/toggle/view/etc. tags.

However, tags *are* implemented at a core level. Next step is to add
keybinds for the various tag actions.

After that, I will work on multi-output support.
2026-01-26 15:04:41 -06:00
Ben Buhse
87ec2d4f60
Working on refactoring inits 2026-01-26 13:10:51 -06:00
Ben Buhse
67eef42bd8 Merge pull request 'Clean up some code, implement pointer-warp-on-focus-change, fix a crash' (#3) from pointer-warp-on-focus-change into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/3
2026-01-26 04:00:57 +01:00
Ben Buhse
e1a0b89ced
Standardize panic messages and clean up code 2026-01-25 20:57:05 -06:00
Ben Buhse
c953fe3d68
Fix pointer warp for new and closed windows 2026-01-25 13:26:57 -06:00