Commit graph

22 commits

Author SHA1 Message Date
Ben Buhse
f349733051
Set bar.pending_manage.output_geometry to true on creation
Without this, if you had a config with no bar, added the bar, then
reloaded the config, its geometry would never be created because of the
early return in Bar.manage(), so nothing would ever get drawn.
2026-02-26 16:40:15 -06:00
Ben Buhse
a9473204ad
Convert Bar to use river-shell-surface
I want to implement more functionality to the bar, similar to what
machi has in its bar, but it seems a lot easier to just handle the bar
with the rest of the manage/render loop that rwm and beansprout use.

To do that, I had to convert the bar to use river-shell-surface instead
of zwlr-layer-shell.

In that process, I also removed support for zwlr-layer-shell exclusive
zones. It made calculating the usable area for the layout more annoying.
If someone *really* wants, I would consider adding it back, but the only
thing I can think of that requires exclusive area is a bar, and we don't
really support other bars, so I don't think it's needed.

I also switched a couple of places to use saturating subtraction on
unsigned ints.
2026-02-26 16:34:48 -06:00
Ben Buhse
b921751100
Implement single_window_ratio
This is a new config option that allows the user to set the width ratio
when only a single window is tiled and visible. The main idea is that,
on ultrawides, a single window taking the full width could be ugly.
With this new config, you can make the window take a smaller width.

I also renamed consts to snake_case instead of SCREAMING_CASE and fixed
a bug where the default primary_count and primary_ratio weren't updated
on config reload.
2026-02-25 13:51:39 -06:00
Ben Buhse
8e6c28da7b
Fix some memory leaks 2026-02-22 17:38:28 -06:00
Ben Buhse
7045b21534
Handle {exit_}fullscreen_requested events on Windows 2026-02-19 13:56:37 -06:00
Ben Buhse
9b0bac12ff
Fix text scaling in Bar
Before, we were missing the initial events from the wl_output, including
the scale. This meant that we weren't scaling the bar clock correctly.
To fix it, we just moved the wl_global binding into the .wl_output event

We also got rid of the hashmap of outputs in Globals and Context.
2026-02-16 19:09:33 -06:00
Ben Buhse
5922107579
Implement configuration for the Bar
This adds a few new options for the bar (instead of hardcoding all of
them). fonts, text_color, background_color, positoon, and margins.

Also fixed a couple of bugs when reloading the config and destroying
layer shell and wl surfaces in the wrong order.
2026-02-16 16:07:02 -06:00
Ben Buhse
dbf32e793c
Finish wiring up the TagOverlay
We had to fix a couple of compile errors that weren't showing while it
wasn't wired up (since I never just tried to compile TagOverlay.zig on
its own). We also changed the lifecycle to re-create/destroy the surface
to show/hide it, similar to the way that river-tag-overlay actually did
it.

Finally, I added @branchHint(.cold) to a few places in the event loop
where, if we're in the branch, the wm is definitely exiting, so it's
fine if they're cold (should almost never happen).
2026-02-16 11:33:48 -06:00
Ben Buhse
43ebdd273c
Refactor Bar/Output surfaces into anon struct
Both the wl_surface and layer_surface in each are always expected to
exist at the same time. Since they're optional, it makes more sense to
combine them into a single optional struct.
2026-02-15 18:02:48 -06:00
Ben Buhse
bcc0e9705e
Move Bar.inits() env into Context
Since each bar has its own, it's easier to just share it. This does
create a consistent slight overhead, but may be useful anyways if we
care about the Env more further down the line.
2026-02-15 17:20:59 -06:00
Ben Buhse
5c427234d7
Add layer shell support and fix floating windows
Now, I actually save the river-layer-shell-v1 and keep track of the
non-exclusive area. The layout calculation uses the usable area instead
of the entire output's geometry.

I removed boundary clamping for the floating windows because it was a
bit janky when hitting the edges. I'll probably add it back at some
point. I also made windows default to 75% of the usable area instead of
keeping their tiled size so that maximized windows look decent when
floating for the first time. Finally, since I removed the clamping, I
added a center_float keybind to center a floating window. If you're
cycling through focused windows and one isn't on the screen, you can use
the center_float bind to get the window visible again.

Replaced all divTrunc with divFloor to be consistent. I think they
should all be positive, anyways, so they'd be the same, but I like just
having one.
2026-02-14 11:30:37 -06:00
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
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
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
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
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
4157dd67f6
Fix use-after-free by moving config-reload into the manage cycle 2026-01-31 14:08:46 -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
30231f1149
Refactor initialization and Context struct
I tried to make it a little bit easier to follow and get rid of the
need to call back to context.x.y.z (as much) [I hope]
2026-01-24 17:48:01 -06:00