Skip to content

Commit cdbc229

Browse files
committed
Support Wayland output resizing
1 parent 5e0d014 commit cdbc229

5 files changed

Lines changed: 56 additions & 3 deletions

File tree

server/internal/config/desktop.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import (
1313
)
1414

1515
type Desktop struct {
16-
Display string
17-
Wayland bool
16+
Display string
17+
Wayland bool
18+
WaylandOutput string
19+
WaylandResizeCommand string
1820

1921
ScreenSize types.ScreenSize
2022

@@ -37,6 +39,16 @@ func (Desktop) Init(cmd *cobra.Command) error {
3739
return err
3840
}
3941

42+
cmd.PersistentFlags().String("desktop.wayland.output", "HEADLESS-1", "Wayland output name used for resizing")
43+
if err := viper.BindPFlag("desktop.wayland.output", cmd.PersistentFlags().Lookup("desktop.wayland.output")); err != nil {
44+
return err
45+
}
46+
47+
cmd.PersistentFlags().String("desktop.wayland.resize_command", "wlr-randr", "Wayland output resize executable")
48+
if err := viper.BindPFlag("desktop.wayland.resize_command", cmd.PersistentFlags().Lookup("desktop.wayland.resize_command")); err != nil {
49+
return err
50+
}
51+
4052
cmd.PersistentFlags().String("desktop.screen", "1280x720@30", "default screen size and framerate")
4153
if err := viper.BindPFlag("desktop.screen", cmd.PersistentFlags().Lookup("desktop.screen")); err != nil {
4254
return err
@@ -82,6 +94,8 @@ func (Desktop) InitV2(cmd *cobra.Command) error {
8294
func (s *Desktop) Set() {
8395
s.Display = viper.GetString("desktop.display")
8496
s.Wayland = viper.GetBool("desktop.wayland")
97+
s.WaylandOutput = viper.GetString("desktop.wayland.output")
98+
s.WaylandResizeCommand = viper.GetString("desktop.wayland.resize_command")
8599

86100
// Display is provided by env variable unless explicitly set
87101
if s.Display == "" {

server/internal/desktop/wayland.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ func (input *waylandInput) sync() error {
169169
return input.emit(evSyn, 0, 0)
170170
}
171171

172+
func (input *waylandInput) position() (int, int) {
173+
input.mu.Lock()
174+
defer input.mu.Unlock()
175+
return input.cursorX, input.cursorY
176+
}
177+
172178
func (input *waylandInput) move(x, y int) error {
173179
input.mu.Lock()
174180
defer input.mu.Unlock()

server/internal/desktop/xorg.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package desktop
22

33
import (
4+
"fmt"
45
"image"
56
"os/exec"
67
"regexp"
@@ -22,7 +23,7 @@ func (manager *DesktopManagerCtx) Move(x, y int) {
2223

2324
func (manager *DesktopManagerCtx) GetCursorPosition() (int, int) {
2425
if manager.waylandInput != nil {
25-
return manager.waylandInput.cursorX, manager.waylandInput.cursorY
26+
return manager.waylandInput.position()
2627
}
2728
return xorg.GetCursorPosition()
2829
}
@@ -153,6 +154,14 @@ func (manager *DesktopManagerCtx) ScreenConfigurations() []types.ScreenSize {
153154

154155
func (manager *DesktopManagerCtx) SetScreenSize(screenSize types.ScreenSize) (types.ScreenSize, error) {
155156
if manager.waylandInput != nil {
157+
if manager.config.WaylandResizeCommand == "" || manager.config.WaylandOutput == "" {
158+
return manager.screenSize, fmt.Errorf("Wayland output resize is not configured")
159+
}
160+
resize := fmt.Sprintf("%dx%d", screenSize.Width, screenSize.Height)
161+
if err := exec.Command(manager.config.WaylandResizeCommand, "--output", manager.config.WaylandOutput, "--mode", resize).Run(); err != nil {
162+
return manager.screenSize, fmt.Errorf("resize Wayland output: %w", err)
163+
}
164+
156165
input, err := newWaylandInput(screenSize.Width, screenSize.Height)
157166
if err != nil {
158167
return manager.screenSize, err

webpage/docs/configuration/desktop.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ Neko uses the [X Server](https://www.x.org/archive/X11R7.6/doc/man/man1/Xserver.
1515
<ConfigurationTab options={configOptions} filter={[
1616
'desktop.display',
1717
'desktop.wayland',
18+
'desktop.wayland.output',
19+
'desktop.wayland.resize_command',
1820
'desktop.screen'
1921
]} comments={false} />
2022

2123
- <Def id="display" /> refers to the X server that is running on the system. If it is not specified, the environment variable `DISPLAY` is used. The same display is referred to in the [Capture](capture#video.display) configuration to capture the screen. In most cases, we want to use the same display for both.
2224
- <Def id="wayland" /> disables X11 desktop initialization and injects pointer and keyboard events through a `/dev/uinput` virtual device. The container must have access to `/dev/uinput`; the compositor must accept libinput devices.
25+
- <Def id="wayland.output" /> is the compositor output name passed to the resize command. The default `HEADLESS-1` matches the wlroots headless backend.
26+
- <Def id="wayland.resize_command" /> is the executable used to resize the output. It must accept `--output <name> --mode <width>x<height>`, as `wlr-randr` does.
2327
- <Def id="screen" /> refers to the screen resolution and refresh rate. The format is `<width>x<height>@<refresh rate>`. If not specified, the default is `1280x720@30`.
2428

2529
:::tip

webpage/docs/configuration/help.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,26 @@
269269
"defaultValue": false,
270270
"description": "use Wayland desktop input and screen management"
271271
},
272+
{
273+
"key": [
274+
"desktop",
275+
"wayland",
276+
"output"
277+
],
278+
"type": "string",
279+
"defaultValue": "HEADLESS-1",
280+
"description": "Wayland output name used for resizing"
281+
},
282+
{
283+
"key": [
284+
"desktop",
285+
"wayland",
286+
"resize_command"
287+
],
288+
"type": "string",
289+
"defaultValue": "wlr-randr",
290+
"description": "Wayland output resize executable"
291+
},
272292
{
273293
"key": [
274294
"desktop",

0 commit comments

Comments
 (0)