Commit graph

143 commits

Author SHA1 Message Date
Ben Buhse
efd0222899
Add window title and wm info to Bar
This commit adds the focused window title to the left side of the bar
and some WM info (primary count/ratio and # of visible/total windows) to
the right side.

It also adds new vertical_padding and horizontal_padding config options
for the bar.
2026-02-27 11:02:42 -06:00
Ben Buhse
062748967c
Move Utf-8 -> codepoint conversion to utils
Once we add more text to the bar, it makes sense to move this into a
helper function.
2026-02-26 17:29:22 -06:00
Ben Buhse
98d15e3773
build: use type inference for manifest import 2026-02-26 17:26:52 -06:00
Ben Buhse
f00c8dbc37 Merge pull request 'Convert Bar to use river shell surface' (#1) from new-bar into main
Reviewed-on: https://codeberg.org/beansprout/beansprout/pulls/1
2026-02-26 23:56:56 +01:00
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
2be1a1af18
Fix building docs from emerge
This is equivalent to the scdoc patch in the river ebuild
2026-02-25 16:25:26 -06:00
Ben Buhse
bc370573a8
Return an error if b.findProgram errors instead of just skipping 2026-02-25 16:12:44 -06:00
Ben Buhse
09f43674b5
Add man pages
beansprout(1) is basically just the README and beansprout(5) is basically
just docs/CONFIGURATION.md.

By default, the man pages are generated if scdoc is availabled, but they
can also be explicitly disabled with -Dman-pages.
2026-02-25 16:02:58 -06:00
Ben Buhse
164ae9a7ab
Implement left-side primary
This adds a new config `primary_side` that can be either `left` or `right`
and determines whether the primary stack is on the left or the right
side of the screen.
2026-02-25 15:16: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
07794019dc
Move old TODO comments to docs/TODO.md 2026-02-24 16:40:58 -06:00
Ben Buhse
bf5ee081d6
Add support for handling quotes in spawn args
The spawn keybind takes a command to launch with `std.process.Child.init`
but we weren't handling quotes in the arguments. We had to add special
tokenization to respect quotes.
2026-02-23 19:09:17 -06:00
Ben Buhse
8b5681a26f
Fix a de-init that I missed in 9fef3f70 2026-02-23 18:57:41 -06:00
Ben Buhse
0bb891a18b
Merge branch 'image-better' 2026-02-22 18:19:34 -06:00
Ben Buhse
006bae3532
Remove manual pixel conversion in WallpaperImage
I used to manually convert pixels from RGBA=>ARGB because Wayland
compositors are only guaranteed to support XRGB and ARGB, but zigimg
doesn't include either of those. This was a bit slow, especially on
debug builds (though not *super* noticeable on release builds).

I realized, though, that zigimg's Rgba32 format is the same as pixman's
a8b8g8r8... on little-endian. I kept the old code just in case someone
out there happens to be running beansprout on MIPS, but I have not
tested it.
2026-02-22 18:15:04 -06:00
Ben Buhse
4c58a3d842
Fix a number of typos in comments 2026-02-22 18:01:57 -06:00
Ben Buhse
b9d13583ab
Fix a number of typos in comments 2026-02-22 17:51:17 -06:00
Ben Buhse
8e6c28da7b
Fix some memory leaks 2026-02-22 17:38:28 -06:00
Ben Buhse
9fef3f70f5
Add XkbBinding.deinit()
Also fixed a crash if two non-spawn keybinds had the same keys
2026-02-22 14:57:41 -06:00
Ben Buhse
1b37ab7afd
Implement passthrough mode
When active, key presses are passed directly to the focused window.
I've mostly used this for testing beansprout, but I'm sure there are
other uses.
2026-02-22 08:59:45 -06:00
Ben Buhse
5f4d80f313
Fix sendTo{Prev,Next}Output commands
Before, they would try send the window to the "next" output even if
there was only one output... which really just means sending the window
to the bottom of the stack. Instead, they should be a noop.

Also fixed a bug when removing all outputs where the seat wouldn't
clear its focused output.
2026-02-19 14:01:51 -06:00
Ben Buhse
7045b21534
Handle {exit_}fullscreen_requested events on Windows 2026-02-19 13:56:37 -06:00
Ben Buhse
de55f0c6ee
Move orphan window handling into wm.manage()
This just helps consolidate it into a single place
2026-02-18 17:12:51 -06:00
Ben Buhse
507b16521d Merge pull request 'Implement window rules' (#14) from window-rules into main
Reviewed-on: https://codeberg.org/bwbuhse/beansprout/pulls/14
2026-02-18 23:22:56 +01:00
Ben Buhse
5ca0b9d157
Add documentation and example for window rules 2026-02-18 16:13:16 -06:00
Ben Buhse
76f292332b
Fix floating window initial sizes
When I added support for propose dimensions, I was foolishly just
choosing the min (or max) if only one was set. However, a lot of windows
will a set a very small min size with no max, which meant we would have
really tiny windows when first floating one. The fix was to try set to
75% but then clamp to the min/max dimensions the window gave.

After fixing that, there was still an issue where windows kept their
size after being floated. That's because there was a propose_dimensions
call happening later in Window.manage(). I'm skipping that now if a
window became floating in the same manage event.
2026-02-18 16:06:09 -06:00
Ben Buhse
3a7975eb1f
Fix a memory leak during window.close
We weren't actually destroying the window or removing its link if the
window was closed while it didn't have an output.
2026-02-18 15:46:35 -06:00
Ben Buhse
dc1e38e737
Support river_window_v1.dimensions_hint
This is currently only used when floating a window for the first time.
If the window has preferred dimensions, we will use those isntead of the
75% of the screen size rule we were using before.
2026-02-18 15:39:58 -06:00
Ben Buhse
08be768d99
Fix two crashes
One was where WM was assuming that a seat existed during first manage,
but that's not always true, so we have to check that before running the
initialization code. I also split that off into its own function like in
Window.

The other crash was when trying to calculate the layout with the
output's width and/or height equal to zero, it would crash subtracting
the border width.

I discovered both of these when try to restart beansprout without
restarting River.
2026-02-18 15:35:14 -06:00
Ben Buhse
6f68850a70
Fix crash when windows arrive before seat/output
I found this when trying to restart beansprout after a separate crash.

Basically, the .window handler used to put new
windows on seat.focused_output for new windows,
but after a restart this is still null even when
an output (and windows) already exist.
Windows became orphans with output=null, breaking
the focused_window.output == focused_output assert
2026-02-17 20:44:32 -06:00
Ben Buhse
433e377237
Rename calculatePrimaryStackLayout
It's the only layout, so just rename to calculateLayout()
2026-02-17 16:55:35 -06:00
Ben Buhse
c4da4ef30a
Make window rules frame perfect
This moves window initialization earlier in the manage sequence.
Previously, it was on the Window's first manage() call, but this is
after the layout has already been calculated, which matters both because
of tags and whether the window starts floating or not.

Now, initialization is handled in a separate function that gets called
in Output.calculatePrimaryStackLayout() instead.
2026-02-17 16:54:14 -06:00
Ben Buhse
6b8350e7b6
Create initial window rules set up
At least tag rules seem to be working (but they're not frame perfect).

I might need to investigate more for float/no_float.

Rules are ANDed and only apply during window's first manage sequence,
so changing an appid/title doesn't affect anything.
2026-02-17 16:26:18 -06:00
Ben Buhse
11cef4b2f8
Update log scopes in the various config/ files 2026-02-17 16:23:19 -06:00
Ben Buhse
b4c4019cad
Rename config files
Switch to file-as-struct for the ones that are just the configs structs
and use singular for the ones that are just parsers
2026-02-17 12:53:15 -06:00
Ben Buhse
03fd4d0087
Make focus follow window when using swapWindow 2026-02-17 11:32:04 -06:00
Ben Buhse
5824f84c35
Fix zoom keybind bugs
There were two bugs:
1) If we were focused on the first window and then tried to use the
   zoom keybind, we looked for the next tiled window in the list
   (correctly skipping floating windows), but we didn't also check the
   tags. This meant that if the next window was on a non-visible tag,
   it didn't work.
2) After fixing that, we weren't updating the focus to the newly
   promoted window, so the border would flash around the window that got
   moved to 2nd for a frame. We just needed to update the pending focus
   window for seat if we had to swap windows.
2026-02-17 11:20:43 -06:00
Ben Buhse
bc04072e9d
Split up logging in LibinputDevice 2026-02-17 09:28:38 -06:00
Ben Buhse
4c0117724e
Make Config.keybinds into a hash map
This helps us with de-duplication. Previously, if you had host-specific
keybinds on the same key combination, the compositor would choose the
first... which is the opposite of how everything else in our config
handling works.
2026-02-16 19:44:05 -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
a37f72f0d7
Apply Rect to Buffer.borderedRectangle
Also set it to have all fields with a default of 0 since we use that
quite a bit and it saves writing it.
2026-02-16 17:32:46 -06:00
Ben Buhse
515e94320b
Apply Rect to Output 2026-02-16 17:27:31 -06:00
Ben Buhse
5333b4cbe0
Create utils.Rect struct for geometries
Also fixed a crash that I'm really not sure how I didn't have happen
before during Output.create()

Right now, only Window is updated to use Rect. I'll try updating all
instances of x,y,width,height combo to use it.
2026-02-16 17:16:25 -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
ce9a972b60
Create config/input.zig
This mvoes all of the input {} block parsing into its own file
2026-02-16 14:05:42 -06:00
Ben Buhse
fc0482902e
Create config/pointer_binds.zig
This moves all of the pointer_binds {} block parsing into its own file
2026-02-16 14:05:42 -06:00
Ben Buhse
5d61663220
Create config/keybinds.zig
This moves all of the keybinds {} block parsing into its own file
2026-02-16 14:05:42 -06:00
Ben Buhse
ef5b4369a6
Create config/tag_overlay.zig
This moves all over the tag_overlay {} block parsing into its own file
2026-02-16 14:05:39 -06:00
Ben Buhse
83f8d00081
Create config/borders.zig
This moves all of the borders {} block parsing into its own file
2026-02-16 13:25:41 -06:00