Skip to content

ryo-zen/oxyshift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oxyshift

Dynamic Wayland display and wallpaper manager

oxyshift is Wayland display manager that automatically switches display profiles based on connected monitors and manages wallpaper state across sleep/wake cycles.

oxyshift has not been tested with a range of monitors or laptops so it might still be buggy on diffrent systems. I just developed it to help me solve an persistent wallpaper issue with swww.

Tested only in Arch and Hyprland.

Features

  • Automatic Display Configuration: Detects connected displays and applies matching profiles
  • Unified Wallpaper Management: Integrated swww support with persistent wallpaper state
  • TOML Configuration: Modern, readable configuration format
  • Hot Reload: Automatically reloads configuration when changed
  • Memory Safe: Written in Rust for reliability and performance
  • Async Design: Non-blocking event handling with Tokio
  • Quickshell Integration: Shares wallpaper state with quickshell settings

What Makes oxyshift Unique?

Unlike other display managers (kanshi, shikane, way-displays), oxyshift provides unified wallpaper + display management:

  • Wallpaper changes through quickshell settings persist across sleep/wake cycles
  • Shared state file (~/.local/state/quickshell/user/current-wallpaper) synchronized between components
  • Profile wallpapers respect user selections instead of overriding them
  • Automatic wallpaper restoration when displays reconnect

Installation

From Source

git clone https://github.com/yourusername/oxyshift.git
cd oxyshift
cargo build --release
sudo cp target/release/oxyshift /usr/local/bin/

Dependencies

  • A Wayland compositor with wlr-output-management-unstable-v1 support for Hyprland
  • swww for wallpaper management (optional but recommended)

Configuration

Create a configuration file at ~/.config/oxyshift/config.toml:

# Single monitor setup
[[profile]]
name = "laptop"
wallpaper = "~/Pictures/Wallpapers/laptop.jpg"
exec = ["hyprctl notify -1 2000 'rgb(00ff00)' 'Laptop mode activated'"]

  [[profile.output]]
  name = "eDP-1"
  mode = "1920x1080@60"
  scale = 1.5
  position = [0, 0]

# External monitor setup
[[profile]]
name = "docked"
wallpaper = "~/Pictures/Wallpapers/desktop.jpg"
exec = ["hyprctl notify -1 2000 'rgb(0000ff)' 'Docked mode activated'"]

  [[profile.output]]
  name = "eDP-1"
  enabled = false

  [[profile.output]]
  name = "HDMI-A-2"
  mode = "2560x1440@144"
  scale = 1.0
  position = [0, 0]
  adaptive_sync = true

# Dual monitor setup
[[profile]]
name = "dual-monitors"
wallpaper = "~/Pictures/Wallpapers/ultrawide.jpg"

  [[profile.output]]
  name = "eDP-1"
  mode = "1920x1080@60"
  scale = 1.0
  position = [0, 0]

  [[profile.output]]
  name = "HDMI-A-2"
  mode = "2560x1440@144"
  scale = 1.0
  position = [1920, 0]

Configuration Options

Profile Settings

  • name: Unique identifier for the profile
  • wallpaper: Optional wallpaper path (can use ~ for home directory)
  • exec: Commands to execute when profile is activated

Output Settings

  • name: Output name (e.g., "eDP-1", "HDMI-A-2", or "*" for wildcard)
  • enabled: Whether the output is enabled (default: true)
  • mode: Display resolution and refresh rate (e.g., "1920x1080@60")
  • scale: Display scaling factor (e.g., 1.5)
  • position: Position in global coordinates [x, y]
  • transform: Display rotation ("90", "180", "270", "flipped-90", etc.)
  • adaptive_sync: Enable adaptive sync (FreeSync/G-Sync)

Usage

As a Daemon

# Start the daemo
oxyshift

# With custom config file
oxyshift --config /path/to/config.toml

# Test config without applying
oxyshift --test-only

# Enable debug logging
oxyshift --debug

Systemd User Service (Recommended)

Create ~/.config/systemd/user/oxyshift.service:

[Unit]
Description=oxyshift - Dynamic Wayland Display and Wallpaper Manager
Documentation=https://github.com/yourusername/oxyshift
After=graphical-session.target
Wants=graphical-session.target
PartOf=graphical-session.target

[Service]
Type=exec
ExecStart=/usr/local/bin/oxyshift --config %h/.config/oxyshift/config.toml
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

# Environment for Wayland
Environment=XDG_RUNTIME_DIR=/run/user/1000
Environment=WAYLAND_DISPLAY=wayland-1

# Process management
KillMode=mixed
TimeoutStopSec=30

# Security settings
PrivateNetwork=false
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=%h/.config/oxyshift %h/.local/state
NoNewPrivileges=true

[Install]
WantedBy=graphical-session.target

Then enable and start:

systemctl --user enable --now oxyshift

Comparison with Other Tools

Feature kanshi shikane way-displays oxyshift
Language C Rust C Rust
Configuration Custom TOML YAML TOML
Wallpaper Management
Wallpaper Persistence
Hot Reload Manual
Async Support
Quickshell Integration

Development

Building

cargo build

Testing

cargo test

Running with Debug Output

RUST_LOG=debug cargo run -- --debug

Architecture

oxyshift consists of several key components:

  • Wayland Client: Communicates with compositor via wlr-output-management protocol
  • Profile Manager: Matches connected displays to configuration profiles
  • Swww Manager: Handles wallpaper application and state persistence
  • Config Watcher: Monitors config file for hot-reload
  • Event Loop: Async event handling for display changes, signals, and config updates

Troubleshooting

Wallpaper not restoring after sleep

  1. Ensure swww is installed and accessible:

    which swww
    swww --version
  2. Check shared wallpaper state file exists:

    cat ~/.local/state/quickshell/user/current-wallpaper
  3. Check oxyshift logs:

    journalctl --user -u oxyshift -f

Profile not matching

Run with debug logging to see profile matching:

RUST_LOG=debug oxyshift --debug

Or test config without applying:

oxyshift --test-only

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE file for details.

Acknowledgments

  • Original kanshi for inspiration
  • shikane for demonstrating Rust implementation
  • swww for Wayland wallpaper management
  • autorandr for the X11 predecessor
  • The Rust Wayland ecosystem (wayland-rs, smithay)
  • quickshell for desktop shell integration

Project Name

oxyshift = "oxy" (oxygen/Rust) + "shift" (display profile and wallpaper transitions)

About

oxyshift is Wayland display manager that automatically switches display profiles based on connected monitors and manages wallpaper state across sleep/wake cycles

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages