mirror of
				https://github.com/wizbright/waybox.git
				synced 2025-11-03 09:01:45 -05:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "master" and "0.2.0" have entirely different histories.
		
	
	
		
	
		
					 82 changed files with 1470 additions and 2167 deletions
				
			
		
							
								
								
									
										19
									
								
								.build.yml
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								.build.yml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,27 +3,20 @@
 | 
			
		|||
#
 | 
			
		||||
image: archlinux
 | 
			
		||||
packages:
 | 
			
		||||
  - clang
 | 
			
		||||
  - gcc
 | 
			
		||||
  - libevdev
 | 
			
		||||
  - libinput
 | 
			
		||||
  - libxkbcommon
 | 
			
		||||
  - libxml2
 | 
			
		||||
  - meson
 | 
			
		||||
  - wayland
 | 
			
		||||
  - wayland-protocols
 | 
			
		||||
  - wlroots-git
 | 
			
		||||
  - libinput
 | 
			
		||||
  - libxkbcommon
 | 
			
		||||
  - libxml2
 | 
			
		||||
  - wlroots
 | 
			
		||||
  - xorg-server-xwayland
 | 
			
		||||
sources:
 | 
			
		||||
  - https://github.com/wizbright/waybox
 | 
			
		||||
tasks:
 | 
			
		||||
  - setup: |
 | 
			
		||||
      cd waybox
 | 
			
		||||
      CC=gcc meson setup build-gcc
 | 
			
		||||
      meson build
 | 
			
		||||
  - build: |
 | 
			
		||||
      cd waybox
 | 
			
		||||
      ninja -C build-gcc
 | 
			
		||||
  - clang: |
 | 
			
		||||
      cd waybox
 | 
			
		||||
      CC=clang meson setup build-clang
 | 
			
		||||
      ninja -C build-clang
 | 
			
		||||
      ninja -C build
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ block_comment_start = /*
 | 
			
		|||
block_comment_end = */
 | 
			
		||||
 | 
			
		||||
curly_bracket_next_line = false
 | 
			
		||||
max_line_length = 100
 | 
			
		||||
max_line_length = 80
 | 
			
		||||
spaces_around_brackets = outside
 | 
			
		||||
spaces_around_operators = true
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								.github/workflows/build.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/build.yml
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -12,18 +12,18 @@ on: [push, pull_request]
 | 
			
		|||
jobs:
 | 
			
		||||
    build:
 | 
			
		||||
        runs-on: ubuntu-latest
 | 
			
		||||
        container: alpine:edge
 | 
			
		||||
        container: archlinux:base-devel
 | 
			
		||||
        steps:
 | 
			
		||||
            - name: packages
 | 
			
		||||
              run: |
 | 
			
		||||
                apk add clang gcc libevdev-dev libinput-dev libxkbcommon-dev libxml2-dev meson musl-dev wayland-dev wayland-protocols wlroots wlroots-dev xwayland
 | 
			
		||||
            # actions/checkout@v4 clones the repository
 | 
			
		||||
            - uses: actions/checkout@v4
 | 
			
		||||
            - name: build-gcc
 | 
			
		||||
                pacman-key --init
 | 
			
		||||
                pacman -Syu --noconfirm
 | 
			
		||||
                pacman -S --noconfirm git meson libxkbcommon libinput libxml2 wayland wayland-protocols wlroots xorg-server-xwayland
 | 
			
		||||
            # actions/checkout@v2 clones the repository
 | 
			
		||||
            - uses: actions/checkout@v2
 | 
			
		||||
            - name: setup
 | 
			
		||||
              run: |
 | 
			
		||||
                CC=gcc meson setup build-gcc
 | 
			
		||||
                ninja -C build-gcc
 | 
			
		||||
            - name: build-clang
 | 
			
		||||
                meson build
 | 
			
		||||
            - name: build
 | 
			
		||||
              run: |
 | 
			
		||||
                CC=clang meson setup build-clang
 | 
			
		||||
                ninja -C build-clang
 | 
			
		||||
                ninja -C build
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ If you already have your own pull request habits, feel free to use them. If you
 | 
			
		|||
don't, however, allow me to make a suggestion: feature branches pulled from
 | 
			
		||||
upstream. Try this:
 | 
			
		||||
 | 
			
		||||
1. Fork Waybox
 | 
			
		||||
1. Fork waybox
 | 
			
		||||
2. `git clone https://github.com/username/waybox && cd waybox`
 | 
			
		||||
3. `git remote add upstream https://github.com/wizbright/waybox`
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ process is:
 | 
			
		|||
 | 
			
		||||
## Style Reference
 | 
			
		||||
 | 
			
		||||
Waybox is written in C with a style similar to the [kernel
 | 
			
		||||
waybox is written in C with a style similar to the [kernel
 | 
			
		||||
style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but
 | 
			
		||||
with a few notable differences.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ Try to break the line in the place which you think is the most appropriate.
 | 
			
		|||
 | 
			
		||||
### Line Length
 | 
			
		||||
 | 
			
		||||
Try to keep your lines under 100 columns, but you can break this rule if it
 | 
			
		||||
Try to keep your lines under 80 columns, but you can go up to 100 if it
 | 
			
		||||
improves readability. Don't break lines indiscriminately, try to find nice
 | 
			
		||||
breaking points so your code is easy to read.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										45
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,10 +1,8 @@
 | 
			
		|||
# Waybox
 | 
			
		||||
 | 
			
		||||
A \*box-style (minimalist) Wayland compositor modeled largely on Openbox (WIP)
 | 
			
		||||
An Openbox clone on Wayland (WIP)
 | 
			
		||||
 | 
			
		||||
### Goals
 | 
			
		||||
 | 
			
		||||
The main goal of this project is to provide a similar feel to \*box-style window managers but on Wayland
 | 
			
		||||
The main goal of this project is to provide a similar feel to Openbox but on Wayland
 | 
			
		||||
 | 
			
		||||
### Contributing
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,47 +11,22 @@ contributing.](https://github.com/wizbright/waybox/blob/master/CONTRIBUTING.md)
 | 
			
		|||
 | 
			
		||||
### Dependencies
 | 
			
		||||
 | 
			
		||||
* [Meson](https://mesonbuild.com/) or [muon](http://muon.build)
 | 
			
		||||
* [Wayland](https://wayland.freedesktop.org/)
 | 
			
		||||
* [libevdev](https://www.freedesktop.org/wiki/Software/libevdev/)
 | 
			
		||||
* [libinput](http://www.freedesktop.org/wiki/Software/libinput)
 | 
			
		||||
* [libxml2](http://xmlsoft.org/)
 | 
			
		||||
* [Meson](https://mesonbuild.com/)
 | 
			
		||||
* [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots/)
 | 
			
		||||
* [libxml2](http://xmlsoft.org/)
 | 
			
		||||
* [Wayland](https://wayland.freedesktop.org/)
 | 
			
		||||
* [xkbcommon](https://xkbcommon.org/)
 | 
			
		||||
 | 
			
		||||
### Build instructions
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
meson setup build
 | 
			
		||||
meson build
 | 
			
		||||
cd build
 | 
			
		||||
ninja
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
After that, you should have an executable as waybox/waybox
 | 
			
		||||
 | 
			
		||||
For those who don't want to use a Python-based build system, it's also possible
 | 
			
		||||
to use muon instead of Meson.
 | 
			
		||||
 | 
			
		||||
### Screenshots
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
### Useful Programs
 | 
			
		||||
 | 
			
		||||
Because \*box-style compositors are minimalist, most functionality is left to external programs.  As such, Waybox only functions as a box in which you can put whatever you need.  Here are some useful programs to complement Waybox if you desire:
 | 
			
		||||
 | 
			
		||||
* Panel: You can use [Waybar](https://github.com/Alexays/Waybar) or [yambar](https://codeberg.org/dnkl/yambar), similar to tint2 or fbpanel in Openbox or Fluxbox.
 | 
			
		||||
* Dock: You can use [Cairo Dock](https://www.glx-dock.org/) just like you did on Openbox.  There's also a [port with Wayland-specific enhancements](https://github.com/dkondor/cairo-dock-core/) that you may want to try. A much more compact option is [LavaLauncher](https://sr.ht/~leon_plickat/LavaLauncher/), but it's much harder to configure.
 | 
			
		||||
* Wallpaper utility: There are various utilities to set your wallpaper, each with their own advantages, including [wpaperd](https://github.com/danyspin97/wpaperd) (can select a random wallpaper from a directory), [swaybg](https://github.com/swaywm/swaybg) (can set the background color as well well as a wallpaper), and [hyprpaper](https://github.com/hyprwm/hyprpaper) (can change the wallpaper dynamically during runtime through IPC).
 | 
			
		||||
* Notification client: [mako](https://wayland.emersion.fr/mako/)
 | 
			
		||||
* [wl-clipboard](https://wayland.emersion.fr/mako/): Access the clipboard in scripts (also used by [neovim](https://neovim.io/))
 | 
			
		||||
* Screenshots: [grim](https://git.sr.ht/~emersion/grim) and [slurp](https://github.com/emersion/slurp)
 | 
			
		||||
* Screen recording: [wf-recorder](https://github.com/ammen99/wf-recorder)
 | 
			
		||||
* Menu support: [rofi-wayland](https://github.com/lbonn/rofi)
 | 
			
		||||
 | 
			
		||||
### Contact
 | 
			
		||||
I can be found as wiz on Rizon and wizbright on Libera. 
 | 
			
		||||
Join [#waybox](https://libera.chat/guides/connect) for discussion
 | 
			
		||||
I can be found as wiz on Rizon and WizBright on Freenode. 
 | 
			
		||||
Join [#waybox](http://webchat.freenode.net/?channels=waybox) for discussion
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,48 +23,15 @@ cairo-dock &
 | 
			
		|||
mako &
 | 
			
		||||
 | 
			
		||||
# Load a random wallpaper
 | 
			
		||||
get_random_wallpaper()
 | 
			
		||||
{
 | 
			
		||||
    oldifs=$IFS
 | 
			
		||||
    IFS=:
 | 
			
		||||
    data_dirs=${XDG_DATA_DIRS:-${datadir:-/usr/share}}:${XDG_DATA_HOME:-~/.local/share}
 | 
			
		||||
    for data_dir in $data_dirs;do
 | 
			
		||||
        IFS=$oldifs
 | 
			
		||||
oldifs=$IFS
 | 
			
		||||
IFS=:
 | 
			
		||||
data_dirs=${XDG_DATA_DIRS:-${datadir:-/usr/share}}:${XDG_DATA_HOME:-~/.local/share}
 | 
			
		||||
for data_dir in $data_dirs;
 | 
			
		||||
do
 | 
			
		||||
    wpdir="$data_dir/wallpapers"
 | 
			
		||||
    test -d "$wpdir" && \
 | 
			
		||||
        find $wpdir -name '*.jpg' -o -name '*.png' -o -name '*.svg'
 | 
			
		||||
    done | (shuf -n 1 || tail -n 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
load_wallpaper() {
 | 
			
		||||
    uses_wayland_info=0
 | 
			
		||||
    if (which hyprpaper && which socat && (test "$uses_wayland_info" = "0" || which wayland-info)) >/dev/null 2>&1; then
 | 
			
		||||
        hyprpaper &
 | 
			
		||||
        HYPRPAPER_SOCKET="${XDG_RUNTIME_DIR:-"/run/user/$(id -u)"}"/hypr/.hyprpaper.sock
 | 
			
		||||
        # Change the wallpaper every hour
 | 
			
		||||
        while test -S "$HYPRPAPER_SOCKET"; do
 | 
			
		||||
            if test "$uses_wayland_info" != "0";
 | 
			
		||||
            then
 | 
			
		||||
                current_output=$(wayland-info -i wl_output | \
 | 
			
		||||
                    grep 'name:' | tail -n 1 | cut -d : -f 2 | tr -d ' ')
 | 
			
		||||
            fi
 | 
			
		||||
            random_wallpaper="$(get_random_wallpaper)"
 | 
			
		||||
            for cmd in "preload $random_wallpaper" \
 | 
			
		||||
                "wallpaper $current_output,$random_wallpaper" \
 | 
			
		||||
                'unload all';
 | 
			
		||||
            do
 | 
			
		||||
                printf "$cmd" | socat UNIX-CONNECT:"$HYPRPAPER_SOCKET" -
 | 
			
		||||
            done
 | 
			
		||||
            [ $? -ne 0 ] && rm -f $HYPRPAPER_SOCKET
 | 
			
		||||
            sleep 60m
 | 
			
		||||
        done
 | 
			
		||||
    elif which swaybg >/dev/null 2>&1; then
 | 
			
		||||
        get_random_wallpaper | xargs swaybg -c '#303030' -m fill -i &
 | 
			
		||||
    elif which wpaperd >/dev/null 2>&1; then
 | 
			
		||||
        wpaperd &
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
load_wallpaper &
 | 
			
		||||
done | (shuf -n 1 || tail -n 1) | xargs swaybg -m fill -i &
 | 
			
		||||
IFS=$oldifs
 | 
			
		||||
 | 
			
		||||
# vim: ft=sh
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
#export ECORE_IMF_MODULE=uim
 | 
			
		||||
 | 
			
		||||
# Current compositor.  Needed for Wayland security negotiation.
 | 
			
		||||
export XDG_CURRENT_DESKTOP=Waybox
 | 
			
		||||
export XDG_CURRENT_DESKTOP=waybox
 | 
			
		||||
export XDG_SESSION_TYPE=wayland
 | 
			
		||||
 | 
			
		||||
# Make sure to run the X initialization if started through a display manager 
 | 
			
		||||
| 
						 | 
				
			
			@ -30,25 +30,17 @@ if test -n "$DISPLAY" && test -d /etc/X11/xinit/xinitrc.d;
 | 
			
		|||
then
 | 
			
		||||
    for f in /etc/X11/xinit/xinitrc.d/*.sh;
 | 
			
		||||
    do
 | 
			
		||||
        test -r "$f" && . "$f"
 | 
			
		||||
        test -f "$f" && . "$f"
 | 
			
		||||
    done
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Emerging standard, used by i.a. modern GTK versions instead of the obsolete
 | 
			
		||||
# org.gnome.default-applications.terminal.exec gsetting (which is now ignored)
 | 
			
		||||
# https://github.com/Vladimir-csp/xdg-terminal-exec (or create a symlink to
 | 
			
		||||
# your preferred terminal emulator)
 | 
			
		||||
TERMINAL=xdg-terminal-exec
 | 
			
		||||
# Get the preferred terminal from GNOME (if you use mostly GTK apps)
 | 
			
		||||
TERMINAL=$(gsettings get org.gnome.desktop.default-applications.terminal exec | tr -d \')
 | 
			
		||||
# Get the preferred terminal from KDE (if you use mostly Qt apps)
 | 
			
		||||
#TERMINAL=$(kreadconfig5 --file kdeglobals --group General --key TerminalApplication --default "konsole")
 | 
			
		||||
# Or just set it hard:
 | 
			
		||||
#TERMINAL=kitty
 | 
			
		||||
export TERMINAL
 | 
			
		||||
 | 
			
		||||
if command -v xdg-autostart >/dev/null 2>&1;
 | 
			
		||||
then
 | 
			
		||||
    export XDG_CURRENT_DESTKOP=OPENBOX
 | 
			
		||||
else
 | 
			
		||||
    # Use autostart scripts for these environments
 | 
			
		||||
    export WB_AUTOSTART_ENVIRONMENT=GNOME:KDE:OPENBOX
 | 
			
		||||
fi
 | 
			
		||||
# Use autostart scripts for these environments
 | 
			
		||||
export WB_AUTOSTART_ENVIRONMENT=GNOME:KDE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										71
									
								
								data/menu
									
										
									
									
									
								
							
							
						
						
									
										71
									
								
								data/menu
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,71 +0,0 @@
 | 
			
		|||
#!/bin/env python
 | 
			
		||||
 | 
			
		||||
import os, subprocess, sys
 | 
			
		||||
import shlex
 | 
			
		||||
import xml.dom.minidom as dom
 | 
			
		||||
 | 
			
		||||
def get_waybox_pid(name='waybox'):
 | 
			
		||||
    lines = subprocess.Popen(['pgrep', '-x', name], stdout=subprocess.PIPE).stdout.read().splitlines()
 | 
			
		||||
    if lines:
 | 
			
		||||
        return int(lines[0])
 | 
			
		||||
    else:
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
def get_menu_items(menu, indent, expand):
 | 
			
		||||
    menu_id = menu.getAttribute('id')
 | 
			
		||||
    nonselectable = str(bool(menu_id == '')).lower()
 | 
			
		||||
    print("%s%s ⇢\0info\x1f{\"menu\": \"%s\"}\x1fnonselectable\x1f%s" % (indent, menu.getAttribute('label').replace('_', '') or menu_id, menu_id, nonselectable))
 | 
			
		||||
    indent = indent + " "
 | 
			
		||||
    children = menu.childNodes
 | 
			
		||||
    for i in range(0, children.length):
 | 
			
		||||
        if expand:
 | 
			
		||||
            if children[i].nodeType == dom.Node.ELEMENT_NODE and children[i].tagName == 'item':
 | 
			
		||||
                action = children[i].getElementsByTagName('action')[0].getAttribute('name')
 | 
			
		||||
                cmd = ""
 | 
			
		||||
                icon = children[i].getAttribute('icon')
 | 
			
		||||
                label = children[i].getAttribute('label').replace('_', '')
 | 
			
		||||
                if action == 'Execute':
 | 
			
		||||
                    cmd = children[i].getElementsByTagName('execute')[0].firstChild.nodeValue
 | 
			
		||||
                elif action == 'Exit':
 | 
			
		||||
                    cmd = "kill -s SIGTERM %d" % get_waybox_pid()
 | 
			
		||||
                elif action == 'Reconfigure':
 | 
			
		||||
                    cmd = "kill -s SIGUSR2 %d" % get_waybox_pid()
 | 
			
		||||
                print("%s\0info\x1f{\"exec\": \"%s\"}\x1ficon\x1f%s\x1fdisplay\x1f%s %s" % (cmd, cmd.replace('"', '\\"'), icon, indent, label))
 | 
			
		||||
            elif children[i].nodeType == dom.Node.ELEMENT_NODE and children[i].tagName == 'menu':
 | 
			
		||||
                if children[i].getAttribute('execute') == "":
 | 
			
		||||
                    get_menu_items(children[i], indent, os.getenv('ROFI_RETV') is None)
 | 
			
		||||
                else:
 | 
			
		||||
                    try:
 | 
			
		||||
                        import xml.parsers.expat
 | 
			
		||||
                        lines = subprocess.Popen(shlex.split(children[i].getAttribute('execute')), stdout=subprocess.PIPE).stdout.read()
 | 
			
		||||
                        pipe = dom.parseString(lines)
 | 
			
		||||
                        pipes = pipe.getElementsByTagName('menu')
 | 
			
		||||
                        for j in range(0, pipes.length):
 | 
			
		||||
                            get_menu_items(pipes[j], indent, True)
 | 
			
		||||
                    # If a script doesn't function correctly anymore, don't stop rendering the menu
 | 
			
		||||
                    except xml.parsers.expat.ExpatError:
 | 
			
		||||
                        pass
 | 
			
		||||
 | 
			
		||||
menu_xml = os.getenv("WB_MENU_XML") or "menu.xml"
 | 
			
		||||
document = dom.parse(menu_xml)
 | 
			
		||||
 | 
			
		||||
print("\0message\x1f%s" % os.path.abspath(menu_xml))
 | 
			
		||||
if not (info := os.getenv('ROFI_INFO')) is None:
 | 
			
		||||
    import json
 | 
			
		||||
    obj = json.JSONDecoder().decode(s=info)
 | 
			
		||||
    if 'exec' in info:
 | 
			
		||||
        subprocess.Popen(shlex.split(obj['exec']), stdout=subprocess.PIPE)
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
    elif 'menu' in obj:
 | 
			
		||||
        # Eh document.getElementById() seems not to work
 | 
			
		||||
        menus = document.getElementsByTagName('menu')
 | 
			
		||||
        for i in range(0, menus.length):
 | 
			
		||||
            if menus[i].getAttribute('id') == obj['menu']:
 | 
			
		||||
                menu = menus[i]
 | 
			
		||||
                if not menu is None:
 | 
			
		||||
                    get_menu_items(menu, "", True)
 | 
			
		||||
                    print("---\0nonselectable\x1ftrue")
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
root_menu = document.getElementsByTagName('menu')[0]
 | 
			
		||||
get_menu_items(root_menu, "", True)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,4 @@
 | 
			
		|||
cfdata = configuration_data()
 | 
			
		||||
cfdata.set('bindir', get_option('prefix') / get_option('bindir'))
 | 
			
		||||
cfdata.set('libexecdir', get_option('prefix') / get_option('libexecdir'))
 | 
			
		||||
cfdata.set('localedir', get_option('prefix') / get_option('localedir'))
 | 
			
		||||
cfdata.set('sysconfdir', get_option('prefix') / get_option('sysconfdir'))
 | 
			
		||||
| 
						 | 
				
			
			@ -34,21 +33,8 @@ install_data(
 | 
			
		|||
  install_mode: 'rw-r--r--',
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
install_data(
 | 
			
		||||
  'waybox.svg',
 | 
			
		||||
  install_dir: get_option('prefix') / get_option('datadir') / 'icons',
 | 
			
		||||
  install_mode: 'rw-r--r--',
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
install_data(
 | 
			
		||||
  'waybox.desktop',
 | 
			
		||||
  install_dir: get_option('prefix') / get_option('datadir') + '/wayland-sessions',
 | 
			
		||||
  install_mode: 'rw-r--r--',
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
install_data(
 | 
			
		||||
  'menu',
 | 
			
		||||
  install_dir: get_option('prefix') / get_option('bindir'),
 | 
			
		||||
  install_mode: 'rwxr-xr-x',
 | 
			
		||||
  rename: ['waybox-menu']
 | 
			
		||||
  )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										51
									
								
								data/rc.xml
									
										
									
									
									
								
							
							
						
						
									
										51
									
								
								data/rc.xml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,15 +9,15 @@
 | 
			
		|||
    <right>0</right>
 | 
			
		||||
  </margins>
 | 
			
		||||
  <keyboard>
 | 
			
		||||
    <!-- XKB configuration.  See `man xkeyboard-config` for more information -->
 | 
			
		||||
    <!-- Keyboard layout.  See `man xkeyboard-config` for more information -->
 | 
			
		||||
    <!-- You can use the XKB_* environment variables instead -->
 | 
			
		||||
    <!-- <xkb>
 | 
			
		||||
    <!-- <keyboardLayout>
 | 
			
		||||
      <model>105</model>
 | 
			
		||||
      <layout>us</layout>
 | 
			
		||||
      <options>ctrl:swapcaps,esperanto:dvorak,lv3:ralt_switch_multikey</options>
 | 
			
		||||
      <rules>evdev</rules>
 | 
			
		||||
      <variant>dvorak</variant>
 | 
			
		||||
    </xkb> -->
 | 
			
		||||
    </keyboardLayout> -->
 | 
			
		||||
    <!-- Keybindings for windows -->
 | 
			
		||||
    <keybind key="A-F4">
 | 
			
		||||
      <action name="Close"/>
 | 
			
		||||
| 
						 | 
				
			
			@ -42,16 +42,16 @@
 | 
			
		|||
    </keybind>
 | 
			
		||||
    <!-- Keybindings for window switching -->
 | 
			
		||||
    <keybind key="A-Tab">
 | 
			
		||||
      <action name="NextWindow"/>
 | 
			
		||||
      <action name="Unshade"/>
 | 
			
		||||
      <action name="NextWindow">
 | 
			
		||||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
    <keybind key="A-S-ISO_Left_Tab">
 | 
			
		||||
      <action name="PreviousWindow"/>
 | 
			
		||||
      <action name="Unshade"/>
 | 
			
		||||
      <action name="PreviousWindow">
 | 
			
		||||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
    <keybind key="C-A-Tab">
 | 
			
		||||
      <action name="NextWindow"/>
 | 
			
		||||
      <action name="Unshade"/>
 | 
			
		||||
      <action name="NextWindow">
 | 
			
		||||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
    <!-- Keybindings for running applications -->
 | 
			
		||||
    <keybind key="W-Return">
 | 
			
		||||
| 
						 | 
				
			
			@ -64,17 +64,6 @@
 | 
			
		|||
        <execute>grim "$(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim_fs.png')"</execute>
 | 
			
		||||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
    <keybind key="A-Sys_Req">
 | 
			
		||||
      <action name="Execute">
 | 
			
		||||
        <execute>grim -g "$(slurp -d)" "$(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim_sel.png')"</execute>
 | 
			
		||||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
    <keybind key="A-r">
 | 
			
		||||
      <action name="Execute">
 | 
			
		||||
        <!-- If you'd prefer to use something like wmenu: `waybox-menu | wmenu | xargs env` -->
 | 
			
		||||
        <execute>rofi -show waybox-menu</execute>
 | 
			
		||||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
    <keybind key="A-F2">
 | 
			
		||||
      <action name="Execute">
 | 
			
		||||
        <execute>obrun l</execute>
 | 
			
		||||
| 
						 | 
				
			
			@ -112,26 +101,4 @@
 | 
			
		|||
      </action>
 | 
			
		||||
    </keybind>
 | 
			
		||||
  </keyboard>
 | 
			
		||||
  <!-- Configuration for mice and other pointers. <mouse> instead of <pointer> only for backwards compatibility. -->
 | 
			
		||||
  <mouse>
 | 
			
		||||
    <!-- libinput configuration. -->
 | 
			
		||||
    <!-- <libinput>
 | 
			
		||||
      <accelProfile>adaptive</accelProfile>
 | 
			
		||||
      <accelSpeed>0.9</accelSpeed>
 | 
			
		||||
      <calibrationMatrix>0 0 0 0 0 0</calibrationMatrix>
 | 
			
		||||
      <clickMethod>buttonAreas</clickMethod>
 | 
			
		||||
      <disableWhileTrackpointing>enabled</disableWhileTrackpointing>
 | 
			
		||||
      <disableWhileTyping>enabled</disableWhileTyping>
 | 
			
		||||
      <leftHanded>disabled</leftHanded>
 | 
			
		||||
      <middleEmulation>enabled</middleEmulation>
 | 
			
		||||
      <naturalScroll>disabled</naturalScroll>
 | 
			
		||||
      <scrollButton>BTN_MIDDLE</scrollButton>
 | 
			
		||||
      <scrollButtonLock>disabled</scrollButtonLock>
 | 
			
		||||
      <scrollMethod>twofinger</scrollMethod>
 | 
			
		||||
      <tap>enabled</tap>
 | 
			
		||||
      <tapButtonMap>lrm</tapButtonMap>
 | 
			
		||||
      <tapDrag>enabled</tapDrag>
 | 
			
		||||
      <tapDragLock>enabled</tapDragLock>
 | 
			
		||||
    </libinput> -->
 | 
			
		||||
  </mouse>
 | 
			
		||||
</openbox_config>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,5 +4,4 @@ Comment=An Openbox-like compositor for Wayland
 | 
			
		|||
Comment[de]=Ein Wayland-Compositor ähnlich zu Openbox
 | 
			
		||||
Comment[eo]=Komponilo de Wayland, kiu similas je Openbox
 | 
			
		||||
Exec=waybox
 | 
			
		||||
Icon=waybox
 | 
			
		||||
Type=Application
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,7 @@ then
 | 
			
		|||
fi
 | 
			
		||||
 | 
			
		||||
# And the XDG autostart script
 | 
			
		||||
if command -v xdg-autostart >/dev/null 2>&1;
 | 
			
		||||
then
 | 
			
		||||
    # Probably what you want instead of my simple shell script.
 | 
			
		||||
    # https://gitlab.com/somini/xdg-autostart/
 | 
			
		||||
    WB_XDG_AUTOSTART="xdg-autostart"
 | 
			
		||||
elif test -x $WB_USER_CONF_DIR/xdg-autostart;
 | 
			
		||||
if test -x $WB_USER_CONF_DIR/xdg-autostart;
 | 
			
		||||
then
 | 
			
		||||
    WB_XDG_AUTOSTART=$WB_USER_CONF_DIR/xdg-autostart;
 | 
			
		||||
elif test -x $WB_SYS_CONF_DIR/xdg-autostart;
 | 
			
		||||
| 
						 | 
				
			
			@ -77,26 +72,6 @@ then
 | 
			
		|||
    WB_XDG_AUTOSTART="@libexecdir@/openbox-autostart OPENBOX";
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -f $WB_USER_CONF_DIR/menu.xml;
 | 
			
		||||
then
 | 
			
		||||
    WB_MENU_XML=$WB_USER_CONF_DIR/menu.xml
 | 
			
		||||
elif test -f $WB_SYS_CONF_DIR/menu.xml;
 | 
			
		||||
then
 | 
			
		||||
    WB_MENU_XML=$WB_SYS_CONF_DIR/menu.xml
 | 
			
		||||
elif test -f $OB_USER_CONF_DIR/menu.xml;
 | 
			
		||||
then
 | 
			
		||||
    _ "WARNING: Using files from Openbox. These may not work correctly."
 | 
			
		||||
    WB_MENU_XML=$OB_USER_CONF_DIR/menu.xml
 | 
			
		||||
elif test -f $OB_SYS_CONF_DIR/menu.xml;
 | 
			
		||||
then
 | 
			
		||||
    _ "WARNING: Using files from Openbox. These may not work correctly."
 | 
			
		||||
    WB_MENU_XML=$OB_SYS_CONF_DIR/menu.xml;
 | 
			
		||||
else
 | 
			
		||||
    _ "ERROR: No menu file found." >&2
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
export WB_MENU_XML
 | 
			
		||||
 | 
			
		||||
if test -f $WB_USER_CONF_DIR/rc.xml;
 | 
			
		||||
then
 | 
			
		||||
    WB_RC_XML=$WB_USER_CONF_DIR/rc.xml
 | 
			
		||||
| 
						 | 
				
			
			@ -119,11 +94,9 @@ export WB_RC_XML
 | 
			
		|||
 | 
			
		||||
if which dbus-launch >/dev/null 2>&1;
 | 
			
		||||
then
 | 
			
		||||
    DBUS_LAUNCH="dbus-launch --exit-with-session"
 | 
			
		||||
    DBUS_LANCH="dbus-launch --exit-with-session"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
export PATH=@bindir@:$PATH
 | 
			
		||||
 | 
			
		||||
# No need to export these to Waybox
 | 
			
		||||
unset TEXTDOMAIN TEXTDOMAINDIR
 | 
			
		||||
$DBUS_LAUNCH @libexecdir@/waybox --startup "${WB_AUTOSTART:-true}; ${WB_XDG_AUTOSTART:-true}" "$@"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
<?xml version="1.0" standalone="no"?>
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 | 
			
		||||
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="48px" width="48px">
 | 
			
		||||
  <desc>Waybox icon</desc>
 | 
			
		||||
  <defs>
 | 
			
		||||
    <linearGradient id="titlegradient" x1="0" y1="0" x2="0" y2="1">
 | 
			
		||||
        <stop offset="0%" stop-color="#589bda" />
 | 
			
		||||
        <stop offset="100%" stop-color="#3c7cb7" />
 | 
			
		||||
    </linearGradient>
 | 
			
		||||
  </defs>
 | 
			
		||||
  <rect height="10" width="48" x="0" y="0" fill="url(#titlegradient)" />
 | 
			
		||||
  <rect height="38" width="48" x="0" y="10" fill="#eaeaea" />
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 601 B  | 
| 
						 | 
				
			
			@ -66,8 +66,6 @@ do
 | 
			
		|||
                    then
 | 
			
		||||
                        show_in=0
 | 
			
		||||
                        break 2
 | 
			
		||||
                    else
 | 
			
		||||
                        show_in=1
 | 
			
		||||
                    fi
 | 
			
		||||
                done
 | 
			
		||||
            done
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +88,7 @@ do
 | 
			
		|||
        then
 | 
			
		||||
            # Don't run the Exec key if a non-empty TryExec command can't be found
 | 
			
		||||
            TRY_EXEC=$(cat "$f" | grep '^TryExec\s*=\s*\S' | sed -e 's/^TryExec\s*=\s*//g');
 | 
			
		||||
            if test -n "$TRY_EXEC" && ! command -v $TRY_EXEC >/dev/null 2>&1;
 | 
			
		||||
            if test -n "$TRY_EXEC" && ! which $TRY_EXEC;
 | 
			
		||||
            then
 | 
			
		||||
                continue
 | 
			
		||||
            fi
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,5 @@ struct wb_cursor {
 | 
			
		|||
 | 
			
		||||
struct wb_cursor *wb_cursor_create(struct wb_server *server);
 | 
			
		||||
void wb_cursor_destroy(struct wb_cursor *cursor);
 | 
			
		||||
void reset_cursor_mode(struct wb_server *server);
 | 
			
		||||
 | 
			
		||||
#endif /* cursor.h */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,36 +1,55 @@
 | 
			
		|||
#ifndef _WB_OUTPUT_H
 | 
			
		||||
#define _WB_OUTPUT_H
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include <wlr/render/wlr_renderer.h>
 | 
			
		||||
#include <wlr/render/wlr_texture.h>
 | 
			
		||||
#include <wlr/types/wlr_xdg_output_v1.h>
 | 
			
		||||
 | 
			
		||||
#include "waybox/server.h"
 | 
			
		||||
#include <wlr/types/wlr_output_management_v1.h>
 | 
			
		||||
 | 
			
		||||
struct wb_output {
 | 
			
		||||
	struct wlr_output *wlr_output;
 | 
			
		||||
	struct wb_server *server;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct wlr_scene_tree *shell_background;
 | 
			
		||||
		struct wlr_scene_tree *shell_bottom;
 | 
			
		||||
		struct wlr_scene_tree *shell_fullscreen;
 | 
			
		||||
		struct wlr_scene_tree *shell_overlay;
 | 
			
		||||
		struct wlr_scene_tree *shell_top;
 | 
			
		||||
	} layers;
 | 
			
		||||
 | 
			
		||||
	bool gamma_lut_changed;
 | 
			
		||||
	struct wlr_box geometry;
 | 
			
		||||
	struct wl_list layers[4];
 | 
			
		||||
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wl_listener frame;
 | 
			
		||||
	struct wl_listener request_state;
 | 
			
		||||
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data);
 | 
			
		||||
void output_frame_notify(struct wl_listener *listener, void *data);
 | 
			
		||||
void output_destroy_notify(struct wl_listener *listener, void *data);
 | 
			
		||||
void init_output(struct wb_server *server);
 | 
			
		||||
struct wb_view {
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
	struct wb_server *server;
 | 
			
		||||
	struct wlr_xdg_toplevel *xdg_toplevel;
 | 
			
		||||
#if !WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	struct wlr_xdg_surface *xdg_surface;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	struct wlr_xdg_toplevel_decoration_v1 *decoration;
 | 
			
		||||
	int decoration_height;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener map;
 | 
			
		||||
	struct wl_listener unmap;
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wl_listener new_popup;
 | 
			
		||||
	struct wl_listener request_maximize;
 | 
			
		||||
	struct wl_listener request_minimize;
 | 
			
		||||
	struct wl_listener request_move;
 | 
			
		||||
	struct wl_listener request_resize;
 | 
			
		||||
	struct wl_listener surface_commit;
 | 
			
		||||
	bool mapped;
 | 
			
		||||
 | 
			
		||||
	struct wlr_box current_position;
 | 
			
		||||
	struct wlr_box previous_position;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void output_frame_notify(struct wl_listener* listener, void *data);
 | 
			
		||||
void output_destroy_notify(struct wl_listener* listener, void *data);
 | 
			
		||||
void new_output_notify(struct wl_listener* listener, void *data);
 | 
			
		||||
 | 
			
		||||
#endif /* output.h */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,16 @@
 | 
			
		|||
#ifndef _WB_SEAT_H
 | 
			
		||||
#define _WB_SEAT_H
 | 
			
		||||
 | 
			
		||||
#include <wlr/types/wlr_keyboard.h>
 | 
			
		||||
#include <wlr/types/wlr_primary_selection.h>
 | 
			
		||||
#include <wlr/types/wlr_primary_selection_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_seat.h>
 | 
			
		||||
 | 
			
		||||
struct wb_server;
 | 
			
		||||
 | 
			
		||||
struct wb_seat {
 | 
			
		||||
	struct wlr_seat *seat;
 | 
			
		||||
 | 
			
		||||
	struct wlr_layer_surface_v1 *focused_layer;
 | 
			
		||||
 | 
			
		||||
	struct wl_list keyboards;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener request_set_primary_selection;
 | 
			
		||||
| 
						 | 
				
			
			@ -17,16 +20,13 @@ struct wb_seat {
 | 
			
		|||
struct wb_keyboard {
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
	struct wb_server *server;
 | 
			
		||||
	struct wlr_keyboard *keyboard;
 | 
			
		||||
	struct wlr_input_device *device;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wl_listener modifiers;
 | 
			
		||||
	struct wl_listener key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wb_server;
 | 
			
		||||
struct wb_seat *wb_seat_create(struct wb_server *server);
 | 
			
		||||
void seat_focus_surface(struct wb_seat *seat, struct wlr_surface *surface);
 | 
			
		||||
void seat_set_focus_layer(struct wb_seat *seat, struct wlr_layer_surface_v1 *layer);
 | 
			
		||||
void wb_seat_destroy(struct wb_seat *seat);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,30 +1,30 @@
 | 
			
		|||
#ifndef _WB_SERVER_H
 | 
			
		||||
#define _WB_SERVER_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#define MAX(a, b) ((a > b) ? (a) : (b))
 | 
			
		||||
#define MIN(a, b) ((a < b) ? (a) : (b))
 | 
			
		||||
#define TITLEBAR_HEIGHT 8 /* TODO: Get this from the theme */
 | 
			
		||||
#include <wlr/version.h>
 | 
			
		||||
#define WLR_CHECK_VERSION(major, minor, micro) (WLR_VERSION_NUM >= ((major << 16) | (minor << 8) | (micro)))
 | 
			
		||||
 | 
			
		||||
#include <wlr/backend.h>
 | 
			
		||||
#include <wlr/render/allocator.h>
 | 
			
		||||
#include <wlr/render/wlr_renderer.h>
 | 
			
		||||
#include <wlr/render/wlr_texture.h>
 | 
			
		||||
#include <wlr/types/wlr_compositor.h>
 | 
			
		||||
#include <wlr/types/wlr_data_device.h>
 | 
			
		||||
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_gamma_control_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_idle_notify_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_output_layout.h>
 | 
			
		||||
#include <wlr/types/wlr_scene.h>
 | 
			
		||||
#include <wlr/types/wlr_idle.h>
 | 
			
		||||
#include <wlr/types/wlr_screencopy_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_matrix.h>
 | 
			
		||||
#include <wlr/types/wlr_gamma_control_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_output_layout.h>
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
#include <wlr/types/wlr_subcompositor.h>
 | 
			
		||||
#include <wlr/types/wlr_xdg_output_v1.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <wlr/types/wlr_xdg_shell.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef USE_NLS
 | 
			
		||||
#	include <libintl.h>
 | 
			
		||||
#	include <locale.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -37,27 +37,21 @@
 | 
			
		|||
#include "waybox/cursor.h"
 | 
			
		||||
#include "decoration.h"
 | 
			
		||||
#include "layer_shell.h"
 | 
			
		||||
#include "waybox/xdg_shell.h"
 | 
			
		||||
#include "waybox/output.h"
 | 
			
		||||
#include "waybox/seat.h"
 | 
			
		||||
 | 
			
		||||
struct wb_server {
 | 
			
		||||
	struct wl_display *wl_display;
 | 
			
		||||
	struct wl_event_loop *wl_event_loop;
 | 
			
		||||
 | 
			
		||||
	struct wlr_allocator *allocator;
 | 
			
		||||
	struct wlr_backend *backend;
 | 
			
		||||
	struct wlr_compositor *compositor;
 | 
			
		||||
	struct wlr_gamma_control_manager_v1 *gamma_control_manager;
 | 
			
		||||
	struct wlr_idle_inhibit_manager_v1 *idle_inhibit_manager;
 | 
			
		||||
	struct wlr_idle_notifier_v1 *idle_notifier;
 | 
			
		||||
	struct wlr_output_layout *output_layout;
 | 
			
		||||
	struct wlr_xdg_output_manager_v1 *output_manager;
 | 
			
		||||
	struct wlr_renderer *renderer;
 | 
			
		||||
	struct wlr_scene *scene;
 | 
			
		||||
	struct wlr_scene_output_layout *scene_layout;
 | 
			
		||||
	struct wlr_session *session;
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	struct wlr_subcompositor *subcompositor;
 | 
			
		||||
	struct wlr_output_manager_v1 *wlr_output_manager;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	struct wb_config *config;
 | 
			
		||||
	char *config_file;
 | 
			
		||||
| 
						 | 
				
			
			@ -65,36 +59,26 @@ struct wb_server {
 | 
			
		|||
	struct wb_cursor *cursor;
 | 
			
		||||
	struct wb_seat *seat;
 | 
			
		||||
 | 
			
		||||
	struct wb_toplevel *grabbed_toplevel;
 | 
			
		||||
	struct wb_view *grabbed_view;
 | 
			
		||||
	struct wlr_box grab_geo_box;
 | 
			
		||||
	double grab_x, grab_y;
 | 
			
		||||
	uint32_t resize_edges;
 | 
			
		||||
	struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list;
 | 
			
		||||
	struct wl_list toplevels;
 | 
			
		||||
	struct wl_list views;
 | 
			
		||||
 | 
			
		||||
	struct wlr_layer_shell_v1 *layer_shell;
 | 
			
		||||
	struct wlr_xdg_shell *xdg_shell;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener gamma_control_set_gamma;
 | 
			
		||||
	struct wl_listener new_layer_surface;
 | 
			
		||||
	struct wl_listener new_xdg_surface;
 | 
			
		||||
	struct wl_listener new_xdg_decoration;
 | 
			
		||||
	struct wl_listener new_xdg_popup;
 | 
			
		||||
	struct wl_listener new_xdg_toplevel;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener destroy_inhibit_manager;
 | 
			
		||||
	struct wl_listener destroy_inhibitor;
 | 
			
		||||
	struct wl_listener new_inhibitor;
 | 
			
		||||
	struct wl_list inhibitors;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener new_input;
 | 
			
		||||
	struct wl_listener new_output;
 | 
			
		||||
	struct wl_listener output_configuration_applied;
 | 
			
		||||
	struct wl_listener output_configuration_tested;
 | 
			
		||||
	struct wl_list outputs; /* wb_output::link */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool wb_create_backend(struct wb_server *server);
 | 
			
		||||
bool wb_start_server(struct wb_server *server);
 | 
			
		||||
bool wb_terminate(struct wb_server *server);
 | 
			
		||||
bool wb_create_backend(struct wb_server* server);
 | 
			
		||||
bool wb_start_server(struct wb_server* server);
 | 
			
		||||
bool wb_terminate(struct wb_server* server);
 | 
			
		||||
 | 
			
		||||
#endif /* server.h */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,49 +1,11 @@
 | 
			
		|||
#ifndef _WB_XDG_SHELL_H
 | 
			
		||||
#define _WB_XDG_SHELL_H
 | 
			
		||||
 | 
			
		||||
#include <wlr/types/wlr_fractional_scale_v1.h>
 | 
			
		||||
 | 
			
		||||
#include "waybox/server.h"
 | 
			
		||||
 | 
			
		||||
struct wb_popup {
 | 
			
		||||
	struct wlr_xdg_popup *xdg_popup;
 | 
			
		||||
	struct wl_listener commit;
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wb_toplevel {
 | 
			
		||||
	struct wb_server *server;
 | 
			
		||||
	struct wlr_xdg_toplevel *xdg_toplevel;
 | 
			
		||||
	struct wlr_scene_tree *scene_tree;
 | 
			
		||||
 | 
			
		||||
	struct wlr_xdg_toplevel_decoration_v1 *decoration;
 | 
			
		||||
 | 
			
		||||
	struct wlr_ext_foreign_toplevel_handle_v1 *foreign_toplevel_handle;
 | 
			
		||||
	struct wlr_ext_foreign_toplevel_handle_v1_state foreign_toplevel_state;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener map;
 | 
			
		||||
	struct wl_listener unmap;
 | 
			
		||||
	struct wl_listener commit;
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wl_listener new_popup;
 | 
			
		||||
	struct wl_listener request_fullscreen;
 | 
			
		||||
	struct wl_listener request_maximize;
 | 
			
		||||
	struct wl_listener request_minimize;
 | 
			
		||||
	struct wl_listener request_move;
 | 
			
		||||
	struct wl_listener request_resize;
 | 
			
		||||
	struct wl_listener set_app_id;
 | 
			
		||||
	struct wl_listener set_title;
 | 
			
		||||
 | 
			
		||||
	struct wlr_box geometry;
 | 
			
		||||
	struct wlr_box previous_geometry;
 | 
			
		||||
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void init_xdg_shell(struct wb_server *server);
 | 
			
		||||
void focus_toplevel(struct wb_toplevel *toplevel);
 | 
			
		||||
struct wlr_output *get_active_output(struct wb_toplevel *toplevel);
 | 
			
		||||
struct wb_toplevel *get_toplevel_at(
 | 
			
		||||
void focus_view(struct wb_view *view, struct wlr_surface *surface);
 | 
			
		||||
struct wb_view *desktop_view_at(
 | 
			
		||||
		struct wb_server *server, double lx, double ly,
 | 
			
		||||
		struct wlr_surface **surface, double *sx, double *sy);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								meson.build
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								meson.build
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
project(
 | 
			
		||||
  'Waybox',
 | 
			
		||||
  'c',
 | 
			
		||||
  version: '0.2.3',
 | 
			
		||||
  version: '0.2.0',
 | 
			
		||||
  license: 'MIT',
 | 
			
		||||
  meson_version: '>=0.60.0',
 | 
			
		||||
  meson_version: '>=0.52.0',
 | 
			
		||||
  default_options: [
 | 
			
		||||
    'c_std=c11',
 | 
			
		||||
    'warning_level=2',
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,6 @@ add_project_arguments(
 | 
			
		|||
  '-Wno-unused-parameter',
 | 
			
		||||
  '-D_DEFAULT_SOURCE',
 | 
			
		||||
  '-D_POSIX_C_SOURCE=200112L',
 | 
			
		||||
  '-DWL_HIDE_DEPRECATED', # Hide the deprecated parts of the Wayland API
 | 
			
		||||
  '-DWLR_USE_UNSTABLE',
 | 
			
		||||
  '-DPACKAGE_NAME="' + meson.project_name() + '"',
 | 
			
		||||
  '-DPACKAGE_VERSION="' + meson.project_version() + '"',
 | 
			
		||||
| 
						 | 
				
			
			@ -26,27 +25,16 @@ cc = meson.get_compiler('c')
 | 
			
		|||
# Adding include directory
 | 
			
		||||
inc_dir = include_directories('include')
 | 
			
		||||
 | 
			
		||||
if get_option('wlroots-version') != ''
 | 
			
		||||
  wlroots_version = get_option('wlroots-version')
 | 
			
		||||
else
 | 
			
		||||
  wlroots_version = ['wlroots-0.20', 'wlroots-0.19', 'wlroots-0.18']
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libevdev = dependency('libevdev')
 | 
			
		||||
libinput = dependency('libinput', version: '>=1.21.0', required: false)
 | 
			
		||||
libxml2 = dependency('libxml-2.0')
 | 
			
		||||
wayland_protos = dependency('wayland-protocols', version: '>=1.37')
 | 
			
		||||
wlroots = dependency('wlroots', version: '>=0.15.0')
 | 
			
		||||
wayland_server = dependency('wayland-server', version: '>=1.15')
 | 
			
		||||
wlroots = dependency(wlroots_version, version: '>=0.17.0')
 | 
			
		||||
wayland_protos  = dependency('wayland-protocols', version: '>=1.17')
 | 
			
		||||
xkbcommon  = dependency('xkbcommon')
 | 
			
		||||
 | 
			
		||||
if libinput.found()
 | 
			
		||||
  add_project_arguments('-DHAS_LIBINPUT', language: 'c')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
msgfmt = find_program('msgfmt', required: false)
 | 
			
		||||
if msgfmt.found()
 | 
			
		||||
  source_root = meson.current_source_dir()
 | 
			
		||||
  add_project_arguments('-DUSE_NLS=1', language: 'c')
 | 
			
		||||
  subdir('po')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
option('wlroots-version', type: 'string', value: '', description: 'The version of wlroots with which to compile the compositor')
 | 
			
		||||
							
								
								
									
										17
									
								
								po/af.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/af.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:03-0400\n"
 | 
			
		||||
"Last-Translator: aspersieman <aspersieman@gmail.com>\n"
 | 
			
		||||
"Language-Team: Afrikaans\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -128,12 +134,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +146,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/ar.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/ar.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:03-0400\n"
 | 
			
		||||
"Last-Translator: كريم اولاد الشلحة <herr.linux88@gmail.com>\n"
 | 
			
		||||
"Language-Team: Arabic <herr.linux88@gmail.com>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -128,12 +134,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +146,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/be.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/be.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:03-0400\n"
 | 
			
		||||
"Last-Translator: Mikalai Udodau <crom-a@tut.by>\n"
 | 
			
		||||
"Language-Team: Belarusian <i18n@mova.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/bn_IN.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/bn_IN.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:06-0400\n"
 | 
			
		||||
"Last-Translator: Runa Bhattacharjee <runabh@gmail.com>\n"
 | 
			
		||||
"Language-Team: Bengali (India) <en@li.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/ca.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/ca.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:06-0400\n"
 | 
			
		||||
"Last-Translator: David Majà Martínez <davidmaja@gmail.com>\n"
 | 
			
		||||
"Language-Team: catalan\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/cs.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/cs.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:06-0400\n"
 | 
			
		||||
"Last-Translator: David Kolibac <david@kolibac.cz>\n"
 | 
			
		||||
"Language-Team: Czech <cs@li.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/da.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/da.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2022-02-18 17:43-0500\n"
 | 
			
		||||
"Last-Translator: Jesper Sander <sander.contrib@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										115
									
								
								po/de.po
									
										
									
									
									
								
							
							
						
						
									
										115
									
								
								po/de.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,8 +11,8 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2024-01-25 21:21-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2024-01-25 21:34-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2022-02-22 21:21-0500\n"
 | 
			
		||||
"Last-Translator: Volker Ribbert <volker.nospam@netcologne.de>\n"
 | 
			
		||||
"Language-Team:  <de@li.org>\n"
 | 
			
		||||
"Language: de\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -22,10 +22,10 @@ msgstr ""
 | 
			
		|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 | 
			
		||||
 | 
			
		||||
msgid "WARNING: Using files from Openbox. These may not work correctly."
 | 
			
		||||
msgstr "WARNUNG: Benutze Dateien von Openbox, was nicht richtig funktionieren wird."
 | 
			
		||||
msgstr "WARNUNG: Benutzt Dateien aus Openbox. Das wird nicht richtig werken."
 | 
			
		||||
 | 
			
		||||
msgid "ERROR: No configuration file found."
 | 
			
		||||
msgstr "FEHLER: Keine Konfigurationsdatei gefunden."
 | 
			
		||||
msgstr "FEHLER: Keine Einstellungsdatei gefunden."
 | 
			
		||||
 | 
			
		||||
msgid "Unable to evaluate expression"
 | 
			
		||||
msgstr "Konnte den Ausdruck nicht evaluieren"
 | 
			
		||||
| 
						 | 
				
			
			@ -39,18 +39,18 @@ msgstr "Kein nodeset"
 | 
			
		|||
msgid ""
 | 
			
		||||
"Unable to parse the configuration file. Consult stderr for more information."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Kann die Konfigurationsdatei nicht verarbeiten. Für weitere Informationen siehe "
 | 
			
		||||
"die Standardfehlerausgabe."
 | 
			
		||||
"Kann nicht die Einstullungsdatei analisieren. Für mehr Informationen die "
 | 
			
		||||
"Standardfehlerausgabe lesen."
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't create new context!"
 | 
			
		||||
msgstr "Konnte keinen neuen Kontext erstellen!"
 | 
			
		||||
msgstr "Konnte einen neuen Zusammenhang nicht erstellen"
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't register the namespace"
 | 
			
		||||
msgstr "Konnte den Namensraum nicht registrieren"
 | 
			
		||||
msgstr "Konte dem Namensnraum nicht registrieren"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Syntax: %s [options]\n"
 | 
			
		||||
msgstr "Syntax: %s [Optionen]\n"
 | 
			
		||||
msgstr "Eingabe: %s [Optionen]\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ msgstr "  --config-file DATEI Pfad zur Konfigurationsdatei\n"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "  --sm-disable        Disable connection to the session manager\n"
 | 
			
		||||
msgstr "  --sm-disable        Deaktiviere Verbindung zum Sitzungsmanager\n"
 | 
			
		||||
msgstr "  --sm-disable        Verbindung zum Sitzungsmanager trennen\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "  --startup CMD       Run CMD after starting\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ msgstr "  --startup CMD       CMD nach Start ausführen\n"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "  --debug             Display debugging output\n"
 | 
			
		||||
msgstr "  --debug             Ausgabe von Debug-Informationen\n"
 | 
			
		||||
msgstr "  --debug             Fehlersuche-Ergebnis anzeigen\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
| 
						 | 
				
			
			@ -92,8 +92,8 @@ msgid ""
 | 
			
		|||
"on Wayland.\n"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"\n"
 | 
			
		||||
"Weitere Openbox-Optionen werden nicht angenommen, da sie überwiegend "
 | 
			
		||||
"sinnlos unter Wayland sind.\n"
 | 
			
		||||
"Weitere Openbox-Optionen sind nicht angenommen, meistens wegen sie sind "
 | 
			
		||||
"sinnlos auf Wayland.\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s requires an argument\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -101,25 +101,31 @@ msgstr "%s erfordert einen Parameter\n"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s hasn't been implemented yet.\n"
 | 
			
		||||
msgstr "%s wurde bisher nicht implementiert.\n"
 | 
			
		||||
msgstr "%s ist schon nicht implementiert.\n"
 | 
			
		||||
 | 
			
		||||
msgid "Successfully created backend"
 | 
			
		||||
msgstr "Das Backend wurde erfolgreich erstellt"
 | 
			
		||||
msgstr "Das Backend wurde erfolgreich hergestellt"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create backend"
 | 
			
		||||
msgstr "Das Backend wurde nicht erstellt"
 | 
			
		||||
msgstr "Das Backend wurde nicht erfolgreich hergestellt"
 | 
			
		||||
 | 
			
		||||
msgid "Successfully started server"
 | 
			
		||||
msgstr "Der Server wurde erfolgreich gestartet"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start server"
 | 
			
		||||
msgstr "Der Server wurde nicht gestartet"
 | 
			
		||||
msgstr "Der Server wurde nicht erfolgreich gestartet"
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr "Konnte keine Oberflächentextur bekommen"
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr "Konnte nicht einen Renderer an die Ausgabe nicht anbringen"
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr "Neues Ausgabegerät entdeckt"
 | 
			
		||||
msgstr "Neue Ausgabegerät entdeckt"
 | 
			
		||||
 | 
			
		||||
msgid "Could not add an output layout."
 | 
			
		||||
msgstr "Konnte keine neue Ausgabenanordnung hinzufügen."
 | 
			
		||||
msgid "Couldn't commit pending frame to output"
 | 
			
		||||
msgstr "Konnte sich nicht an den anstehenden Rahmen an die Ausgabe eintragen"
 | 
			
		||||
 | 
			
		||||
msgid "New keyboard detected"
 | 
			
		||||
msgstr "Neue Tastatur entdeckt"
 | 
			
		||||
| 
						 | 
				
			
			@ -128,25 +134,16 @@ msgid "New pointer detected"
 | 
			
		|||
msgstr "Neuer Zeiger entdeckt"
 | 
			
		||||
 | 
			
		||||
msgid "Unsupported input device detected"
 | 
			
		||||
msgstr "Unbekanntes Eingabegerät entdeckt"
 | 
			
		||||
msgstr "Unerkanntes Eingabegerät entdeckt"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr "Scheiterte mit Verbindung an ein Wayland-Display"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to get an event loop"
 | 
			
		||||
msgstr "Scheiterte eine Ereignisschleife zu bekommen"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr "Der Renderer wurde nicht erstellt"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr "Der Allokator wurde nicht erstellt"
 | 
			
		||||
msgstr "Scheiterte an eines Wayland-Displays verbinden"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr "Starten des Backend gescheitert"
 | 
			
		||||
 | 
			
		||||
msgid "Running Wayland compositor on Wayland display"
 | 
			
		||||
msgstr "Führe Wayland-Compositor auf Wayland-Display aus"
 | 
			
		||||
msgstr "Ausführt Wayland-Compositor auf Wayland-Display"
 | 
			
		||||
 | 
			
		||||
msgid "Display destroyed"
 | 
			
		||||
msgstr "Display zerstört"
 | 
			
		||||
| 
						 | 
				
			
			@ -154,32 +151,18 @@ msgstr "Display zerstört"
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr "Tastaturfokus ist jetzt auf Oberfläche"
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next toplevel"
 | 
			
		||||
msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr "Fokussiert jetzige Ansicht"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Couldn't commit pending frame to output"
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Der anstehende Frame konnte nicht an die Ausgabe übergeben werden"
 | 
			
		||||
 | 
			
		||||
#, fuzzy
 | 
			
		||||
#~ msgid "Failed to create wlr_backend"
 | 
			
		||||
#~ msgstr "wlr_backend wurde nicht erstellt"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Couldn't get a surface texture"
 | 
			
		||||
#~ msgstr "Konnte keine Oberflächentextur bekommen"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Couldn't attach renderer to output"
 | 
			
		||||
#~ msgstr "Konnte Renderer nicht an die Ausgabe binden"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Focusing current view"
 | 
			
		||||
#~ msgstr "Fokussiert jetzige Ansicht"
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr "Fokussiert nächste Ansicht"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Unable to parse XML file"
 | 
			
		||||
#~ msgstr "Konnte die XML-Datei nicht analysieren"
 | 
			
		||||
#~ msgstr "Konnte die XML-Datei nicht analisieren"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Invalid action \"%s\" requested. No such action exists."
 | 
			
		||||
#~ msgstr "Ungültige Aktion \"%s\" angefordert. Diese existiert nicht."
 | 
			
		||||
#~ msgstr "Ungültige Aktion \"%s\" angefordert. Es gibt keine solche."
 | 
			
		||||
 | 
			
		||||
#~ msgid "No"
 | 
			
		||||
#~ msgstr "Nein"
 | 
			
		||||
| 
						 | 
				
			
			@ -262,7 +245,7 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
#~ msgstr "Immer im _Hintergrund"
 | 
			
		||||
 | 
			
		||||
#~ msgid "_Send to desktop"
 | 
			
		||||
#~ msgstr "_Sende an Desktop"
 | 
			
		||||
#~ msgstr "_Verschieben nach"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Client menu"
 | 
			
		||||
#~ msgstr "Anwendungsmenü"
 | 
			
		||||
| 
						 | 
				
			
			@ -299,8 +282,8 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
#~ "Waybox was compiled without image loading support. Icons in menus will "
 | 
			
		||||
#~ "not be loaded."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Waybox wurde ohne Unterstützung für Bilder kompiliert. Diese werden in Menüs "
 | 
			
		||||
#~ "daher nicht geladen."
 | 
			
		||||
#~ "Waybox wurde ohne Bildladungsunterstützung kompiliert. Ikone in Menüs "
 | 
			
		||||
#~ "werden nicht geladen werden."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Conflict with key binding in config file"
 | 
			
		||||
#~ msgstr "Störende Tastenkombination in Konfigurationsdatei"
 | 
			
		||||
| 
						 | 
				
			
			@ -319,18 +302,18 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Attempted to access menu \"%s\" but it does not exist"
 | 
			
		||||
#~ msgstr "Versuchter Zugriff auf Menü \"%s\", welches nicht existiert"
 | 
			
		||||
#~ msgstr "Versuchter Zugriff auf Menü \"%s\", doch es existiert nicht"
 | 
			
		||||
 | 
			
		||||
#~ msgid "More..."
 | 
			
		||||
#~ msgstr "Mehr..."
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Invalid button \"%s\" in mouse binding"
 | 
			
		||||
#~ msgstr "Maus-Kombination mit ungültiger Taste \"%s\""
 | 
			
		||||
#~ msgstr "Maus-Einbindung mit ungültiger Taste \"%s\""
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Invalid context \"%s\" in mouse binding"
 | 
			
		||||
#~ msgstr "Maus-Kombination mit ungültigem Kontext \"%s\""
 | 
			
		||||
#~ msgstr "Maus-Einbindung mit ungültigem Kontext \"%s\""
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Unable to change to home directory \"%s\": %s"
 | 
			
		||||
| 
						 | 
				
			
			@ -338,8 +321,8 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
 | 
			
		||||
#~ msgid "Unable to find a valid config file, using some simple defaults"
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Keine gültige Konfigurationsdatei vorhanden, daher werden einfache "
 | 
			
		||||
#~ "Standardwerte benutzt"
 | 
			
		||||
#~ "Keine gültige Konfigurationsdatei vorhanden, benutze einfache "
 | 
			
		||||
#~ "Standardwerte"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Unable to load a theme."
 | 
			
		||||
#~ msgstr "Kann kein Thema laden."
 | 
			
		||||
| 
						 | 
				
			
			@ -379,12 +362,12 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
 | 
			
		||||
#~ msgid "  --debug-focus       Display debugging output for focus handling\n"
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "  --debug-focus       Debug-Informationen für Fokus-Handling anzeigen\n"
 | 
			
		||||
#~ "  --debug-focus       Fehlersuche-Ergebnis für Fokus-Handling anzeigen\n"
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "  --debug-session     Display debugging output for session management\n"
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "  --debug-session     Debug-Informationen für Sitzungsmanager anzeigen\n"
 | 
			
		||||
#~ "  --debug-session     Fehler-Ergebnis für Sitzungsmanager anzeigen\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
| 
						 | 
				
			
			@ -418,7 +401,7 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Unable to make directory \"%s\": %s"
 | 
			
		||||
#~ msgstr "Kann Verzeichnis \"%s\" nicht erstellen: %s"
 | 
			
		||||
#~ msgstr "Kann nicht Verzeichnis \"%s\" machen: %s"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Unable to save the session to \"%s\": %s"
 | 
			
		||||
| 
						 | 
				
			
			@ -426,10 +409,10 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Error while saving the session to \"%s\": %s"
 | 
			
		||||
#~ msgstr "Fehler beim Speichern der Sitzung in \"%s\": %s"
 | 
			
		||||
#~ msgstr "Fehler während die Sitzung in \"%s\" speichern: %s"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Not connected to a session manager"
 | 
			
		||||
#~ msgstr "Nicht mit Sitzungsmanager verbunden"
 | 
			
		||||
#~ msgstr "An einer Sitzungsmanager nicht verbindet"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Running %s"
 | 
			
		||||
| 
						 | 
				
			
			@ -437,7 +420,7 @@ msgstr "Fokussiere nächst höhere Ebene"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Invalid modifier key \"%s\" in key/mouse binding"
 | 
			
		||||
#~ msgstr "Ungültige Modifier-Taste \"%s\" in Tasten/Maus-Kombination"
 | 
			
		||||
#~ msgstr "Ungültige Modifier-Taste \"%s\" in Tasten/Maus-Einbindung"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#~ msgid "Invalid key code \"%s\" in key binding"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/el.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/el.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: Efstathios Iosifidis <iosifidis@opensuse.org>\n"
 | 
			
		||||
"Language-Team: Ελληνικά, Σύγχρονα <opensuse-translation-el@opensuse.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										58
									
								
								po/eo.po
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								po/eo.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,8 +7,8 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2024-01-25 21:21-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2024-01-25 21:35-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2022-02-22 21:21-0500\n"
 | 
			
		||||
"Last-Translator: Keith <keith@localhost>\n"
 | 
			
		||||
"Language-Team: Esperanto\n"
 | 
			
		||||
"Language: eo\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ msgid "ERROR: No configuration file found."
 | 
			
		|||
msgstr "ERARO: Neniu agordo-dosiero trovita."
 | 
			
		||||
 | 
			
		||||
msgid "Unable to evaluate expression"
 | 
			
		||||
msgstr "Ne eblis taksi esprimon"
 | 
			
		||||
msgstr "Ne povas taksi esprimon"
 | 
			
		||||
 | 
			
		||||
msgid "No nodesetval"
 | 
			
		||||
msgstr "Neniu nodara valoro"
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ msgid "Couldn't create new context!"
 | 
			
		|||
msgstr "Ne povis krei novan kuntekston!"
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't register the namespace"
 | 
			
		||||
msgstr "Ne eblis registri la nomspacon"
 | 
			
		||||
msgstr "Ne povas registri lo nomspacon"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Syntax: %s [options]\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -98,13 +98,13 @@ msgstr "%s postulas argumenton\n"
 | 
			
		|||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s hasn't been implemented yet.\n"
 | 
			
		||||
msgstr "%s ankoraŭ ne estas efektivigita.\n"
 | 
			
		||||
msgstr "%s ankoraŭ ne estas efektigita.\n"
 | 
			
		||||
 | 
			
		||||
msgid "Successfully created backend"
 | 
			
		||||
msgstr "Sukcese kreis servilan dorson"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create backend"
 | 
			
		||||
msgstr "Malsukcesis krei servilan dorson"
 | 
			
		||||
msgstr "Malsukesis krei servilan dorson"
 | 
			
		||||
 | 
			
		||||
msgid "Successfully started server"
 | 
			
		||||
msgstr "Sukcese startigis servilon"
 | 
			
		||||
| 
						 | 
				
			
			@ -112,11 +112,17 @@ msgstr "Sukcese startigis servilon"
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr "Malsukcesis startigi servilon"
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr "Nova eligilo malkovrita"
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr "Ne povis akiri surfacan teksturon"
 | 
			
		||||
 | 
			
		||||
msgid "Could not add an output layout."
 | 
			
		||||
msgstr "Ne eblis aldoni eligan aranĝon."
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr "Ne povis almeti bildigilon al eligo"
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr "Nova enigilo malkovrita"
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't commit pending frame to output"
 | 
			
		||||
msgstr "Ne povis surmeti atendantan framon sur eligon"
 | 
			
		||||
 | 
			
		||||
msgid "New keyboard detected"
 | 
			
		||||
msgstr "Nova klavaro malkovrita"
 | 
			
		||||
| 
						 | 
				
			
			@ -130,17 +136,8 @@ msgstr "Nerekonata enigilo malkovrita"
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr "Malsukcesis konektiĝi al Wayland-ekrano"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to get an event loop"
 | 
			
		||||
msgstr "Malsukcesis atingi evento-iteracion"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr "Malsukcesis krei servilan bildigilon"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr "Malsukcesis krei servilan asignilon"
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr "Malsukcesis startigi servilan dorson"
 | 
			
		||||
msgstr "Malsukesis startigi servilan dorson"
 | 
			
		||||
 | 
			
		||||
msgid "Running Wayland compositor on Wayland display"
 | 
			
		||||
msgstr "Plenumas Wayland-komponilon sur Wayland-ekrano"
 | 
			
		||||
| 
						 | 
				
			
			@ -151,24 +148,11 @@ msgstr "Ekrano finigita"
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr "Klavara fokuso nun estas sur surfaco"
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next toplevel"
 | 
			
		||||
msgstr "Fokusas la sekvan supran nivelon"
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr "Fokusas nunan vidon"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Couldn't commit pending frame to output"
 | 
			
		||||
#~ msgstr "Ne eblis surmeti atendantan framon sur eligon"
 | 
			
		||||
 | 
			
		||||
#, fuzzy
 | 
			
		||||
#~ msgid "Failed to create wlr_backend"
 | 
			
		||||
#~ msgstr "Malsukesis krei servilan dorson"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Couldn't get a surface texture"
 | 
			
		||||
#~ msgstr "Ne povis akiri surfacan teksturon"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Couldn't attach renderer to output"
 | 
			
		||||
#~ msgstr "Ne povis almeti bildigilon al eligo"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Focusing current view"
 | 
			
		||||
#~ msgstr "Fokusas nunan vidon"
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr "Fokusas la sekvan vidon"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Unable to parse XML file"
 | 
			
		||||
#~ msgstr "Ne povas analizi XML-dosieron"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								po/es.po
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								po/es.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,8 +11,8 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2022-12-06 22:35-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: Nicolás de la Torre <ndelatorre@gmail.com>\n"
 | 
			
		||||
"Language-Team: español <es@li.org>\n"
 | 
			
		||||
"Language: es\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ msgstr ""
 | 
			
		|||
msgid "Couldn't register the namespace"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
#, fuzzy, c-format
 | 
			
		||||
msgid "Syntax: %s [options]\n"
 | 
			
		||||
msgstr "Sintaxis: % [opciones]\n"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +114,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,12 +138,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +150,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/et.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/et.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: mihkel <turakas@gmail.com>\n"
 | 
			
		||||
"Language-Team: Estonian <et@li.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/eu.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/eu.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: Inko I. A. <inkoia@gmail.com>\n"
 | 
			
		||||
"Language-Team: Inko I. A. <inkoia@gmail.com>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/fi.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/fi.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -10,7 +10,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: Lauri Hakko <aperculum@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/fr.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/fr.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,7 +11,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: Cyrille Bagard <nocbos@gmail.com>\n"
 | 
			
		||||
"Language-Team: français <fr@li.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +113,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,12 +137,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,6 +149,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/gl_ES.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/gl_ES.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 19:33-0400\n"
 | 
			
		||||
"Last-Translator: Javier Mancebo <palleiros@yahoo.es>\n"
 | 
			
		||||
"Language-Team: Galician\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +106,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +130,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +142,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/he.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/he.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 10:30-0400\n"
 | 
			
		||||
"Last-Translator: Eli Zaretskii <eliz@gnu.org>\n"
 | 
			
		||||
"Language-Team: Rahut <genghiskhan@gmx.ca>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/hr.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/hr.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,7 +6,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:07-0400\n"
 | 
			
		||||
"Last-Translator: boljsa <asjlob AT vip.hr>\n"
 | 
			
		||||
"Language-Team:  <asjlob AT vip.hr>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/hu.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/hu.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:42-0400\n"
 | 
			
		||||
"Last-Translator: Laszlo Dvornik <rezuri@zoho.com>\n"
 | 
			
		||||
"Language-Team: Hungarian\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/ia.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/ia.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,7 +6,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:42-0400\n"
 | 
			
		||||
"Last-Translator: Nik Kalach <nikka@fedoraproject.org>\n"
 | 
			
		||||
"Language-Team: Interlingua (International Auxiliary Language Association) "
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/it.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/it.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:08-0400\n"
 | 
			
		||||
"Last-Translator: Davide Truffa <davide@catoblepa.org>\n"
 | 
			
		||||
"Language-Team: Italian <tp@lists.linux.it>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/ja.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/ja.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:08-0400\n"
 | 
			
		||||
"Last-Translator: Ryoichiro Suzuki <ryoichiro.suzuki@gmail.com>\n"
 | 
			
		||||
"Language-Team: Japanese <ja@li.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/lt.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/lt.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:42-0400\n"
 | 
			
		||||
"Last-Translator: Algimantas Margevičius <margevicius.algimantas@gmail.com>\n"
 | 
			
		||||
"Language-Team: Lietuvių <>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -128,12 +134,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +146,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/lv.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/lv.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:08-0400\n"
 | 
			
		||||
"Last-Translator: Einars Sprugis <einars8@gmail.com>\n"
 | 
			
		||||
"Language-Team: Latvian <locale@laka.lv>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,11 @@
 | 
			
		|||
i18n = import('i18n')
 | 
			
		||||
add_project_arguments('-DGETTEXT_PACKAGE="' + meson.project_name().to_lower() + '"',
 | 
			
		||||
  '-DLOCALEDIR="' + get_option('prefix') / get_option('localedir') + '"',
 | 
			
		||||
  '-DUSE_NLS=1', language: 'c')
 | 
			
		||||
 | 
			
		||||
i18n = import('i18n', required: false)
 | 
			
		||||
if i18n.found()
 | 
			
		||||
  i18n.gettext(meson.project_name().to_lower(),
 | 
			
		||||
  language:'c')
 | 
			
		||||
i18n.gettext(meson.project_name().to_lower(),
 | 
			
		||||
  args: ['--directory=' + source_root,
 | 
			
		||||
    '--add-comments=TRANSLATORS',
 | 
			
		||||
    '--no-location',
 | 
			
		||||
    '--keyword=_',
 | 
			
		||||
    '--msgid-bugs=https://github.com/wizbright/waybox/issues']
 | 
			
		||||
)
 | 
			
		||||
endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/nl.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/nl.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,7 +11,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:08-0400\n"
 | 
			
		||||
"Last-Translator: Pjotr <pjotrvertaalt@gmail.com>\n"
 | 
			
		||||
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +112,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,12 +136,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +148,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/no.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/no.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:23-0400\n"
 | 
			
		||||
"Last-Translator: Michael Kjelbergvik Thung <postlogic@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/pl.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/pl.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,7 +11,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:08-0400\n"
 | 
			
		||||
"Last-Translator: Jakub Błażejczyk\n"
 | 
			
		||||
"Language-Team: polski <kuboslawik@gmail.com>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +111,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,12 +135,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +147,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/pt.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/pt.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:42-0400\n"
 | 
			
		||||
"Last-Translator: Sérgio Marques <smarquespt@gmail.com>\n"
 | 
			
		||||
"Language-Team: \n"
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +112,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,12 +136,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +148,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/pt_BR.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/pt_BR.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:45-0400\n"
 | 
			
		||||
"Last-Translator: Og Maciel <ogmaciel@gnome.org>\n"
 | 
			
		||||
"Language-Team: Brazilian Portuguese <gnome-l10n-br@listas.cipsga.org.br>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +111,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,12 +135,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +147,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/ro.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/ro.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:09-0400\n"
 | 
			
		||||
"Last-Translator: Radu Feflea <rfeflea@googlemail.com>\n"
 | 
			
		||||
"Language-Team: none\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/ru.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/ru.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:09-0400\n"
 | 
			
		||||
"Last-Translator: Moroz Sergey L. <se.seam@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/sk.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/sk.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:09-0400\n"
 | 
			
		||||
"Last-Translator: Frantisek Elias <elias.frantisek@gmail.com>\n"
 | 
			
		||||
"Language-Team: Slovak <sk@sk.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/sr.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/sr.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:09-0400\n"
 | 
			
		||||
"Last-Translator: Jay Alexander Fleming <tito.nehru.naser@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -128,12 +134,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +146,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:09-0400\n"
 | 
			
		||||
"Last-Translator: Jay A. Fleming <tito.nehru.naser@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -128,12 +134,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +146,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/sv.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/sv.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 18:42-0400\n"
 | 
			
		||||
"Last-Translator: Mikael Magnusson <mikachu@icculus.org>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/tr.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/tr.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:09-0400\n"
 | 
			
		||||
"Last-Translator: Muhammet Kara <muhammet.k@gmail.com>\n"
 | 
			
		||||
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +109,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,12 +133,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +145,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/uk.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/uk.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:10-0400\n"
 | 
			
		||||
"Last-Translator: Serhiy Lysovenko <lisovenko.s[at]gmail[dot]com>\n"
 | 
			
		||||
"Language-Team: Ukrainian <linux.org.ua>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +106,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +130,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +142,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/vi.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/vi.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,7 +7,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2022-02-01 21:17-0500\n"
 | 
			
		||||
"Last-Translator: Quan Tran <qeed.quan@gmail.com>\n"
 | 
			
		||||
"Language-Team: None\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +106,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +130,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +142,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: waybox\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2024-01-25 21:21-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
			
		||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
			
		||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -104,10 +104,16 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Could not add an output layout."
 | 
			
		||||
msgid "Couldn't commit pending frame to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New keyboard detected"
 | 
			
		||||
| 
						 | 
				
			
			@ -122,15 +128,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to get an event loop"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,5 +140,8 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next toplevel"
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/zh_CN.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/zh_CN.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2020-03-10 14:10-0400\n"
 | 
			
		||||
"Last-Translator: zhou sf <sxzzsf@gmail.com>\n"
 | 
			
		||||
"Language-Team: Simplified Chinese\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,12 +132,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +144,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								po/zh_TW.po
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								po/zh_TW.po
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,7 +8,7 @@ msgid ""
 | 
			
		|||
msgstr ""
 | 
			
		||||
"Project-Id-Version: Waybox 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2022-12-06 22:27-0500\n"
 | 
			
		||||
"POT-Creation-Date: 2022-02-22 21:19-0500\n"
 | 
			
		||||
"PO-Revision-Date: 2022-02-01 21:14-0500\n"
 | 
			
		||||
"Last-Translator: 洪任諭 <pcman.tw@gmail.com>\n"
 | 
			
		||||
"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,12 @@ msgstr ""
 | 
			
		|||
msgid "Failed to start server"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't get a surface texture"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Couldn't attach renderer to output"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "New output device detected"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +131,6 @@ msgstr ""
 | 
			
		|||
msgid "Failed to connect to a Wayland display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create renderer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to create allocator"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Failed to start backend"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +143,9 @@ msgstr ""
 | 
			
		|||
msgid "Keyboard focus is now on surface"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing current view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Focusing next view"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										49
									
								
								protocol/idle.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								protocol/idle.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<protocol name="idle">
 | 
			
		||||
  <copyright><![CDATA[
 | 
			
		||||
    Copyright (C) 2015 Martin Gräßlin
 | 
			
		||||
 | 
			
		||||
    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 2.1 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
  ]]></copyright>
 | 
			
		||||
  <interface  name="org_kde_kwin_idle" version="1">
 | 
			
		||||
      <description summary="User idle time manager">
 | 
			
		||||
        This interface allows to monitor user idle time on a given seat. The interface
 | 
			
		||||
        allows to register timers which trigger after no user activity was registered
 | 
			
		||||
        on the seat for a given interval. It notifies when user activity resumes.
 | 
			
		||||
 | 
			
		||||
        This is useful for applications wanting to perform actions when the user is not
 | 
			
		||||
        interacting with the system, e.g. chat applications setting the user as away, power
 | 
			
		||||
        management features to dim screen, etc..
 | 
			
		||||
      </description>
 | 
			
		||||
      <request name="get_idle_timeout">
 | 
			
		||||
        <arg name="id" type="new_id" interface="org_kde_kwin_idle_timeout"/>
 | 
			
		||||
        <arg name="seat" type="object" interface="wl_seat"/>
 | 
			
		||||
        <arg name="timeout" type="uint" summary="The idle timeout in msec"/>
 | 
			
		||||
      </request>
 | 
			
		||||
  </interface>
 | 
			
		||||
  <interface name="org_kde_kwin_idle_timeout" version="1">
 | 
			
		||||
      <request name="release" type="destructor">
 | 
			
		||||
        <description summary="release the timeout object"/>
 | 
			
		||||
      </request>
 | 
			
		||||
      <request name="simulate_user_activity">
 | 
			
		||||
          <description summary="Simulates user activity for this timeout, behaves just like real user activity on the seat"/>
 | 
			
		||||
      </request>
 | 
			
		||||
      <event name="idle">
 | 
			
		||||
          <description summary="Triggered when there has not been any user activity in the requested idle time interval"/>
 | 
			
		||||
      </event>
 | 
			
		||||
      <event name="resumed">
 | 
			
		||||
          <description summary="Triggered on the first user activity after an idle event"/>
 | 
			
		||||
      </event>
 | 
			
		||||
  </interface>
 | 
			
		||||
</protocol>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir')
 | 
			
		||||
 | 
			
		||||
wayland_scanner_dep = dependency('wayland-scanner', version: '>=1.15')
 | 
			
		||||
wayland_scanner = find_program(wayland_scanner_dep.get_variable(pkgconfig: 'wayland_scanner'))
 | 
			
		||||
wayland_scanner = find_program('wayland-scanner', version: '>= 1.15')
 | 
			
		||||
 | 
			
		||||
wayland_scanner_server = generator(
 | 
			
		||||
  wayland_scanner,
 | 
			
		||||
| 
						 | 
				
			
			@ -23,20 +22,23 @@ wayland_scanner_client = generator(
 | 
			
		|||
 | 
			
		||||
protocols = [
 | 
			
		||||
  [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'staging/ext-idle-notify/ext-idle-notify-v1.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
 | 
			
		||||
  'wlr-gamma-control-unstable-v1.xml',
 | 
			
		||||
  'wlr-layer-shell-unstable-v1.xml',
 | 
			
		||||
  'idle.xml',
 | 
			
		||||
  'wlr-screencopy-unstable-v1.xml',
 | 
			
		||||
  'wlr-layer-shell-unstable-v1.xml',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
client_protocols = [
 | 
			
		||||
  [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
 | 
			
		||||
  [wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
 | 
			
		||||
  'wlr-layer-shell-unstable-v1.xml',
 | 
			
		||||
  'idle.xml',
 | 
			
		||||
  'wlr-screencopy-unstable-v1.xml',
 | 
			
		||||
  'wlr-layer-shell-unstable-v1.xml',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
wl_protos_src = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 763 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 749 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 142 KiB  | 
| 
						 | 
				
			
			@ -1,15 +1,8 @@
 | 
			
		|||
#include <libxml/parser.h>
 | 
			
		||||
#include <libxml/xpath.h>
 | 
			
		||||
#include <libxml/xpathInternals.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
static unsigned long strtoulong(char *s) {
 | 
			
		||||
	if (s)
 | 
			
		||||
		return strtoul(s, (char **) NULL, 10);
 | 
			
		||||
	else return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *parse_xpath_expr(char *expr, xmlXPathContextPtr ctxt) {
 | 
			
		||||
	xmlXPathObjectPtr object = xmlXPathEvalExpression((xmlChar *) expr, ctxt);
 | 
			
		||||
	if (object == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +25,7 @@ static xmlChar *get_attribute(xmlNode *node, char *attr_name) {
 | 
			
		|||
	xmlAttr *attr = node->properties;
 | 
			
		||||
	while (attr && strcmp((char *) attr->name, attr_name) != 0)
 | 
			
		||||
		attr = attr->next;
 | 
			
		||||
	return attr ? attr->children->content : (xmlChar *) "";
 | 
			
		||||
	return attr->children->content;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void get_action(xmlNode *new_node, struct wb_key_binding *key_bind) {
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +61,7 @@ static void get_action(xmlNode *new_node, struct wb_key_binding *key_bind) {
 | 
			
		|||
			key_bind->cmd = (char *) xmlStrdup(cur_node->children->content);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt) {
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +146,6 @@ bool init_config(struct wb_server *server) {
 | 
			
		|||
 | 
			
		||||
	doc = xmlReadFile(rc_file, NULL, XML_PARSE_RECOVER);
 | 
			
		||||
	wlr_log(WLR_INFO, "Using config file %s", rc_file);
 | 
			
		||||
	setenv("WAYBOX_CONFIG_FILE", rc_file, true);
 | 
			
		||||
	free(rc_file);
 | 
			
		||||
	if (doc == NULL) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Unable to parse the configuration file. Consult stderr for more information."));
 | 
			
		||||
| 
						 | 
				
			
			@ -168,44 +161,24 @@ bool init_config(struct wb_server *server) {
 | 
			
		|||
		wlr_log(WLR_INFO, "%s", _("Couldn't register the namespace"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config->keyboard_layout.use_config = parse_xpath_expr("//ob:keyboard//ob:xkb", ctxt) != NULL;
 | 
			
		||||
	config->keyboard_layout.use_config = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout", ctxt) != NULL;
 | 
			
		||||
 | 
			
		||||
	if (config->keyboard_layout.use_config) {
 | 
			
		||||
		config->keyboard_layout.layout = parse_xpath_expr("//ob:keyboard//ob:xkb//ob:layout", ctxt);
 | 
			
		||||
		config->keyboard_layout.model = parse_xpath_expr("//ob:keyboard//ob:xkb//ob:model", ctxt);
 | 
			
		||||
		config->keyboard_layout.options = parse_xpath_expr("//ob:keyboard//ob:xkb//ob:options", ctxt);
 | 
			
		||||
		config->keyboard_layout.rules = parse_xpath_expr("//ob:keyboard//ob:xkb//ob:rules", ctxt);
 | 
			
		||||
		config->keyboard_layout.variant = parse_xpath_expr("//ob:keyboard//ob:xkb//ob:variant", ctxt);
 | 
			
		||||
		config->keyboard_layout.layout = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout//ob:layout", ctxt);
 | 
			
		||||
		config->keyboard_layout.model = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout//ob:model", ctxt);
 | 
			
		||||
		config->keyboard_layout.options = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout//ob:options", ctxt);
 | 
			
		||||
		config->keyboard_layout.rules = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout//ob:rules", ctxt);
 | 
			
		||||
		config->keyboard_layout.variant = parse_xpath_expr("//ob:keyboard//ob:keyboardLayout//ob:variant", ctxt);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config->libinput_config.use_config = parse_xpath_expr("//ob:mouse//ob:libinput", ctxt) != NULL;
 | 
			
		||||
	if (config->libinput_config.use_config) {
 | 
			
		||||
		config->libinput_config.accel_profile = parse_xpath_expr("//ob:mouse//ob:libinput/ob:accelProfile", ctxt);
 | 
			
		||||
		config->libinput_config.accel_speed = parse_xpath_expr("//ob:mouse//ob:libinput/ob:accelSpeed", ctxt);
 | 
			
		||||
		config->libinput_config.calibration_matrix = parse_xpath_expr("//ob:mouse//ob:libinput/ob:calibrationMatrix", ctxt);
 | 
			
		||||
		config->libinput_config.click_method = parse_xpath_expr("//ob:mouse//ob:libinput/ob:clickMethod", ctxt);
 | 
			
		||||
		config->libinput_config.dwt = parse_xpath_expr("//ob:mouse//ob:libinput/ob:disableWhileTyping", ctxt);
 | 
			
		||||
		config->libinput_config.dwtp = parse_xpath_expr("//ob:mouse//ob:libinput/ob:disableWhileTrackpointing", ctxt);
 | 
			
		||||
		config->libinput_config.left_handed = parse_xpath_expr("//ob:mouse//ob:libinput/ob:leftHanded", ctxt);
 | 
			
		||||
		config->libinput_config.middle_emulation = parse_xpath_expr("//ob:mouse//ob:libinput/ob:middleEmulation", ctxt);
 | 
			
		||||
		config->libinput_config.natural_scroll = parse_xpath_expr("//ob:mouse//ob:libinput/ob:naturalScroll", ctxt);
 | 
			
		||||
		config->libinput_config.scroll_button = parse_xpath_expr("//ob:mouse//ob:libinput/ob:scrollButton", ctxt);
 | 
			
		||||
		config->libinput_config.scroll_button_lock = parse_xpath_expr("//ob:mouse//ob:libinput/ob:scrollButtonLock", ctxt);
 | 
			
		||||
		config->libinput_config.scroll_method = parse_xpath_expr("//ob:mouse//ob:libinput/ob:scrollMethod", ctxt);
 | 
			
		||||
		config->libinput_config.tap = parse_xpath_expr("//ob:mouse//ob:libinput/ob:tap", ctxt);
 | 
			
		||||
		config->libinput_config.tap_button_map = parse_xpath_expr("//ob:mouse//ob:libinput/ob:tapButtonMap", ctxt);
 | 
			
		||||
		config->libinput_config.tap_drag = parse_xpath_expr("//ob:mouse//ob:libinput/ob:tapDrag", ctxt);
 | 
			
		||||
		config->libinput_config.tap_drag = parse_xpath_expr("//ob:mouse//ob:libinput/ob:tapDragLock", ctxt);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!parse_key_bindings(config, ctxt)) {
 | 
			
		||||
		xmlFreeDoc(doc);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config->margins.bottom = strtoulong(parse_xpath_expr("//ob:margins/ob:bottom", ctxt));
 | 
			
		||||
	config->margins.left = strtoulong(parse_xpath_expr("//ob:margins/ob:left", ctxt));
 | 
			
		||||
	config->margins.right = strtoulong(parse_xpath_expr("//ob:margins/ob:right", ctxt));
 | 
			
		||||
	config->margins.top = strtoulong(parse_xpath_expr("//ob:margins/ob:top", ctxt));
 | 
			
		||||
	config->margins.bottom = strtoul(parse_xpath_expr("//ob:margins/ob:bottom", ctxt), NULL, 10);
 | 
			
		||||
	config->margins.left = strtoul(parse_xpath_expr("//ob:margins/ob:left", ctxt), NULL, 10);
 | 
			
		||||
	config->margins.right = strtoul(parse_xpath_expr("//ob:margins/ob:right", ctxt), NULL, 10);
 | 
			
		||||
	config->margins.top = strtoul(parse_xpath_expr("//ob:margins/ob:top", ctxt), NULL, 10);
 | 
			
		||||
 | 
			
		||||
	server->config = config;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,16 +4,16 @@
 | 
			
		|||
#include "waybox/server.h"
 | 
			
		||||
 | 
			
		||||
enum action_type {
 | 
			
		||||
	ACTION_EXIT = 1 << 0,
 | 
			
		||||
	ACTION_NEXT_WINDOW = 1 << 1,
 | 
			
		||||
	ACTION_EXECUTE = 1 << 2,
 | 
			
		||||
	ACTION_PREVIOUS_WINDOW = 1 << 3,
 | 
			
		||||
	ACTION_CLOSE = 1 << 4,
 | 
			
		||||
	ACTION_RECONFIGURE = 1 << 5,
 | 
			
		||||
	ACTION_TOGGLE_MAXIMIZE = 1 << 6,
 | 
			
		||||
	ACTION_ICONIFY = 1 << 7,
 | 
			
		||||
	ACTION_SHADE = 1 << 8,
 | 
			
		||||
	ACTION_UNSHADE = 1 << 9,
 | 
			
		||||
	ACTION_CLOSE = 1,
 | 
			
		||||
	ACTION_EXECUTE = 2,
 | 
			
		||||
	ACTION_EXIT = 4,
 | 
			
		||||
	ACTION_ICONIFY = 8,
 | 
			
		||||
	ACTION_NEXT_WINDOW = 16,
 | 
			
		||||
	ACTION_PREVIOUS_WINDOW = 32,
 | 
			
		||||
	ACTION_RECONFIGURE = 64,
 | 
			
		||||
	ACTION_SHADE = 128,
 | 
			
		||||
	ACTION_TOGGLE_MAXIMIZE = 256,
 | 
			
		||||
	ACTION_UNSHADE = 512,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wb_config {
 | 
			
		||||
| 
						 | 
				
			
			@ -27,26 +27,6 @@ struct wb_config {
 | 
			
		|||
 | 
			
		||||
		bool use_config;
 | 
			
		||||
	} keyboard_layout;
 | 
			
		||||
	struct {
 | 
			
		||||
		char *accel_profile;
 | 
			
		||||
		char *accel_speed;
 | 
			
		||||
		char *calibration_matrix;
 | 
			
		||||
		char *click_method;
 | 
			
		||||
		char *dwt;
 | 
			
		||||
		char *dwtp;
 | 
			
		||||
		char *left_handed;
 | 
			
		||||
		char *middle_emulation;
 | 
			
		||||
		char *natural_scroll;
 | 
			
		||||
		char *scroll_button;
 | 
			
		||||
		char *scroll_button_lock;
 | 
			
		||||
		char *scroll_method;
 | 
			
		||||
		char *tap;
 | 
			
		||||
		char *tap_button_map;
 | 
			
		||||
		char *tap_drag;
 | 
			
		||||
		char *tap_drag_lock;
 | 
			
		||||
 | 
			
		||||
		bool use_config;
 | 
			
		||||
	} libinput_config;
 | 
			
		||||
	struct {
 | 
			
		||||
		int bottom;
 | 
			
		||||
		int left;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,25 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include "waybox/cursor.h"
 | 
			
		||||
#include "waybox/xdg_shell.h"
 | 
			
		||||
 | 
			
		||||
void reset_cursor_mode(struct wb_server *server) {
 | 
			
		||||
	/* Reset the cursor mode to passthrough */
 | 
			
		||||
	server->cursor->cursor_mode = WB_CURSOR_PASSTHROUGH;
 | 
			
		||||
	server->grabbed_toplevel = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void process_cursor_move(struct wb_server *server) {
 | 
			
		||||
	/* Move the grabbed toplevel to the new position. */
 | 
			
		||||
	struct wb_toplevel *toplevel = server->grabbed_toplevel;
 | 
			
		||||
	if (toplevel->scene_tree->node.type == WLR_SCENE_NODE_TREE) {
 | 
			
		||||
		toplevel->geometry.x = server->cursor->cursor->x - server->grab_x;
 | 
			
		||||
		toplevel->geometry.y = server->cursor->cursor->y - server->grab_y;
 | 
			
		||||
		wlr_scene_node_set_position(&toplevel->scene_tree->node,
 | 
			
		||||
				toplevel->geometry.x, toplevel->geometry.y);
 | 
			
		||||
	}
 | 
			
		||||
	/* Move the grabbed view to the new position. */
 | 
			
		||||
	server->grabbed_view->current_position.x = server->cursor->cursor->x - server->grab_x;
 | 
			
		||||
	server->grabbed_view->current_position.y = server->cursor->cursor->y - server->grab_y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void process_cursor_resize(struct wb_server *server) {
 | 
			
		||||
	struct wb_toplevel *toplevel = server->grabbed_toplevel;
 | 
			
		||||
	struct wb_view *view = server->grabbed_view;
 | 
			
		||||
	double border_x = server->cursor->cursor->x - server->grab_x;
 | 
			
		||||
	double border_y = server->cursor->cursor->y - server->grab_y;
 | 
			
		||||
	int new_left = server->grab_geo_box.x;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,20 +40,18 @@ static void process_cursor_resize(struct wb_server *server) {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 19, 0)
 | 
			
		||||
	struct wlr_box geo_box = toplevel->xdg_toplevel->base->geometry;
 | 
			
		||||
#else
 | 
			
		||||
	struct wlr_box geo_box;
 | 
			
		||||
	wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box);
 | 
			
		||||
#endif
 | 
			
		||||
	toplevel->geometry.x = new_left - geo_box.x;
 | 
			
		||||
	toplevel->geometry.y = new_top - geo_box.y;
 | 
			
		||||
		wlr_scene_node_set_position(&toplevel->scene_tree->node,
 | 
			
		||||
				toplevel->geometry.x, toplevel->geometry.y);
 | 
			
		||||
	wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
 | 
			
		||||
	view->current_position.x = new_left - geo_box.x;
 | 
			
		||||
	view->current_position.y = new_top - geo_box.y;
 | 
			
		||||
 | 
			
		||||
	int new_width = new_right - new_left;
 | 
			
		||||
	int new_height = new_bottom - new_top;
 | 
			
		||||
	wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, new_width, new_height);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	wlr_xdg_toplevel_set_size(view->xdg_toplevel, new_width, new_height);
 | 
			
		||||
#else
 | 
			
		||||
	wlr_xdg_toplevel_set_size(view->xdg_surface, new_width, new_height);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void process_cursor_motion(struct wb_server *server, uint32_t time) {
 | 
			
		||||
| 
						 | 
				
			
			@ -76,18 +64,18 @@ static void process_cursor_motion(struct wb_server *server, uint32_t time) {
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Otherwise, find the toplevel under the pointer and send the event along. */
 | 
			
		||||
	/* Otherwise, find the view under the pointer and send the event along. */
 | 
			
		||||
	double sx, sy;
 | 
			
		||||
	struct wlr_seat *seat = server->seat->seat;
 | 
			
		||||
	struct wlr_surface *surface = NULL;
 | 
			
		||||
	struct wb_toplevel *toplevel = get_toplevel_at(server,
 | 
			
		||||
	struct wb_view *view = desktop_view_at(server,
 | 
			
		||||
			server->cursor->cursor->x, server->cursor->cursor->y, &surface, &sx, &sy);
 | 
			
		||||
	if (!toplevel) {
 | 
			
		||||
		/* If there's no toplevel under the cursor, set the cursor image to a
 | 
			
		||||
	if (!view) {
 | 
			
		||||
		/* If there's no view under the cursor, set the cursor image to a
 | 
			
		||||
		 * default. This is what makes the cursor image appear when you move it
 | 
			
		||||
		 * around the screen, not over any toplevels. */
 | 
			
		||||
		wlr_cursor_set_xcursor(
 | 
			
		||||
				server->cursor->cursor, server->cursor->xcursor_manager, "default");
 | 
			
		||||
		 * around the screen, not over any views. */
 | 
			
		||||
		wlr_xcursor_manager_set_cursor_image(
 | 
			
		||||
				server->cursor->xcursor_manager, "left_ptr", server->cursor->cursor);
 | 
			
		||||
	}
 | 
			
		||||
	if (surface) {
 | 
			
		||||
		/*
 | 
			
		||||
| 
						 | 
				
			
			@ -105,25 +93,19 @@ static void process_cursor_motion(struct wb_server *server, uint32_t time) {
 | 
			
		|||
		 * the last client to have the cursor over it. */
 | 
			
		||||
		wlr_seat_pointer_clear_focus(seat);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_idle_notifier_v1_notify_activity(server->idle_notifier, seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_cursor *cursor =
 | 
			
		||||
		wl_container_of(listener, cursor, cursor_motion);
 | 
			
		||||
	struct wlr_pointer_motion_event *event = data;
 | 
			
		||||
	wlr_cursor_move(cursor->cursor, &event->pointer->base,
 | 
			
		||||
			event->delta_x, event->delta_y);
 | 
			
		||||
	struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_motion);
 | 
			
		||||
	struct wlr_event_pointer_motion *event = data;
 | 
			
		||||
	wlr_cursor_move(cursor->cursor, event->device, event->delta_x, event->delta_y);
 | 
			
		||||
	process_cursor_motion(cursor->server, event->time_msec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_cursor *cursor =
 | 
			
		||||
		wl_container_of(listener, cursor, cursor_motion_absolute);
 | 
			
		||||
	struct wlr_pointer_motion_absolute_event *event = data;
 | 
			
		||||
	wlr_cursor_warp_absolute(cursor->cursor, &event->pointer->base,
 | 
			
		||||
			event->x, event->y);
 | 
			
		||||
	struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_motion_absolute);
 | 
			
		||||
	struct wlr_event_pointer_motion_absolute *event = data;
 | 
			
		||||
	wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
 | 
			
		||||
	process_cursor_motion(cursor->server, event->time_msec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,23 +114,21 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
 | 
			
		|||
	 * event. */
 | 
			
		||||
	struct wb_cursor *cursor =
 | 
			
		||||
		wl_container_of(listener, cursor, cursor_button);
 | 
			
		||||
	struct wlr_pointer_button_event *event = data;
 | 
			
		||||
	struct wlr_event_pointer_button *event = data;
 | 
			
		||||
	/* Notify the client with pointer focus that a button press has occurred */
 | 
			
		||||
	wlr_seat_pointer_notify_button(cursor->server->seat->seat,
 | 
			
		||||
			event->time_msec, event->button, event->state);
 | 
			
		||||
	double sx, sy;
 | 
			
		||||
	struct wlr_surface *surface = NULL;
 | 
			
		||||
	struct wb_toplevel *toplevel = get_toplevel_at(cursor->server,
 | 
			
		||||
	struct wb_view *view = desktop_view_at(cursor->server,
 | 
			
		||||
			cursor->server->cursor->cursor->x, cursor->server->cursor->cursor->y, &surface, &sx, &sy);
 | 
			
		||||
	if (event->state == WL_POINTER_BUTTON_STATE_RELEASED) {
 | 
			
		||||
	if (event->state == WLR_BUTTON_RELEASED) {
 | 
			
		||||
		/* If you released any buttons, we exit interactive move/resize mode. */
 | 
			
		||||
		reset_cursor_mode(cursor->server);
 | 
			
		||||
		cursor->cursor_mode = WB_CURSOR_PASSTHROUGH;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Focus that client if the button was _pressed_ */
 | 
			
		||||
		focus_toplevel(toplevel);
 | 
			
		||||
		focus_view(view, surface);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_idle_notifier_v1_notify_activity(cursor->server->idle_notifier, cursor->server->seat->seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_cursor_axis(struct wl_listener *listener, void *data) {
 | 
			
		||||
| 
						 | 
				
			
			@ -156,11 +136,11 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) {
 | 
			
		|||
	 * for example when you move the scroll wheel. */
 | 
			
		||||
	struct wb_cursor *cursor =
 | 
			
		||||
		wl_container_of(listener, cursor, cursor_axis);
 | 
			
		||||
	struct wlr_pointer_axis_event *event = data;
 | 
			
		||||
	struct wlr_event_pointer_axis *event = data;
 | 
			
		||||
	/* Notify the client with pointer focus of the axis event. */
 | 
			
		||||
	wlr_seat_pointer_notify_axis(cursor->server->seat->seat,
 | 
			
		||||
			event->time_msec, event->orientation, event->delta,
 | 
			
		||||
			event->delta_discrete, event->source, event->relative_direction);
 | 
			
		||||
			event->delta_discrete, event->source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_cursor_frame(struct wl_listener *listener, void *data) {
 | 
			
		||||
| 
						 | 
				
			
			@ -196,12 +176,12 @@ static void handle_cursor_request(struct wl_listener *listener, void *data) {
 | 
			
		|||
struct wb_cursor *wb_cursor_create(struct wb_server *server) {
 | 
			
		||||
	struct wb_cursor *cursor = malloc(sizeof(struct wb_cursor));
 | 
			
		||||
	cursor->cursor = wlr_cursor_create();
 | 
			
		||||
	cursor->cursor_mode = WB_CURSOR_PASSTHROUGH;
 | 
			
		||||
	cursor->server = server;
 | 
			
		||||
 | 
			
		||||
	const char *xcursor_size = getenv("XCURSOR_SIZE");
 | 
			
		||||
	cursor->xcursor_manager = wlr_xcursor_manager_create(getenv("XCURSOR_THEME"),
 | 
			
		||||
				xcursor_size ? strtoul(xcursor_size, (char **) NULL, 10) : 24);
 | 
			
		||||
	wlr_xcursor_manager_load(cursor->xcursor_manager, 1);
 | 
			
		||||
 | 
			
		||||
	cursor->cursor_motion.notify = handle_cursor_motion;
 | 
			
		||||
	wl_signal_add(&cursor->cursor->events.motion, &cursor->cursor_motion);
 | 
			
		||||
| 
						 | 
				
			
			@ -232,14 +212,6 @@ void wb_cursor_destroy(struct wb_cursor *cursor) {
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&cursor->request_cursor.link);
 | 
			
		||||
	wl_list_remove(&cursor->cursor_motion.link);
 | 
			
		||||
	wl_list_remove(&cursor->cursor_motion_absolute.link);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&cursor->cursor_button.link);
 | 
			
		||||
	wl_list_remove(&cursor->cursor_axis.link);
 | 
			
		||||
	wl_list_remove(&cursor->cursor_frame.link);
 | 
			
		||||
 | 
			
		||||
	wlr_xcursor_manager_destroy(cursor->xcursor_manager);
 | 
			
		||||
	wlr_cursor_destroy(cursor->cursor);
 | 
			
		||||
	free(cursor);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,27 +1,30 @@
 | 
			
		|||
#include "decoration.h"
 | 
			
		||||
 | 
			
		||||
static void destroy_xdg_toplevel_decoration(struct wl_listener *listener, void *data) {
 | 
			
		||||
static void destroy_xdg_toplevel_decoration(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct wb_decoration *decoration = wl_container_of(listener, decoration, toplevel_decoration_destroy);
 | 
			
		||||
	wl_list_remove(&decoration->toplevel_decoration_destroy.link);
 | 
			
		||||
	free(decoration);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void free_xdg_decoration_mode(struct wl_listener *listener, void *data) {
 | 
			
		||||
static void free_xdg_decoration_mode(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct wb_decoration *decoration = wl_container_of(listener, decoration, mode_destroy);
 | 
			
		||||
	wl_list_remove(&decoration->mode_destroy.link);
 | 
			
		||||
	wl_list_remove(&decoration->request_mode.link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_xdg_decoration_mode(struct wl_listener *listener, void *data) {
 | 
			
		||||
static void handle_xdg_decoration_mode(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct wlr_xdg_toplevel_decoration_v1 *toplevel_decoration = data;
 | 
			
		||||
	struct wb_decoration *decoration = wl_container_of(listener, decoration, request_mode);
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(decoration->server->toplevels.next, toplevel, link);
 | 
			
		||||
	if (toplevel->xdg_toplevel->base->initialized)
 | 
			
		||||
	struct wb_view *view = wl_container_of(decoration->server->views.next, view, link);
 | 
			
		||||
	wlr_xdg_toplevel_decoration_v1_set_mode(toplevel_decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
 | 
			
		||||
	toplevel->decoration = toplevel_decoration;
 | 
			
		||||
	view->decoration = toplevel_decoration;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_new_xdg_toplevel_decoration(struct wl_listener *listener, void *data) {
 | 
			
		||||
static void handle_new_xdg_toplevel_decoration(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct wb_decoration *decoration = (struct wb_decoration *) calloc(1, sizeof(struct wb_decoration));
 | 
			
		||||
	struct wb_server *server = wl_container_of(listener, server, new_xdg_decoration);
 | 
			
		||||
	decoration->server = server;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,9 +35,12 @@ static void handle_new_xdg_toplevel_decoration(struct wl_listener *listener, voi
 | 
			
		|||
	wl_signal_add(&toplevel_decoration->events.request_mode, &decoration->request_mode);
 | 
			
		||||
	decoration->mode_destroy.notify = free_xdg_decoration_mode;
 | 
			
		||||
	wl_signal_add(&toplevel_decoration->events.destroy, &decoration->mode_destroy);
 | 
			
		||||
	/* For some reason, a lot of clients don't emit the request_mode signal. */
 | 
			
		||||
	handle_xdg_decoration_mode(&decoration->request_mode, toplevel_decoration);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_xdg_decoration(struct wb_server *server) {
 | 
			
		||||
void init_xdg_decoration(struct wb_server *server)
 | 
			
		||||
{
 | 
			
		||||
	struct wlr_xdg_decoration_manager_v1 *decoration = wlr_xdg_decoration_manager_v1_create(server->wl_display);
 | 
			
		||||
	server->new_xdg_decoration.notify = handle_new_xdg_toplevel_decoration;
 | 
			
		||||
	wl_signal_add(&decoration->events.new_toplevel_decoration, &server->new_xdg_decoration);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,41 +0,0 @@
 | 
			
		|||
#include <wlr/types/wlr_idle_inhibit_v1.h>
 | 
			
		||||
 | 
			
		||||
#include "idle.h"
 | 
			
		||||
 | 
			
		||||
static void idle_inhibit_manager_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_server *server = wl_container_of(listener, server, destroy_inhibit_manager);
 | 
			
		||||
	wl_list_remove(&server->new_inhibitor.link);
 | 
			
		||||
	wl_list_remove(&server->inhibitors);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void idle_inhibitor_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_server *server = wl_container_of(listener, server, destroy_inhibitor);
 | 
			
		||||
	/* wlroots will destroy the inhibitor after this callback, so this number will be 1 if the
 | 
			
		||||
	 * last inhibitor is being destroyed. */
 | 
			
		||||
	wl_list_remove(&server->destroy_inhibitor.link);
 | 
			
		||||
	wlr_idle_notifier_v1_set_inhibited(server->idle_notifier,
 | 
			
		||||
			wl_list_length(&server->inhibitors) > 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void idle_inhibitor_new(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_server *server = wl_container_of(listener, server, new_inhibitor);
 | 
			
		||||
	struct wlr_idle_inhibitor_v1 *inhibitor = data;
 | 
			
		||||
 | 
			
		||||
	server->destroy_inhibitor.notify = idle_inhibitor_destroy;
 | 
			
		||||
	wl_signal_add(&inhibitor->events.destroy, &server->destroy_inhibitor);
 | 
			
		||||
	wl_list_remove(&inhibitor->link);
 | 
			
		||||
	wl_list_insert(&server->inhibitors, &inhibitor->link);
 | 
			
		||||
	wlr_idle_notifier_v1_set_inhibited(server->idle_notifier, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool create_idle_manager(struct wb_server *server) {
 | 
			
		||||
	server->idle_notifier = wlr_idle_notifier_v1_create(server->wl_display);
 | 
			
		||||
	server->idle_inhibit_manager = wlr_idle_inhibit_v1_create(server->wl_display);
 | 
			
		||||
 | 
			
		||||
	wl_list_init(&server->inhibitors);
 | 
			
		||||
	server->new_inhibitor.notify = idle_inhibitor_new;
 | 
			
		||||
	wl_signal_add(&server->idle_inhibit_manager->events.new_inhibitor, &server->new_inhibitor);
 | 
			
		||||
	server->destroy_inhibit_manager.notify = idle_inhibit_manager_destroy;
 | 
			
		||||
	wl_signal_add(&server->idle_inhibit_manager->events.destroy, &server->destroy_inhibit_manager);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
#include "waybox/server.h"
 | 
			
		||||
 | 
			
		||||
bool create_idle_manager(struct wb_server *server);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,369 +1,282 @@
 | 
			
		|||
/*
 | 
			
		||||
 * More or less taken verbatim from wio <https://git.sr.ht/~sircmpwn/wio>.
 | 
			
		||||
 * Additional material taken from sway <https://github.com/swaywm/sway>.
 | 
			
		||||
 * More or less taken verbatim from wio <https://git.sr.ht/~sircmpwn/wio>, so in
 | 
			
		||||
 * accordance with its MIT license:
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2019 Drew DeVault
 | 
			
		||||
 * Copyright 2022 Sway Developers
 | 
			
		||||
 */
 | 
			
		||||
#include <wlr/types/wlr_layer_shell_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_scene.h>
 | 
			
		||||
 | 
			
		||||
#include "waybox/xdg_shell.h"
 | 
			
		||||
 | 
			
		||||
static void descriptor_destroy(struct wb_scene_descriptor *desc) {
 | 
			
		||||
	if (!desc) {
 | 
			
		||||
static void apply_exclusive(struct wlr_box *usable_area,
 | 
			
		||||
		uint32_t anchor, int32_t exclusive,
 | 
			
		||||
		int32_t margin_top, int32_t margin_right,
 | 
			
		||||
		int32_t margin_bottom, int32_t margin_left) {
 | 
			
		||||
	if (exclusive <= 0) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&desc->destroy.link);
 | 
			
		||||
 | 
			
		||||
	free(desc);
 | 
			
		||||
	struct {
 | 
			
		||||
		uint32_t anchors;
 | 
			
		||||
		int *positive_axis;
 | 
			
		||||
		int *negative_axis;
 | 
			
		||||
		int margin;
 | 
			
		||||
	} edges[] = {
 | 
			
		||||
		{
 | 
			
		||||
			.anchors =
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP,
 | 
			
		||||
			.positive_axis = &usable_area->y,
 | 
			
		||||
			.negative_axis = &usable_area->height,
 | 
			
		||||
			.margin = margin_top,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			.anchors =
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
 | 
			
		||||
			.positive_axis = NULL,
 | 
			
		||||
			.negative_axis = &usable_area->height,
 | 
			
		||||
			.margin = margin_bottom,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			.anchors =
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
 | 
			
		||||
			.positive_axis = &usable_area->x,
 | 
			
		||||
			.negative_axis = &usable_area->width,
 | 
			
		||||
			.margin = margin_left,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			.anchors =
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
 | 
			
		||||
				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
 | 
			
		||||
			.positive_axis = NULL,
 | 
			
		||||
			.negative_axis = &usable_area->width,
 | 
			
		||||
			.margin = margin_right,
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
	for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); ++i) {
 | 
			
		||||
		if ((anchor & edges[i].anchors) == edges[i].anchors) {
 | 
			
		||||
			if (edges[i].positive_axis) {
 | 
			
		||||
				*edges[i].positive_axis += exclusive + edges[i].margin;
 | 
			
		||||
			}
 | 
			
		||||
			if (edges[i].negative_axis) {
 | 
			
		||||
				*edges[i].negative_axis -= exclusive + edges[i].margin;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_descriptor_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_scene_descriptor *desc =
 | 
			
		||||
		wl_container_of(listener, desc, destroy);
 | 
			
		||||
 | 
			
		||||
	descriptor_destroy(desc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void assign_scene_descriptor(struct wlr_scene_node *node,
 | 
			
		||||
		enum wb_scene_descriptor_type type, void *data) {
 | 
			
		||||
	struct wb_scene_descriptor *desc =
 | 
			
		||||
		calloc(1, sizeof(struct wb_scene_descriptor));
 | 
			
		||||
 | 
			
		||||
	if (!desc) {
 | 
			
		||||
		return;
 | 
			
		||||
static void arrange_layer(struct wlr_output *output,
 | 
			
		||||
		struct wl_list *list /* struct *wb_layer_surface */,
 | 
			
		||||
		struct wlr_box *usable_area, bool exclusive) {
 | 
			
		||||
	struct wb_layer_surface *wb_surface;
 | 
			
		||||
	struct wlr_box full_area = { 0 };
 | 
			
		||||
	wlr_output_effective_resolution(output,
 | 
			
		||||
			&full_area.width, &full_area.height);
 | 
			
		||||
	wl_list_for_each_reverse(wb_surface, list, link) {
 | 
			
		||||
		struct wlr_layer_surface_v1 *layer = wb_surface->layer_surface;
 | 
			
		||||
		struct wlr_layer_surface_v1_state *state = &layer->current;
 | 
			
		||||
		if (exclusive != (state->exclusive_zone > 0)) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		struct wlr_box bounds;
 | 
			
		||||
		if (state->exclusive_zone == -1) {
 | 
			
		||||
			bounds = full_area;
 | 
			
		||||
		} else {
 | 
			
		||||
			bounds = *usable_area;
 | 
			
		||||
		}
 | 
			
		||||
		struct wlr_box box = {
 | 
			
		||||
			.width = state->desired_width,
 | 
			
		||||
			.height = state->desired_height
 | 
			
		||||
		};
 | 
			
		||||
		/* Horizontal axis */
 | 
			
		||||
		const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
 | 
			
		||||
			| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
 | 
			
		||||
		if ((state->anchor & both_horiz) && box.width == 0) {
 | 
			
		||||
			box.x = bounds.x;
 | 
			
		||||
			box.width = bounds.width;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
 | 
			
		||||
			box.x = bounds.x;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
 | 
			
		||||
			box.x = bounds.x + (bounds.width - box.width);
 | 
			
		||||
		} else {
 | 
			
		||||
			box.x = bounds.x + ((bounds.width / 2) - (box.width / 2));
 | 
			
		||||
		}
 | 
			
		||||
		/* Vertical axis */
 | 
			
		||||
		const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
 | 
			
		||||
			| ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
 | 
			
		||||
		if ((state->anchor & both_vert) && box.height == 0) {
 | 
			
		||||
			box.y = bounds.y;
 | 
			
		||||
			box.height = bounds.height;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
 | 
			
		||||
			box.y = bounds.y;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
 | 
			
		||||
			box.y = bounds.y + (bounds.height - box.height);
 | 
			
		||||
		} else {
 | 
			
		||||
			box.y = bounds.y + ((bounds.height / 2) - (box.height / 2));
 | 
			
		||||
		}
 | 
			
		||||
		/* Margin */
 | 
			
		||||
		if ((state->anchor & both_horiz) == both_horiz) {
 | 
			
		||||
			box.x += state->margin.left;
 | 
			
		||||
			box.width -= state->margin.left + state->margin.right;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
 | 
			
		||||
			box.x += state->margin.left;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
 | 
			
		||||
			box.x -= state->margin.right;
 | 
			
		||||
		}
 | 
			
		||||
		if ((state->anchor & both_vert) == both_vert) {
 | 
			
		||||
			box.y += state->margin.top;
 | 
			
		||||
			box.height -= state->margin.top + state->margin.bottom;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
 | 
			
		||||
			box.y += state->margin.top;
 | 
			
		||||
		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
 | 
			
		||||
			box.y -= state->margin.bottom;
 | 
			
		||||
		}
 | 
			
		||||
		if (box.width < 0 || box.height < 0) {
 | 
			
		||||
			wlr_layer_surface_v1_destroy(layer);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	desc->type = type;
 | 
			
		||||
	desc->data = data;
 | 
			
		||||
 | 
			
		||||
	desc->destroy.notify = handle_descriptor_destroy;
 | 
			
		||||
	wl_signal_add(&node->events.destroy, &desc->destroy);
 | 
			
		||||
 | 
			
		||||
	node->data = desc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void arrange_surface(struct wb_output *output, struct wlr_box *full_area,
 | 
			
		||||
		struct wlr_box *usable_area, struct wlr_scene_tree *scene_tree) {
 | 
			
		||||
	struct wlr_scene_node *node;
 | 
			
		||||
	wl_list_for_each(node, &scene_tree->children, link) {
 | 
			
		||||
		struct wb_scene_descriptor *desc = node->data;
 | 
			
		||||
 | 
			
		||||
		if (desc->type == WB_SCENE_DESC_LAYER_SHELL) {
 | 
			
		||||
			struct wb_layer_surface *surface = desc->data;
 | 
			
		||||
			surface->scene->layer_surface->initialized = true;
 | 
			
		||||
			wlr_scene_layer_surface_v1_configure(surface->scene,
 | 
			
		||||
					full_area, usable_area);
 | 
			
		||||
		}
 | 
			
		||||
		/* Apply */
 | 
			
		||||
		wb_surface->geo = box;
 | 
			
		||||
		apply_exclusive(usable_area, state->anchor, state->exclusive_zone,
 | 
			
		||||
				state->margin.top, state->margin.right,
 | 
			
		||||
				state->margin.bottom, state->margin.left);
 | 
			
		||||
		wlr_layer_surface_v1_configure(layer, box.width, box.height);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void arrange_layers(struct wb_output *output) {
 | 
			
		||||
	struct wlr_box usable_area = { 0 };
 | 
			
		||||
	struct wlr_box full_area;
 | 
			
		||||
	wlr_output_effective_resolution(output->wlr_output,
 | 
			
		||||
			&usable_area.width, &usable_area.height);
 | 
			
		||||
 | 
			
		||||
	memcpy(&full_area, &usable_area, sizeof(struct wlr_box));
 | 
			
		||||
	/* Arrange exclusive surfaces from top->bottom */
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
 | 
			
		||||
			&usable_area, true);
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
 | 
			
		||||
			&usable_area, true);
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
 | 
			
		||||
			&usable_area, true);
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
 | 
			
		||||
			&usable_area, true);
 | 
			
		||||
 | 
			
		||||
	arrange_surface(output, &full_area, &usable_area, output->layers.shell_background);
 | 
			
		||||
	arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom);
 | 
			
		||||
	arrange_surface(output, &full_area, &usable_area, output->layers.shell_top);
 | 
			
		||||
	arrange_surface(output, &full_area, &usable_area, output->layers.shell_overlay);
 | 
			
		||||
}
 | 
			
		||||
	/* Arrange non-exlusive surfaces from top->bottom */
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
 | 
			
		||||
			&usable_area, false);
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
 | 
			
		||||
			&usable_area, false);
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
 | 
			
		||||
			&usable_area, false);
 | 
			
		||||
	arrange_layer(output->wlr_output,
 | 
			
		||||
			&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
 | 
			
		||||
			&usable_area, false);
 | 
			
		||||
 | 
			
		||||
static struct wlr_scene_tree *wb_layer_get_scene(struct wb_output *output,
 | 
			
		||||
		enum zwlr_layer_shell_v1_layer type) {
 | 
			
		||||
	switch (type) {
 | 
			
		||||
		case ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND:
 | 
			
		||||
			return output->layers.shell_background;
 | 
			
		||||
		case ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM:
 | 
			
		||||
			return output->layers.shell_bottom;
 | 
			
		||||
		case ZWLR_LAYER_SHELL_V1_LAYER_TOP:
 | 
			
		||||
			return output->layers.shell_top;
 | 
			
		||||
		case ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY:
 | 
			
		||||
			return output->layers.shell_overlay;
 | 
			
		||||
	/* Find topmost keyboard interactive layer, if such a layer exists */
 | 
			
		||||
	uint32_t layers_above_shell[] = {
 | 
			
		||||
		ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
 | 
			
		||||
		ZWLR_LAYER_SHELL_V1_LAYER_TOP,
 | 
			
		||||
	};
 | 
			
		||||
	size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
 | 
			
		||||
	struct wb_layer_surface *layer, *topmost = NULL;
 | 
			
		||||
	for (size_t i = 0; i < nlayers; ++i) {
 | 
			
		||||
		wl_list_for_each_reverse(layer,
 | 
			
		||||
				&output->layers[layers_above_shell[i]], link) {
 | 
			
		||||
			if (layer->layer_surface->current.keyboard_interactive) {
 | 
			
		||||
				topmost = layer;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (topmost != NULL) {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Unreachable */
 | 
			
		||||
	return NULL;
 | 
			
		||||
	/* TODO: Focus topmost layer */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wb_layer_surface *wb_layer_surface_create(
 | 
			
		||||
		struct wlr_scene_layer_surface_v1 *scene) {
 | 
			
		||||
	struct wb_layer_surface *surface = calloc(1, sizeof(struct wb_layer_surface));
 | 
			
		||||
	if (!surface) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	surface->scene = scene;
 | 
			
		||||
 | 
			
		||||
	return surface;
 | 
			
		||||
static void handle_output_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_surface *layer =
 | 
			
		||||
		wl_container_of(listener, layer, output_destroy);
 | 
			
		||||
	layer->layer_surface->output = NULL;
 | 
			
		||||
	wl_list_remove(&layer->output_destroy.link);
 | 
			
		||||
	wlr_layer_surface_v1_destroy(layer->layer_surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_surface_commit(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_surface *surface =
 | 
			
		||||
		wl_container_of(listener, surface, surface_commit);
 | 
			
		||||
	struct wb_toplevel *current_toplevel =
 | 
			
		||||
		wl_container_of(surface->server->toplevels.next, current_toplevel, link);
 | 
			
		||||
 | 
			
		||||
	if (!surface->output || current_toplevel->xdg_toplevel->current.fullscreen) {
 | 
			
		||||
		return;
 | 
			
		||||
	struct wb_layer_surface *layer =
 | 
			
		||||
		wl_container_of(listener, layer, surface_commit);
 | 
			
		||||
	struct wlr_layer_surface_v1 *layer_surface = layer->layer_surface;
 | 
			
		||||
	struct wlr_output *wlr_output = layer_surface->output;
 | 
			
		||||
	if (wlr_output != NULL) {
 | 
			
		||||
		struct wb_output *output = wlr_output->data;
 | 
			
		||||
		arrange_layers(output);
 | 
			
		||||
	}
 | 
			
		||||
	wlr_fractional_scale_v1_notify_scale(surface->scene->layer_surface->surface, surface->output->wlr_output->scale);
 | 
			
		||||
 | 
			
		||||
	struct wlr_layer_surface_v1 *layer_surface = surface->scene->layer_surface;
 | 
			
		||||
	uint32_t committed = layer_surface->current.committed;
 | 
			
		||||
 | 
			
		||||
	enum zwlr_layer_shell_v1_layer layer_type = layer_surface->current.layer;
 | 
			
		||||
	struct wlr_scene_tree *output_layer = wb_layer_get_scene(
 | 
			
		||||
		surface->output, layer_type);
 | 
			
		||||
 | 
			
		||||
	if (committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) {
 | 
			
		||||
		wlr_scene_node_reparent(&surface->scene->tree->node, output_layer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (committed || layer_surface->surface->mapped != surface->mapped) {
 | 
			
		||||
		surface->mapped = layer_surface->surface->mapped;
 | 
			
		||||
		arrange_layers(surface->output);
 | 
			
		||||
 | 
			
		||||
		struct timespec now;
 | 
			
		||||
		clock_gettime(CLOCK_MONOTONIC, &now);
 | 
			
		||||
		wlr_surface_send_frame_done(layer_surface->surface, &now);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) {
 | 
			
		||||
		wlr_scene_node_raise_to_top(&output_layer->node);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (layer_surface == surface->server->seat->focused_layer) {
 | 
			
		||||
		seat_focus_surface(surface->server->seat, layer_surface->surface);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_map(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_surface *surface = wl_container_of(listener,
 | 
			
		||||
			surface, map);
 | 
			
		||||
 | 
			
		||||
	struct wlr_layer_surface_v1 *layer_surface =
 | 
			
		||||
				surface->scene->layer_surface;
 | 
			
		||||
 | 
			
		||||
	/* focus on new surface */
 | 
			
		||||
	if (layer_surface->current.keyboard_interactive &&
 | 
			
		||||
			(layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY ||
 | 
			
		||||
			layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP)) {
 | 
			
		||||
 | 
			
		||||
		struct wb_seat *seat = surface->server->seat;
 | 
			
		||||
		/* but only if the currently focused layer has a lower precedence */
 | 
			
		||||
		if (!seat->focused_layer ||
 | 
			
		||||
				seat->focused_layer->current.layer >= layer_surface->current.layer) {
 | 
			
		||||
			seat_set_focus_layer(seat, layer_surface);
 | 
			
		||||
		}
 | 
			
		||||
		arrange_layers(surface->output);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_unmap(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_surface *surface = wl_container_of(
 | 
			
		||||
			listener, surface, unmap);
 | 
			
		||||
 | 
			
		||||
	struct wb_seat *seat = surface->server->seat;
 | 
			
		||||
	if (seat->focused_layer == surface->scene->layer_surface) {
 | 
			
		||||
		seat_set_focus_layer(seat, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!wl_list_empty(&surface->server->toplevels)) {
 | 
			
		||||
		struct wb_toplevel *toplevel =
 | 
			
		||||
			wl_container_of(surface->server->toplevels.next, toplevel, link);
 | 
			
		||||
		if (toplevel && toplevel->scene_tree && toplevel->scene_tree->node.enabled) {
 | 
			
		||||
			focus_toplevel(toplevel);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void wb_layer_surface_destroy(struct wb_layer_surface *surface) {
 | 
			
		||||
	if (surface == NULL) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (surface->scene->layer_surface->surface != NULL)
 | 
			
		||||
		wlr_fractional_scale_v1_notify_scale(surface->scene->layer_surface->surface,
 | 
			
		||||
				surface->output->wlr_output->scale);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&surface->map.link);
 | 
			
		||||
	wl_list_remove(&surface->unmap.link);
 | 
			
		||||
	wl_list_remove(&surface->surface_commit.link);
 | 
			
		||||
	wl_list_remove(&surface->destroy.link);
 | 
			
		||||
 | 
			
		||||
	free(surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_surface *surface =
 | 
			
		||||
		wl_container_of(listener, surface, destroy);
 | 
			
		||||
 | 
			
		||||
	if (surface->output) {
 | 
			
		||||
		arrange_layers(surface->output);
 | 
			
		||||
	struct wb_layer_surface *layer = wl_container_of(
 | 
			
		||||
			listener, layer, destroy);
 | 
			
		||||
	wl_list_remove(&layer->link);
 | 
			
		||||
	wl_list_remove(&layer->destroy.link);
 | 
			
		||||
	wl_list_remove(&layer->map.link);
 | 
			
		||||
	wl_list_remove(&layer->surface_commit.link);
 | 
			
		||||
	if (layer->layer_surface->output) {
 | 
			
		||||
		wl_list_remove(&layer->output_destroy.link);
 | 
			
		||||
		arrange_layers((struct wb_output *)layer->layer_surface->output->data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&surface->new_popup.link);
 | 
			
		||||
	wb_layer_surface_destroy(surface);
 | 
			
		||||
	free(layer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_popup *popup =
 | 
			
		||||
		wl_container_of(listener, popup, destroy);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&popup->destroy.link);
 | 
			
		||||
	wl_list_remove(&popup->new_popup.link);
 | 
			
		||||
	free(popup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wb_layer_surface *popup_get_layer(
 | 
			
		||||
		struct wb_layer_popup *popup) {
 | 
			
		||||
	struct wlr_scene_node *current = &popup->scene->node;
 | 
			
		||||
	while (current) {
 | 
			
		||||
		if (current->data) {
 | 
			
		||||
			struct wb_scene_descriptor *desc = current->data;
 | 
			
		||||
			if (desc->type == WB_SCENE_DESC_LAYER_SHELL) {
 | 
			
		||||
				return desc->data;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		current = ¤t->parent->node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void popup_unconstrain(struct wb_layer_popup *popup) {
 | 
			
		||||
	struct wb_layer_surface *surface = popup_get_layer(popup);
 | 
			
		||||
	if (!surface) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
 | 
			
		||||
	struct wb_output *output = surface->output;
 | 
			
		||||
 | 
			
		||||
	int lx, ly;
 | 
			
		||||
	wlr_scene_node_coords(&popup->scene->node, &lx, &ly);
 | 
			
		||||
 | 
			
		||||
	/* The output box expressed in the coordinate system of the toplevel
 | 
			
		||||
	 * parent of the popup. */
 | 
			
		||||
	struct wlr_box output_toplevel_sx_box = {
 | 
			
		||||
		.x = output->geometry.x - MIN(lx, 0),
 | 
			
		||||
		.y = output->geometry.y - MAX(ly, 0),
 | 
			
		||||
		.width = output->geometry.width,
 | 
			
		||||
		.height = output->geometry.height,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
 | 
			
		||||
 | 
			
		||||
static struct wb_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
 | 
			
		||||
			struct wlr_scene_tree *parent) {
 | 
			
		||||
	struct wb_layer_popup *popup =
 | 
			
		||||
		calloc(1, sizeof(struct wb_layer_popup));
 | 
			
		||||
	if (popup == NULL) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	popup->wlr_popup = wlr_popup;
 | 
			
		||||
 | 
			
		||||
	popup->scene = wlr_scene_xdg_surface_create(parent,
 | 
			
		||||
			wlr_popup->base);
 | 
			
		||||
 | 
			
		||||
	if (!popup->scene) {
 | 
			
		||||
		free(popup);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assign_scene_descriptor(&popup->scene->node, WB_SCENE_DESC_LAYER_SHELL_POPUP,
 | 
			
		||||
			popup);
 | 
			
		||||
 | 
			
		||||
	popup->destroy.notify = popup_handle_destroy;
 | 
			
		||||
	wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
 | 
			
		||||
 | 
			
		||||
	popup->new_popup.notify = popup_handle_new_popup;
 | 
			
		||||
	wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
 | 
			
		||||
 | 
			
		||||
	popup_unconstrain(popup);
 | 
			
		||||
 | 
			
		||||
	return popup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_popup *layer_popup =
 | 
			
		||||
		wl_container_of(listener, layer_popup, new_popup);
 | 
			
		||||
	struct wlr_xdg_popup *wlr_popup = data;
 | 
			
		||||
	create_popup(wlr_popup, layer_popup->scene);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_new_popup(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_layer_surface *wb_layer_surface =
 | 
			
		||||
		wl_container_of(listener, wb_layer_surface, new_popup);
 | 
			
		||||
	struct wlr_xdg_popup *wlr_popup = data;
 | 
			
		||||
 | 
			
		||||
	create_popup(wlr_popup, wb_layer_surface->scene->tree);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
 | 
			
		||||
static void handle_map(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wlr_layer_surface_v1 *layer_surface = data;
 | 
			
		||||
	wlr_surface_send_enter(layer_surface->surface, layer_surface->output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	if (layer_surface->output == NULL) {
 | 
			
		||||
		struct wb_server *server =
 | 
			
		||||
			wl_container_of(listener, server, new_layer_surface);
 | 
			
		||||
		if (wl_list_length(&server->toplevels) == 0) return;
 | 
			
		||||
		struct wb_toplevel *toplevel =
 | 
			
		||||
			wl_container_of(server->toplevels.next, toplevel, link);
 | 
			
		||||
		layer_surface->output = get_active_output(toplevel);
 | 
			
		||||
	}
 | 
			
		||||
	struct wb_output *output = layer_surface->output->data;
 | 
			
		||||
 | 
			
		||||
void server_new_layer_surface(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_server *server = wl_container_of(
 | 
			
		||||
			listener, server, new_layer_surface);
 | 
			
		||||
	struct wlr_layer_surface_v1 *layer_surface = data;
 | 
			
		||||
	if (!layer_surface->output) {
 | 
			
		||||
		/* Assign last active output */
 | 
			
		||||
		layer_surface->output = output->wlr_output;
 | 
			
		||||
		struct wlr_output *output = wlr_output_layout_output_at(
 | 
			
		||||
				server->output_layout, server->cursor->cursor->x, server->cursor->cursor->y);
 | 
			
		||||
		layer_surface->output = output;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	enum zwlr_layer_shell_v1_layer layer_type = layer_surface->pending.layer;
 | 
			
		||||
	struct wlr_scene_tree *output_layer = wb_layer_get_scene(
 | 
			
		||||
			output, layer_type);
 | 
			
		||||
	struct wlr_scene_layer_surface_v1 *scene_surface =
 | 
			
		||||
		wlr_scene_layer_surface_v1_create(output_layer, layer_surface);
 | 
			
		||||
	if (!scene_surface) {
 | 
			
		||||
	struct wb_output *output = layer_surface->output->data;
 | 
			
		||||
	struct wb_layer_surface *wb_surface =
 | 
			
		||||
		calloc(1, sizeof(struct wb_layer_surface));
 | 
			
		||||
	if (!wb_surface) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	wb_surface->layer_surface = layer_surface;
 | 
			
		||||
	layer_surface->data = wb_surface;
 | 
			
		||||
	wb_surface->server = server;
 | 
			
		||||
 | 
			
		||||
	struct wb_layer_surface *surface =
 | 
			
		||||
		wb_layer_surface_create(scene_surface);
 | 
			
		||||
 | 
			
		||||
	assign_scene_descriptor(&scene_surface->tree->node,
 | 
			
		||||
		WB_SCENE_DESC_LAYER_SHELL, surface);
 | 
			
		||||
	if (!scene_surface->tree->node.data) {
 | 
			
		||||
		wlr_layer_surface_v1_destroy(layer_surface);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	surface->output = output;
 | 
			
		||||
	surface->server = output->server;
 | 
			
		||||
 | 
			
		||||
	surface->surface_commit.notify = handle_surface_commit;
 | 
			
		||||
	wb_surface->surface_commit.notify = handle_surface_commit;
 | 
			
		||||
	wl_signal_add(&layer_surface->surface->events.commit,
 | 
			
		||||
		&surface->surface_commit);
 | 
			
		||||
	surface->map.notify = handle_map;
 | 
			
		||||
	wl_signal_add(&layer_surface->surface->events.map, &surface->map);
 | 
			
		||||
	surface->unmap.notify = handle_unmap;
 | 
			
		||||
	wl_signal_add(&layer_surface->surface->events.unmap, &surface->unmap);
 | 
			
		||||
	surface->destroy.notify = handle_destroy;
 | 
			
		||||
	wl_signal_add(&layer_surface->events.destroy, &surface->destroy);
 | 
			
		||||
	surface->new_popup.notify = handle_new_popup;
 | 
			
		||||
	wl_signal_add(&layer_surface->events.new_popup, &surface->new_popup);
 | 
			
		||||
		&wb_surface->surface_commit);
 | 
			
		||||
	wb_surface->output_destroy.notify = handle_output_destroy;
 | 
			
		||||
	wl_signal_add(&layer_surface->output->events.destroy,
 | 
			
		||||
		&wb_surface->output_destroy);
 | 
			
		||||
	wb_surface->destroy.notify = handle_destroy;
 | 
			
		||||
	wl_signal_add(&layer_surface->events.destroy, &wb_surface->destroy);
 | 
			
		||||
	wb_surface->map.notify = handle_map;
 | 
			
		||||
	wl_signal_add(&layer_surface->events.map, &wb_surface->map);
 | 
			
		||||
	/* TODO: popups */
 | 
			
		||||
 | 
			
		||||
	/* TODO: Listen for subsurfaces */
 | 
			
		||||
	wl_list_insert(&output->layers[layer_surface->pending.layer], &wb_surface->link);
 | 
			
		||||
	/* Temporarily set the layer's current state to pending
 | 
			
		||||
	 * So that we can easily arrange it */
 | 
			
		||||
	struct wlr_layer_surface_v1_state old_state = layer_surface->current;
 | 
			
		||||
| 
						 | 
				
			
			@ -372,9 +285,10 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
 | 
			
		|||
	layer_surface->current = old_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_layer_shell(struct wb_server *server) {
 | 
			
		||||
	server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, 4);
 | 
			
		||||
	server->new_layer_surface.notify = handle_layer_shell_surface;
 | 
			
		||||
void init_layer_shell(struct wb_server *server)
 | 
			
		||||
{
 | 
			
		||||
	server->layer_shell = wlr_layer_shell_v1_create(server->wl_display);
 | 
			
		||||
	server->new_layer_surface.notify = server_new_layer_surface;
 | 
			
		||||
	wl_signal_add(&server->layer_shell->events.new_surface,
 | 
			
		||||
			&server->new_layer_surface);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,51 +2,21 @@
 | 
			
		|||
#define _WB_LAYERS_H
 | 
			
		||||
#include <wlr/types/wlr_layer_shell_v1.h>
 | 
			
		||||
 | 
			
		||||
#include "waybox/output.h"
 | 
			
		||||
struct wb_server;
 | 
			
		||||
 | 
			
		||||
struct wb_layer_surface {
 | 
			
		||||
	struct wb_output *output;
 | 
			
		||||
	struct wlr_layer_surface_v1 *layer_surface;
 | 
			
		||||
	struct wb_server *server;
 | 
			
		||||
 | 
			
		||||
	struct wlr_scene_layer_surface_v1 *scene;
 | 
			
		||||
 | 
			
		||||
	bool mapped;
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wl_listener map;
 | 
			
		||||
	struct wl_listener unmap;
 | 
			
		||||
	struct wl_listener surface_commit;
 | 
			
		||||
	struct wl_listener new_popup;
 | 
			
		||||
};
 | 
			
		||||
	struct wl_listener output_destroy;
 | 
			
		||||
 | 
			
		||||
struct wb_layer_popup {
 | 
			
		||||
	struct wlr_xdg_popup *wlr_popup;
 | 
			
		||||
	struct wlr_scene_tree *scene;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wl_listener new_popup;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wb_layer_subsurface {
 | 
			
		||||
	struct wlr_scene_tree *scene;
 | 
			
		||||
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum wb_scene_descriptor_type {
 | 
			
		||||
	WB_SCENE_DESC_NODE,
 | 
			
		||||
	WB_SCENE_DESC_LAYER_SHELL,
 | 
			
		||||
	WB_SCENE_DESC_LAYER_SHELL_POPUP,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wb_scene_descriptor {
 | 
			
		||||
	enum wb_scene_descriptor_type type;
 | 
			
		||||
	void *data;
 | 
			
		||||
	struct wl_listener destroy;
 | 
			
		||||
	struct wlr_box geo;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void init_layer_shell(struct wb_server *server);
 | 
			
		||||
void assign_scene_descriptor(struct wlr_scene_node *node,
 | 
			
		||||
	enum wb_scene_descriptor_type type, void *data);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,8 @@
 | 
			
		|||
 | 
			
		||||
#include "waybox/server.h"
 | 
			
		||||
 | 
			
		||||
bool show_help(char *name) {
 | 
			
		||||
bool show_help(char *name)
 | 
			
		||||
{
 | 
			
		||||
	printf(_("Syntax: %s [options]\n"), name);
 | 
			
		||||
	printf(_("\nOptions:\n"));
 | 
			
		||||
	printf(_("  --help              Display this help and exit\n"));
 | 
			
		||||
| 
						 | 
				
			
			@ -21,15 +22,16 @@ bool show_help(char *name) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
struct wb_server server = {0};
 | 
			
		||||
void signal_handler(int sig) {
 | 
			
		||||
void signal_handler(int sig)
 | 
			
		||||
{
 | 
			
		||||
	switch (sig) {
 | 
			
		||||
		case SIGINT:
 | 
			
		||||
		case SIGTERM:
 | 
			
		||||
			wl_display_terminate(server.wl_display);
 | 
			
		||||
			break;
 | 
			
		||||
		case SIGUSR1:
 | 
			
		||||
			/* Openbox uses SIGUSR1 to restart and SIGUSR2 to reconfigure.
 | 
			
		||||
			 * What's the difference?
 | 
			
		||||
			/* Openbox uses SIGUSR1 to restart. I'm not sure of the
 | 
			
		||||
			 * difference between restarting and reconfiguring.
 | 
			
		||||
			 */
 | 
			
		||||
		case SIGUSR2:
 | 
			
		||||
			deinit_config(server.config);
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +115,6 @@ int main(int argc, char **argv) {
 | 
			
		|||
	sigaction(SIGTERM, &sa, NULL);
 | 
			
		||||
	sigaction(SIGUSR1, &sa, NULL);
 | 
			
		||||
	sigaction(SIGUSR2, &sa, NULL);
 | 
			
		||||
 | 
			
		||||
	wl_display_run(server.wl_display);
 | 
			
		||||
 | 
			
		||||
	wb_terminate(&server);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ wb_src = files(
 | 
			
		|||
  'config.c',
 | 
			
		||||
  'cursor.c',
 | 
			
		||||
  'decoration.c',
 | 
			
		||||
  'idle.c',
 | 
			
		||||
  'layer_shell.c',
 | 
			
		||||
  'main.c',
 | 
			
		||||
  'output.c',
 | 
			
		||||
| 
						 | 
				
			
			@ -12,8 +11,6 @@ wb_src = files(
 | 
			
		|||
  )
 | 
			
		||||
 | 
			
		||||
wb_dep = [
 | 
			
		||||
  libevdev,
 | 
			
		||||
  libinput,
 | 
			
		||||
  libxml2,
 | 
			
		||||
  wayland_server,
 | 
			
		||||
  wlroots,
 | 
			
		||||
| 
						 | 
				
			
			@ -27,5 +24,4 @@ executable(
 | 
			
		|||
  dependencies: [wb_dep, wlr_protos],
 | 
			
		||||
  install: true,
 | 
			
		||||
  install_dir: get_option('prefix') / get_option('libexecdir'),
 | 
			
		||||
  link_args: ['-Wl,-lm'],
 | 
			
		||||
  )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										247
									
								
								waybox/output.c
									
										
									
									
									
								
							
							
						
						
									
										247
									
								
								waybox/output.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,92 +1,163 @@
 | 
			
		|||
#include "waybox/output.h"
 | 
			
		||||
 | 
			
		||||
void output_frame_notify(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* This function is called every time an output is ready to display a frame,
 | 
			
		||||
	 * generally at the output's refresh rate (e.g. 60Hz). */
 | 
			
		||||
	struct wb_output *output = wl_container_of(listener, output, frame);
 | 
			
		||||
	struct wlr_scene *scene = output->server->scene;
 | 
			
		||||
	struct wlr_scene_output *scene_output =
 | 
			
		||||
		wlr_scene_get_scene_output(scene, output->wlr_output);
 | 
			
		||||
struct render_data {
 | 
			
		||||
	struct wlr_output *output;
 | 
			
		||||
	struct wlr_renderer *renderer;
 | 
			
		||||
	struct wb_view *view;
 | 
			
		||||
	struct timespec *when;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
	wlr_output_layout_get_box(output->server->output_layout,
 | 
			
		||||
			output->wlr_output, &output->geometry);
 | 
			
		||||
static void render_surface(struct wlr_surface *surface,
 | 
			
		||||
				int sx, int sy, void *data) {
 | 
			
		||||
	/* This function is called for every surface that needs to be rendered. */
 | 
			
		||||
	struct render_data *rdata = data;
 | 
			
		||||
	struct wb_view *view = rdata->view;
 | 
			
		||||
	struct wlr_output *output = rdata->output;
 | 
			
		||||
 | 
			
		||||
	if (output->gamma_lut_changed) {
 | 
			
		||||
		output->gamma_lut_changed = false;
 | 
			
		||||
		struct wlr_gamma_control_v1 *gamma_control =
 | 
			
		||||
			wlr_gamma_control_manager_v1_get_control(output->server->gamma_control_manager,
 | 
			
		||||
					output->wlr_output);
 | 
			
		||||
		struct wlr_output_state pending;
 | 
			
		||||
		if (!wlr_scene_output_build_state(scene_output, &pending, NULL))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
 | 
			
		||||
			wlr_output_state_finish(&pending);
 | 
			
		||||
	/* We first obtain a wlr_texture, which is a GPU resource. wlroots
 | 
			
		||||
	 * automatically handles negotiating these with the client. The underlying
 | 
			
		||||
	 * resource could be an opaque handle passed from the client, or the client
 | 
			
		||||
	 * could have sent a pixel buffer which we copied to the GPU, or a few other
 | 
			
		||||
	 * means. You don't have to worry about this, wlroots takes care of it. */
 | 
			
		||||
	struct wlr_texture *texture = wlr_surface_get_texture(surface);
 | 
			
		||||
	if (texture == NULL) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Couldn't get a surface texture"));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		if (!wlr_output_test_state(output->wlr_output, &pending)) {
 | 
			
		||||
			wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
 | 
			
		||||
			wlr_output_state_finish(&pending);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	/* The view has a position in layout coordinates. If you have two displays,
 | 
			
		||||
	 * one next to the other, both 1080p, a view on the rightmost display might
 | 
			
		||||
	 * have layout coordinates of 2000,100. We need to translate that to
 | 
			
		||||
	 * output-local coordinates, or (2000 - 1920). */
 | 
			
		||||
	double ox = 0, oy = 0;
 | 
			
		||||
	wlr_output_layout_output_coords(
 | 
			
		||||
			view->server->output_layout, output, &ox, &oy);
 | 
			
		||||
	ox += view->current_position.x + sx, oy += view->current_position.y + sy;
 | 
			
		||||
 | 
			
		||||
		wlr_output_state_finish(&pending);
 | 
			
		||||
	}
 | 
			
		||||
	/* We also have to apply the scale factor for HiDPI outputs. This is only
 | 
			
		||||
	 * part of the puzzle, Waybox does not fully support HiDPI. */
 | 
			
		||||
	struct wlr_box box = {
 | 
			
		||||
		.x = ox * output->scale,
 | 
			
		||||
		.y = oy * output->scale,
 | 
			
		||||
		.width = surface->current.width * output->scale,
 | 
			
		||||
		.height = surface->current.height * output->scale,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/* Render the scene if needed and commit the output */
 | 
			
		||||
	wlr_scene_output_commit(scene_output, NULL);
 | 
			
		||||
	/*
 | 
			
		||||
	 * Those familiar with OpenGL are also familiar with the role of matrices
 | 
			
		||||
	 * in graphics programming. We need to prepare a matrix to render the view
 | 
			
		||||
	 * with. wlr_matrix_project_box is a helper which takes a box with a desired
 | 
			
		||||
	 * x, y coordinates, width and height, and an output geometry, then
 | 
			
		||||
	 * prepares an orthographic projection and multiplies the necessary
 | 
			
		||||
	 * transforms to produce a model-view-projection matrix.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Naturally you can do this any way you like.
 | 
			
		||||
	 */
 | 
			
		||||
	float matrix[9];
 | 
			
		||||
	enum wl_output_transform transform =
 | 
			
		||||
		wlr_output_transform_invert(surface->current.transform);
 | 
			
		||||
	wlr_matrix_project_box(matrix, &box, transform, 0,
 | 
			
		||||
		output->transform_matrix);
 | 
			
		||||
 | 
			
		||||
	/* This takes our matrix, the texture, and an alpha, and performs the actual
 | 
			
		||||
	 * rendering on the GPU. */
 | 
			
		||||
	wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
 | 
			
		||||
 | 
			
		||||
	/* This lets the client know that we've displayed that frame and it can
 | 
			
		||||
	 * prepare another one now if it likes. */
 | 
			
		||||
	wlr_surface_send_frame_done(surface, rdata->when);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void render_layer_surface(struct wlr_surface *surface,
 | 
			
		||||
		int sx, int sy, void *data) {
 | 
			
		||||
	struct wb_layer_surface *layer_surface = data;
 | 
			
		||||
	struct wlr_texture *texture = wlr_surface_get_texture(surface);
 | 
			
		||||
	if (texture == NULL) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct wlr_output *output = layer_surface->layer_surface->output;
 | 
			
		||||
	double ox = 0, oy = 0;
 | 
			
		||||
	wlr_output_layout_output_coords(
 | 
			
		||||
			layer_surface->server->output_layout, output, &ox, &oy);
 | 
			
		||||
	ox += layer_surface->geo.x + sx, oy += layer_surface->geo.y + sy;
 | 
			
		||||
	float matrix[9];
 | 
			
		||||
	enum wl_output_transform transform =
 | 
			
		||||
		wlr_output_transform_invert(surface->current.transform);
 | 
			
		||||
	struct wlr_box box;
 | 
			
		||||
	memcpy(&box, &layer_surface->geo, sizeof(struct wlr_box));
 | 
			
		||||
	wlr_matrix_project_box(matrix, &box, transform, 0,
 | 
			
		||||
		output->transform_matrix);
 | 
			
		||||
	wlr_render_texture_with_matrix(layer_surface->server->renderer,
 | 
			
		||||
			texture, matrix, 1);
 | 
			
		||||
	struct timespec now;
 | 
			
		||||
	clock_gettime(CLOCK_MONOTONIC, &now);
 | 
			
		||||
	wlr_scene_output_send_frame_done(scene_output, &now);
 | 
			
		||||
	wlr_surface_send_frame_done(surface, &now);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void output_configuration_applied(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_server *server = wl_container_of(listener, server, wlr_output_manager);
 | 
			
		||||
	struct wlr_output_configuration_v1 *configuration = data;
 | 
			
		||||
	wlr_output_configuration_v1_send_succeeded(configuration);
 | 
			
		||||
static void render_layer(
 | 
			
		||||
		struct wb_output *output, struct wl_list *layer_surfaces) {
 | 
			
		||||
	struct wb_layer_surface *layer_surface;
 | 
			
		||||
	wl_list_for_each(layer_surface, layer_surfaces, link) {
 | 
			
		||||
		struct wlr_layer_surface_v1 *wlr_layer_surface_v1 =
 | 
			
		||||
			layer_surface->layer_surface;
 | 
			
		||||
		wlr_surface_for_each_surface(wlr_layer_surface_v1->surface,
 | 
			
		||||
			render_layer_surface, layer_surface);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void output_configuration_tested(struct wl_listener *listener, void *data) {
 | 
			
		||||
	output_configuration_applied(listener, data);
 | 
			
		||||
}
 | 
			
		||||
void output_frame_notify(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_output *output = wl_container_of(listener, output, frame);
 | 
			
		||||
	struct wlr_renderer *renderer = output->server->renderer;
 | 
			
		||||
 | 
			
		||||
void output_request_state_notify(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_output *output = wl_container_of(listener, output, request_state);
 | 
			
		||||
	const struct wlr_output_event_request_state *event = data;
 | 
			
		||||
	struct timespec now;
 | 
			
		||||
	clock_gettime(CLOCK_MONOTONIC, &now);
 | 
			
		||||
 | 
			
		||||
	struct wlr_output_configuration_v1 *configuration = wlr_output_configuration_v1_create();
 | 
			
		||||
	wlr_output_manager_v1_set_configuration(output->server->wlr_output_manager, configuration);
 | 
			
		||||
	if (!wlr_output_attach_render(output->wlr_output, NULL)) {
 | 
			
		||||
		wlr_log_errno(WLR_ERROR, "%s", _("Couldn't attach renderer to output"));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	int width, height;
 | 
			
		||||
	wlr_output_effective_resolution(output->wlr_output, &width, &height);
 | 
			
		||||
	wlr_renderer_begin(renderer, width, height);
 | 
			
		||||
 | 
			
		||||
	wlr_output_commit_state(output->wlr_output, event->state);
 | 
			
		||||
}
 | 
			
		||||
	float color[4] = {0.4f, 0.4f, 0.4f, 1.0f};
 | 
			
		||||
	wlr_renderer_clear(renderer, color);
 | 
			
		||||
 | 
			
		||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
 | 
			
		||||
	const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
 | 
			
		||||
	struct wb_output *output = event->output->data;
 | 
			
		||||
	output->gamma_lut_changed = true;
 | 
			
		||||
	wlr_output_schedule_frame(output->wlr_output);
 | 
			
		||||
	render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
 | 
			
		||||
	render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
 | 
			
		||||
 | 
			
		||||
	struct wb_view *view;
 | 
			
		||||
	wl_list_for_each_reverse(view, &output->server->views, link) {
 | 
			
		||||
		if (!view->mapped)
 | 
			
		||||
			/* An unmapped view should not be rendered */
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		struct render_data rdata = {
 | 
			
		||||
			.output = output->wlr_output,
 | 
			
		||||
			.renderer = renderer,
 | 
			
		||||
			.view = view,
 | 
			
		||||
			.when = &now,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if (view->xdg_toplevel->base->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
			wlr_xdg_surface_for_each_surface(view->xdg_toplevel->base,
 | 
			
		||||
							render_surface, &rdata);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
 | 
			
		||||
	render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
 | 
			
		||||
 | 
			
		||||
	wlr_output_render_software_cursors(output->wlr_output, NULL);
 | 
			
		||||
	wlr_renderer_end(renderer);
 | 
			
		||||
	wlr_output_commit(output->wlr_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void output_destroy_notify(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_output *output = wl_container_of(listener, output, destroy);
 | 
			
		||||
 | 
			
		||||
	wlr_output_layout_remove(output->server->output_layout, output->wlr_output);
 | 
			
		||||
	wl_list_remove(&output->link);
 | 
			
		||||
	wl_list_remove(&output->destroy.link);
 | 
			
		||||
	wl_list_remove(&output->frame.link);
 | 
			
		||||
	wl_list_remove(&output->request_state.link);
 | 
			
		||||
 | 
			
		||||
	/* Frees the layers */
 | 
			
		||||
	size_t num_layers = sizeof(output->layers) / sizeof(struct wlr_scene_node *);
 | 
			
		||||
	for (size_t i = 0; i < num_layers; i++) {
 | 
			
		||||
		struct wlr_scene_node *node =
 | 
			
		||||
			((struct wlr_scene_node **) &output->layers)[i];
 | 
			
		||||
		wlr_scene_node_destroy(node);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&output->link);
 | 
			
		||||
	free(output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -101,38 +172,32 @@ void new_output_notify(struct wl_listener *listener, void *data) {
 | 
			
		|||
         * and our renderer */
 | 
			
		||||
	wlr_output_init_render(wlr_output, server->allocator, server->renderer);
 | 
			
		||||
 | 
			
		||||
	if (!wl_list_empty(&wlr_output->modes)) {
 | 
			
		||||
		struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
 | 
			
		||||
	struct wlr_output_state state;
 | 
			
		||||
	wlr_output_state_init(&state);
 | 
			
		||||
	wlr_output_state_set_enabled(&state, true);
 | 
			
		||||
		wlr_output_set_mode(wlr_output, mode);
 | 
			
		||||
		wlr_output_enable(wlr_output, true);
 | 
			
		||||
 | 
			
		||||
	if (mode != NULL) {
 | 
			
		||||
		wlr_output_state_set_mode(&state, mode);
 | 
			
		||||
		if (!wlr_output_commit(wlr_output)) {
 | 
			
		||||
			wlr_log_errno(WLR_ERROR, "%s", _("Couldn't commit pending frame to output"));
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_output_commit_state(wlr_output, &state);
 | 
			
		||||
	wlr_output_state_finish(&state);
 | 
			
		||||
 | 
			
		||||
	struct wb_output *output = calloc(1, sizeof(struct wb_output));
 | 
			
		||||
	output->server = server;
 | 
			
		||||
	output->wlr_output = wlr_output;
 | 
			
		||||
	wlr_output->data = output;
 | 
			
		||||
 | 
			
		||||
	/* Initializes the layers */
 | 
			
		||||
	size_t num_layers = sizeof(output->layers) / sizeof(struct wlr_scene_node *);
 | 
			
		||||
	for (size_t i = 0; i < num_layers; i++) {
 | 
			
		||||
		((struct wlr_scene_node **) &output->layers)[i] =
 | 
			
		||||
			&wlr_scene_tree_create(&server->scene->tree)->node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_insert(&server->outputs, &output->link);
 | 
			
		||||
 | 
			
		||||
	wl_list_init(&output->layers[0]);
 | 
			
		||||
	wl_list_init(&output->layers[1]);
 | 
			
		||||
	wl_list_init(&output->layers[2]);
 | 
			
		||||
	wl_list_init(&output->layers[3]);
 | 
			
		||||
 | 
			
		||||
	output->destroy.notify = output_destroy_notify;
 | 
			
		||||
	wl_signal_add(&wlr_output->events.destroy, &output->destroy);
 | 
			
		||||
	output->frame.notify = output_frame_notify;
 | 
			
		||||
	wl_signal_add(&wlr_output->events.frame, &output->frame);
 | 
			
		||||
	output->request_state.notify = output_request_state_notify;
 | 
			
		||||
	wl_signal_add(&wlr_output->events.request_state, &output->request_state);
 | 
			
		||||
 | 
			
		||||
	/* Adds this to the output layout. The add_auto function arranges outputs
 | 
			
		||||
	 * from left-to-right in the order they appear. A more sophisticated
 | 
			
		||||
| 
						 | 
				
			
			@ -143,29 +208,5 @@ void new_output_notify(struct wl_listener *listener, void *data) {
 | 
			
		|||
	 * display, which Wayland clients can see to find out information about the
 | 
			
		||||
	 * output (such as DPI, scale factor, manufacturer, etc).
 | 
			
		||||
	 */
 | 
			
		||||
	struct wlr_output_layout_output *l_output =
 | 
			
		||||
	wlr_output_layout_add_auto(server->output_layout, wlr_output);
 | 
			
		||||
	if (!l_output) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Could not add an output layout."));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wlr_output_configuration_v1 *configuration = wlr_output_configuration_v1_create();
 | 
			
		||||
	wlr_output_configuration_head_v1_create(configuration, wlr_output);
 | 
			
		||||
	wlr_output_manager_v1_set_configuration(server->wlr_output_manager, configuration);
 | 
			
		||||
 | 
			
		||||
	struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output);
 | 
			
		||||
	wlr_scene_output_layout_add_output(server->scene_layout, l_output, scene_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_output(struct wb_server *server) {
 | 
			
		||||
	wl_list_init(&server->outputs);
 | 
			
		||||
 | 
			
		||||
	server->new_output.notify = new_output_notify;
 | 
			
		||||
	wl_signal_add(&server->backend->events.new_output, &server->new_output);
 | 
			
		||||
 | 
			
		||||
	server->wlr_output_manager = wlr_output_manager_v1_create(server->wl_display);
 | 
			
		||||
	server->output_configuration_applied.notify = output_configuration_applied;
 | 
			
		||||
	wl_signal_add(&server->wlr_output_manager->events.apply, &server->output_configuration_applied);
 | 
			
		||||
	wl_signal_add(&server->wlr_output_manager->events.test, &server->output_configuration_tested);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										322
									
								
								waybox/seat.c
									
										
									
									
									
								
							
							
						
						
									
										322
									
								
								waybox/seat.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,58 +1,43 @@
 | 
			
		|||
#include <libevdev/libevdev.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <wlr/config.h>
 | 
			
		||||
#if WLR_HAS_LIBINPUT_BACKEND && defined(HAS_LIBINPUT)
 | 
			
		||||
#include <wlr/backend/libinput.h>
 | 
			
		||||
#else
 | 
			
		||||
#undef HAS_LIBINPUT
 | 
			
		||||
#endif
 | 
			
		||||
#include <wlr/backend/session.h>
 | 
			
		||||
#include <wlr/types/wlr_primary_selection.h>
 | 
			
		||||
#include <wlr/types/wlr_primary_selection_v1.h>
 | 
			
		||||
 | 
			
		||||
#include "waybox/seat.h"
 | 
			
		||||
#include "waybox/xdg_shell.h"
 | 
			
		||||
 | 
			
		||||
static void deiconify_toplevel(struct wb_toplevel *toplevel) {
 | 
			
		||||
	if (toplevel->xdg_toplevel->requested.minimized) {
 | 
			
		||||
		toplevel->xdg_toplevel->requested.minimized = false;
 | 
			
		||||
		wl_signal_emit(&toplevel->xdg_toplevel->events.request_minimize, NULL);
 | 
			
		||||
static void deiconify_view(struct wb_view *view) {
 | 
			
		||||
	if (view->xdg_toplevel->requested.minimized) {
 | 
			
		||||
		view->xdg_toplevel->requested.minimized = false;
 | 
			
		||||
		wl_signal_emit(&view->xdg_toplevel->events.request_minimize, NULL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cycle_toplevels(struct wb_server *server) {
 | 
			
		||||
	/* Cycle to the next toplevel */
 | 
			
		||||
	if (wl_list_length(&server->toplevels) < 1) {
 | 
			
		||||
static void cycle_views(struct wb_server *server) {
 | 
			
		||||
	/* Cycle to the next view */
 | 
			
		||||
	if (wl_list_length(&server->views) < 1) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wb_toplevel *current_toplevel = wl_container_of(
 | 
			
		||||
		server->toplevels.prev, current_toplevel, link);
 | 
			
		||||
	deiconify_toplevel(current_toplevel);
 | 
			
		||||
	focus_toplevel(current_toplevel);
 | 
			
		||||
 | 
			
		||||
	/* Move the current toplevel to the beginning of the list */
 | 
			
		||||
	wl_list_remove(¤t_toplevel->link);
 | 
			
		||||
	wl_list_insert(&server->toplevels, ¤t_toplevel->link);
 | 
			
		||||
	struct wb_view *current_view = wl_container_of(
 | 
			
		||||
		server->views.prev, current_view, link);
 | 
			
		||||
	deiconify_view(current_view);
 | 
			
		||||
	focus_view(current_view, current_view->xdg_toplevel->base->surface);
 | 
			
		||||
	/* Move the current view to the beginning of the list */
 | 
			
		||||
	wl_list_remove(¤t_view->link);
 | 
			
		||||
	wl_list_insert(&server->views, ¤t_view->link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cycle_toplevels_reverse(struct wb_server *server) {
 | 
			
		||||
	/* Cycle to the previous toplevel */
 | 
			
		||||
	if (wl_list_length(&server->toplevels) < 1) {
 | 
			
		||||
static void cycle_views_reverse(struct wb_server *server) {
 | 
			
		||||
	/* Cycle to the previous view */
 | 
			
		||||
	if (wl_list_length(&server->views) < 1) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wb_toplevel *current_toplevel = wl_container_of(
 | 
			
		||||
		server->toplevels.next, current_toplevel, link);
 | 
			
		||||
	struct wb_toplevel *next_toplevel = wl_container_of(
 | 
			
		||||
		current_toplevel->link.next, next_toplevel, link);
 | 
			
		||||
	deiconify_toplevel(next_toplevel);
 | 
			
		||||
	focus_toplevel(next_toplevel);
 | 
			
		||||
 | 
			
		||||
	/* Move the current toplevel to after the previous toplevel in the list */
 | 
			
		||||
	wl_list_remove(¤t_toplevel->link);
 | 
			
		||||
	wl_list_insert(server->toplevels.prev, ¤t_toplevel->link);
 | 
			
		||||
	struct wb_view *current_view = wl_container_of(
 | 
			
		||||
		server->views.next, current_view, link);
 | 
			
		||||
	struct wb_view *next_view = wl_container_of(
 | 
			
		||||
		current_view->link.next, next_view, link);
 | 
			
		||||
	deiconify_view(next_view);
 | 
			
		||||
	focus_view(next_view, next_view->xdg_toplevel->base->surface);
 | 
			
		||||
	/* Move the current view to after the previous view in the list */
 | 
			
		||||
	wl_list_remove(¤t_view->link);
 | 
			
		||||
	wl_list_insert(server->views.prev, ¤t_view->link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32_t modifiers) {
 | 
			
		||||
| 
						 | 
				
			
			@ -64,25 +49,14 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32
 | 
			
		|||
	 * Returns true if the keybinding is handled, false to send it to the
 | 
			
		||||
	 * client.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/* TODO: Make these configurable through rc.xml */
 | 
			
		||||
	if (modifiers & (WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT) &&
 | 
			
		||||
		sym >= XKB_KEY_XF86Switch_VT_1 &&
 | 
			
		||||
		sym <= XKB_KEY_XF86Switch_VT_12) {
 | 
			
		||||
		unsigned int vt = sym - XKB_KEY_XF86Switch_VT_1 + 1;
 | 
			
		||||
		wlr_session_change_vt (server->session, vt);
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!server->config) {
 | 
			
		||||
		/* Some default key bindings, when the rc.xml file can't be
 | 
			
		||||
		 * parsed. */
 | 
			
		||||
		if (modifiers & WLR_MODIFIER_ALT && sym == XKB_KEY_Tab)
 | 
			
		||||
			cycle_toplevels(server);
 | 
			
		||||
			cycle_views(server);
 | 
			
		||||
		else if (modifiers & (WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT) &&
 | 
			
		||||
				sym == XKB_KEY_Tab)
 | 
			
		||||
			cycle_toplevels_reverse(server);
 | 
			
		||||
			cycle_views_reverse(server);
 | 
			
		||||
		else if (sym == XKB_KEY_Escape && modifiers & WLR_MODIFIER_CTRL)
 | 
			
		||||
			wl_display_terminate(server->wl_display);
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -94,14 +68,18 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32
 | 
			
		|||
	wl_list_for_each(key_binding, &server->config->key_bindings, link) {
 | 
			
		||||
		if (sym == key_binding->sym && modifiers == key_binding->modifiers) {
 | 
			
		||||
			if (key_binding->action & ACTION_NEXT_WINDOW)
 | 
			
		||||
				cycle_toplevels(server);
 | 
			
		||||
				cycle_views(server);
 | 
			
		||||
			if (key_binding->action & ACTION_PREVIOUS_WINDOW)
 | 
			
		||||
				cycle_toplevels_reverse(server);
 | 
			
		||||
				cycle_views_reverse(server);
 | 
			
		||||
			if (key_binding->action & ACTION_CLOSE) {
 | 
			
		||||
				struct wb_toplevel *current_toplevel = wl_container_of(
 | 
			
		||||
						server->toplevels.next, current_toplevel, link);
 | 
			
		||||
				if (current_toplevel->scene_tree->node.enabled)
 | 
			
		||||
					wlr_xdg_toplevel_send_close(current_toplevel->xdg_toplevel);
 | 
			
		||||
				struct wb_view *current_view = wl_container_of(
 | 
			
		||||
						server->views.next, current_view, link);
 | 
			
		||||
				if (current_view->mapped)
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
					wlr_xdg_toplevel_send_close(current_view->xdg_toplevel);
 | 
			
		||||
#else
 | 
			
		||||
					wlr_xdg_toplevel_send_close(current_view->xdg_surface);
 | 
			
		||||
#endif
 | 
			
		||||
			 }
 | 
			
		||||
			if (key_binding->action & ACTION_EXECUTE) {
 | 
			
		||||
				if (fork() == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -109,38 +87,42 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (key_binding->action & ACTION_TOGGLE_MAXIMIZE) {
 | 
			
		||||
				struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link);
 | 
			
		||||
				if (toplevel->scene_tree->node.enabled)
 | 
			
		||||
					wl_signal_emit(&toplevel->xdg_toplevel->events.request_maximize, NULL);
 | 
			
		||||
				struct wb_view *view = wl_container_of(server->views.next, view, link);
 | 
			
		||||
				if (view->mapped)
 | 
			
		||||
					wl_signal_emit(&view->xdg_toplevel->events.request_maximize, NULL);
 | 
			
		||||
			}
 | 
			
		||||
			if (key_binding->action & ACTION_ICONIFY) {
 | 
			
		||||
				struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link);
 | 
			
		||||
				if (toplevel->scene_tree->node.enabled) {
 | 
			
		||||
					toplevel->xdg_toplevel->requested.minimized = true;
 | 
			
		||||
					wl_signal_emit(&toplevel->xdg_toplevel->events.request_minimize, NULL);
 | 
			
		||||
				struct wb_view *view = wl_container_of(server->views.next, view, link);
 | 
			
		||||
				if (view->mapped) {
 | 
			
		||||
					view->xdg_toplevel->requested.minimized = true;
 | 
			
		||||
					wl_signal_emit(&view->xdg_toplevel->events.request_minimize, NULL);
 | 
			
		||||
					struct wb_view *previous_view = wl_container_of(server->views.prev, previous_view, link);
 | 
			
		||||
					focus_view(previous_view, previous_view->xdg_toplevel->base->surface);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (key_binding->action & ACTION_SHADE) {
 | 
			
		||||
				struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link);
 | 
			
		||||
				if (toplevel->scene_tree->node.enabled) {
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 19, 0)
 | 
			
		||||
					struct wlr_box geo_box = toplevel->xdg_toplevel->base->geometry;
 | 
			
		||||
				struct wb_view *view = wl_container_of(server->views.next, view, link);
 | 
			
		||||
				if (view->mapped) {
 | 
			
		||||
					view->previous_position = view->current_position;
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
					wlr_xdg_toplevel_set_size(view->xdg_toplevel,
 | 
			
		||||
							view->current_position.width, view->decoration_height);
 | 
			
		||||
#else
 | 
			
		||||
					struct wlr_box geo_box;
 | 
			
		||||
					wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box);
 | 
			
		||||
					wlr_xdg_toplevel_set_size(view->xdg_surface,
 | 
			
		||||
							view->current_position.width, view->decoration_height);
 | 
			
		||||
#endif
 | 
			
		||||
					int decoration_height = MAX(geo_box.y - toplevel->geometry.y, TITLEBAR_HEIGHT);
 | 
			
		||||
 | 
			
		||||
					toplevel->previous_geometry = toplevel->geometry;
 | 
			
		||||
					wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel,
 | 
			
		||||
							toplevel->geometry.width, decoration_height);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (key_binding->action & ACTION_UNSHADE) {
 | 
			
		||||
				struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link);
 | 
			
		||||
				if (toplevel->previous_geometry.height > 0 && toplevel->previous_geometry.width > 0 && toplevel->scene_tree->node.enabled) {
 | 
			
		||||
					wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel,
 | 
			
		||||
							toplevel->previous_geometry.width, toplevel->previous_geometry.height);
 | 
			
		||||
				struct wb_view *view = wl_container_of(server->views.next, view, link);
 | 
			
		||||
				if (view->mapped) {
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
					wlr_xdg_toplevel_set_size(view->xdg_toplevel,
 | 
			
		||||
							view->previous_position.width, view->previous_position.height);
 | 
			
		||||
#else
 | 
			
		||||
					wlr_xdg_toplevel_set_size(view->xdg_surface,
 | 
			
		||||
							view->previous_position.width, view->previous_position.height);
 | 
			
		||||
#endif
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (key_binding->action & ACTION_RECONFIGURE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -155,19 +137,6 @@ static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32
 | 
			
		|||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void keyboard_handle_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* This event is raised by the keyboard base wlr_input_device to signal
 | 
			
		||||
	 * the destruction of the wlr_keyboard. It will no longer receive events
 | 
			
		||||
	 * and should be destroyed.
 | 
			
		||||
	 */
 | 
			
		||||
	struct wb_keyboard *keyboard = wl_container_of(listener, keyboard, destroy);
 | 
			
		||||
	wl_list_remove(&keyboard->destroy.link);
 | 
			
		||||
	wl_list_remove(&keyboard->key.link);
 | 
			
		||||
	wl_list_remove(&keyboard->modifiers.link);
 | 
			
		||||
	wl_list_remove(&keyboard->link);
 | 
			
		||||
	free(keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void keyboard_handle_modifiers(
 | 
			
		||||
		struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* This event is raised when a modifier key, such as shift or alt, is
 | 
			
		||||
| 
						 | 
				
			
			@ -180,10 +149,10 @@ static void keyboard_handle_modifiers(
 | 
			
		|||
	 * same seat. You can swap out the underlying wlr_keyboard like this and
 | 
			
		||||
	 * wlr_seat handles this transparently.
 | 
			
		||||
	 */
 | 
			
		||||
	wlr_seat_set_keyboard(keyboard->server->seat->seat, keyboard->keyboard);
 | 
			
		||||
	wlr_seat_set_keyboard(keyboard->server->seat->seat, keyboard->device);
 | 
			
		||||
	/* Send modifiers to the client. */
 | 
			
		||||
	wlr_seat_keyboard_notify_modifiers(keyboard->server->seat->seat,
 | 
			
		||||
		&keyboard->keyboard->modifiers);
 | 
			
		||||
		&keyboard->device->keyboard->modifiers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void keyboard_handle_key(
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +161,7 @@ static void keyboard_handle_key(
 | 
			
		|||
	struct wb_keyboard *keyboard =
 | 
			
		||||
		wl_container_of(listener, keyboard, key);
 | 
			
		||||
	struct wb_server *server = keyboard->server;
 | 
			
		||||
	struct wlr_keyboard_key_event *event = data;
 | 
			
		||||
	struct wlr_event_keyboard_key *event = data;
 | 
			
		||||
	struct wlr_seat *seat = server->seat->seat;
 | 
			
		||||
 | 
			
		||||
	/* Translate libinput keycode -> xkbcommon */
 | 
			
		||||
| 
						 | 
				
			
			@ -200,10 +169,10 @@ static void keyboard_handle_key(
 | 
			
		|||
	/* Get a list of keysyms based on the keymap for this keyboard */
 | 
			
		||||
	const xkb_keysym_t *syms;
 | 
			
		||||
	int nsyms = xkb_state_key_get_syms(
 | 
			
		||||
			keyboard->keyboard->xkb_state, keycode, &syms);
 | 
			
		||||
			keyboard->device->keyboard->xkb_state, keycode, &syms);
 | 
			
		||||
 | 
			
		||||
	bool handled = false;
 | 
			
		||||
	uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->keyboard);
 | 
			
		||||
	uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
 | 
			
		||||
	if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
 | 
			
		||||
		for (int i = 0; i < nsyms; i++) {
 | 
			
		||||
			handled = handle_keybinding(server, syms[i], modifiers);
 | 
			
		||||
| 
						 | 
				
			
			@ -212,12 +181,10 @@ static void keyboard_handle_key(
 | 
			
		|||
 | 
			
		||||
	if (!handled) {
 | 
			
		||||
		/* Otherwise, we pass it along to the client. */
 | 
			
		||||
		wlr_seat_set_keyboard(seat, keyboard->keyboard);
 | 
			
		||||
		wlr_seat_set_keyboard(seat, keyboard->device);
 | 
			
		||||
		wlr_seat_keyboard_notify_key(seat, event->time_msec,
 | 
			
		||||
			event->keycode, event->state);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_idle_notifier_v1_notify_activity(server->idle_notifier, seat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_new_keyboard(struct wb_server *server,
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +192,7 @@ static void handle_new_keyboard(struct wb_server *server,
 | 
			
		|||
	struct wb_keyboard *keyboard =
 | 
			
		||||
		calloc(1, sizeof(struct wb_keyboard));
 | 
			
		||||
	keyboard->server = server;
 | 
			
		||||
	keyboard->keyboard = wlr_keyboard_from_input_device(device);
 | 
			
		||||
	keyboard->device = device;
 | 
			
		||||
 | 
			
		||||
	/* We need to prepare an XKB keymap and assign it to the keyboard. */
 | 
			
		||||
	struct xkb_rule_names *rules = malloc(sizeof(struct xkb_rule_names));
 | 
			
		||||
| 
						 | 
				
			
			@ -252,134 +219,25 @@ static void handle_new_keyboard(struct wb_server *server,
 | 
			
		|||
		XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
 | 
			
		||||
	if (keymap != NULL) {
 | 
			
		||||
		wlr_keyboard_set_keymap(keyboard->keyboard, keymap);
 | 
			
		||||
		wlr_keyboard_set_repeat_info(keyboard->keyboard, 25, 600);
 | 
			
		||||
		wlr_keyboard_set_keymap(device->keyboard, keymap);
 | 
			
		||||
		wlr_keyboard_set_repeat_info(device->keyboard, 25, 600);
 | 
			
		||||
	}
 | 
			
		||||
	free(rules);
 | 
			
		||||
	xkb_keymap_unref(keymap);
 | 
			
		||||
	xkb_context_unref(context);
 | 
			
		||||
 | 
			
		||||
	/* Here we set up listeners for keyboard events. */
 | 
			
		||||
	keyboard->destroy.notify = keyboard_handle_destroy;
 | 
			
		||||
	wl_signal_add(&device->events.destroy, &keyboard->destroy);
 | 
			
		||||
	keyboard->modifiers.notify = keyboard_handle_modifiers;
 | 
			
		||||
	wl_signal_add(&keyboard->keyboard->events.modifiers, &keyboard->modifiers);
 | 
			
		||||
	wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers);
 | 
			
		||||
	keyboard->key.notify = keyboard_handle_key;
 | 
			
		||||
	wl_signal_add(&keyboard->keyboard->events.key, &keyboard->key);
 | 
			
		||||
	wl_signal_add(&device->keyboard->events.key, &keyboard->key);
 | 
			
		||||
 | 
			
		||||
	wlr_seat_set_keyboard(server->seat->seat, keyboard->keyboard);
 | 
			
		||||
	wlr_seat_set_keyboard(server->seat->seat, device);
 | 
			
		||||
 | 
			
		||||
	/* And add the keyboard to our list of keyboards */
 | 
			
		||||
	wl_list_insert(&server->seat->keyboards, &keyboard->link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_LIBINPUT
 | 
			
		||||
static bool libinput_config_get_enabled(char *config) {
 | 
			
		||||
	return strcmp(config, "disabled") != 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void handle_new_pointer(struct wb_server *server, struct wlr_input_device *device) {
 | 
			
		||||
#ifdef HAS_LIBINPUT
 | 
			
		||||
	struct wb_config *config = server->config;
 | 
			
		||||
	if (wlr_input_device_is_libinput(device) && config->libinput_config.use_config) {
 | 
			
		||||
		struct libinput_device *libinput_handle =
 | 
			
		||||
			wlr_libinput_get_device_handle(device);
 | 
			
		||||
 | 
			
		||||
		if (config->libinput_config.accel_profile) {
 | 
			
		||||
			enum libinput_config_accel_profile accel_profile =
 | 
			
		||||
				LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
 | 
			
		||||
			if (strcmp(config->libinput_config.accel_profile, "flat") == 0)
 | 
			
		||||
				accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
 | 
			
		||||
			else if (strcmp(config->libinput_config.accel_profile, "none") == 0)
 | 
			
		||||
				accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
 | 
			
		||||
			libinput_device_config_accel_set_profile(libinput_handle, accel_profile);
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.accel_speed) {
 | 
			
		||||
			double accel_speed = strtod(config->libinput_config.accel_speed, NULL);
 | 
			
		||||
			libinput_device_config_accel_set_speed(libinput_handle, accel_speed);
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.calibration_matrix) {
 | 
			
		||||
			float matrix[6];
 | 
			
		||||
			unsigned short i = 0;
 | 
			
		||||
			while ((matrix[i] = strtod(strtok(config->libinput_config.calibration_matrix, " "), NULL) && i < 6)) {
 | 
			
		||||
				config->libinput_config.calibration_matrix = NULL;
 | 
			
		||||
				i++;
 | 
			
		||||
			}
 | 
			
		||||
			libinput_device_config_calibration_set_matrix(libinput_handle, matrix);
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.click_method) {
 | 
			
		||||
			enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
 | 
			
		||||
			if (strcmp(config->libinput_config.click_method, "clickfinger") == 0)
 | 
			
		||||
				click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
 | 
			
		||||
			else if (strcmp(config->libinput_config.click_method, "none") == 0)
 | 
			
		||||
				click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
 | 
			
		||||
			libinput_device_config_click_set_method(libinput_handle, click_method);
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.dwt) {
 | 
			
		||||
			libinput_device_config_dwt_set_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.dwt));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.dwtp) {
 | 
			
		||||
			libinput_device_config_dwtp_set_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.dwtp));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.left_handed) {
 | 
			
		||||
			libinput_device_config_left_handed_set(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.left_handed));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.middle_emulation) {
 | 
			
		||||
			libinput_device_config_middle_emulation_set_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.middle_emulation));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.natural_scroll) {
 | 
			
		||||
			libinput_device_config_scroll_set_natural_scroll_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.natural_scroll));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.scroll_button) {
 | 
			
		||||
			int button = libevdev_event_code_from_name(EV_KEY, config->libinput_config.scroll_button);
 | 
			
		||||
			if (button != -1) {
 | 
			
		||||
				libinput_device_config_scroll_set_button(libinput_handle, button);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.scroll_button_lock) {
 | 
			
		||||
			libinput_device_config_scroll_set_button_lock(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.scroll_button_lock));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.scroll_method) {
 | 
			
		||||
			enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
 | 
			
		||||
			if (strcmp(config->libinput_config.scroll_method, "edge") == 0)
 | 
			
		||||
				scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
 | 
			
		||||
			else if (strcmp(config->libinput_config.scroll_method, "none") == 0)
 | 
			
		||||
				scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
 | 
			
		||||
			else if (strcmp(config->libinput_config.scroll_method, "button") == 0)
 | 
			
		||||
				scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
 | 
			
		||||
			libinput_device_config_scroll_set_method(libinput_handle, scroll_method);
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.tap) {
 | 
			
		||||
			libinput_device_config_tap_set_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.tap));
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.tap_button_map) {
 | 
			
		||||
			enum libinput_config_tap_button_map map = LIBINPUT_CONFIG_TAP_MAP_LRM;
 | 
			
		||||
			if (strcmp(config->libinput_config.tap_button_map, "lmr") == 0)
 | 
			
		||||
				map = LIBINPUT_CONFIG_TAP_MAP_LMR;
 | 
			
		||||
			libinput_device_config_tap_set_button_map(libinput_handle, map);
 | 
			
		||||
		}
 | 
			
		||||
		if (config->libinput_config.tap_drag) {
 | 
			
		||||
			libinput_device_config_tap_set_drag_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.tap_drag));
 | 
			
		||||
		};
 | 
			
		||||
		if (config->libinput_config.tap_drag_lock) {
 | 
			
		||||
			libinput_device_config_tap_set_drag_lock_enabled(libinput_handle,
 | 
			
		||||
					libinput_config_get_enabled(config->libinput_config.tap_drag_lock));
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	wlr_cursor_attach_input_device(server->cursor->cursor, device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void new_input_notify(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wlr_input_device *device = data;
 | 
			
		||||
	struct wb_server *server = wl_container_of(listener, server, new_input);
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +248,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
 | 
			
		|||
			break;
 | 
			
		||||
		case WLR_INPUT_DEVICE_POINTER:
 | 
			
		||||
			wlr_log(WLR_INFO, "%s: %s", _("New pointer detected"), device->name);
 | 
			
		||||
			handle_new_pointer(server, device);
 | 
			
		||||
			wlr_cursor_attach_input_device(server->cursor->cursor, device);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			wlr_log(WLR_INFO, "%s: %s", _("Unsupported input device detected"), device->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -404,30 +262,6 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
 | 
			
		|||
	wlr_seat_set_capabilities(server->seat->seat, caps);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void seat_focus_surface(struct wb_seat *seat, struct wlr_surface *surface) {
 | 
			
		||||
	if (!surface) {
 | 
			
		||||
		wlr_seat_keyboard_notify_clear_focus(seat->seat);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat->seat);
 | 
			
		||||
	if (kb != NULL) {
 | 
			
		||||
		wlr_seat_keyboard_notify_enter(seat->seat, surface, kb->keycodes,
 | 
			
		||||
			kb->num_keycodes, &kb->modifiers);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void seat_set_focus_layer(struct wb_seat *seat, struct wlr_layer_surface_v1 *layer) {
 | 
			
		||||
	if (!layer) {
 | 
			
		||||
		seat->focused_layer = NULL;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	seat_focus_surface(seat, layer->surface);
 | 
			
		||||
	if (layer->current.layer > ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
 | 
			
		||||
		seat->focused_layer = layer;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_request_set_primary_selection(struct wl_listener *listener,
 | 
			
		||||
		void *data) {
 | 
			
		||||
	struct wb_seat *seat =
 | 
			
		||||
| 
						 | 
				
			
			@ -465,8 +299,8 @@ struct wb_seat *wb_seat_create(struct wb_server *server) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void wb_seat_destroy(struct wb_seat *seat) {
 | 
			
		||||
	wl_list_remove(&seat->keyboards);
 | 
			
		||||
	wl_list_remove(&seat->request_set_primary_selection.link);
 | 
			
		||||
	wl_list_remove(&seat->request_set_selection.link);
 | 
			
		||||
	wlr_seat_destroy(seat->seat);
 | 
			
		||||
	free(seat);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,5 @@
 | 
			
		|||
#include <wlr/types/wlr_data_control_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_fractional_scale_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_viewporter.h>
 | 
			
		||||
 | 
			
		||||
#include "idle.h"
 | 
			
		||||
#include "waybox/server.h"
 | 
			
		||||
#include "waybox/xdg_shell.h"
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 19, 0)
 | 
			
		||||
#	include <wlr/types/wlr_xdg_toplevel_icon_v1.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool wb_create_backend(struct wb_server* server) {
 | 
			
		||||
	/* The Wayland display is managed by libwayland. It handles accepting
 | 
			
		||||
| 
						 | 
				
			
			@ -18,19 +10,12 @@ bool wb_create_backend(struct wb_server* server) {
 | 
			
		|||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
 | 
			
		||||
	if (server->wl_event_loop == NULL) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Failed to get an event loop"));
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* The backend is a wlroots feature which abstracts the underlying input and
 | 
			
		||||
	 * output hardware. The autocreate option will choose the most suitable
 | 
			
		||||
	 * backend based on the current environment, such as opening an X11 window
 | 
			
		||||
	 * if an X11 server is running. */
 | 
			
		||||
	server->backend = wlr_backend_autocreate(server->wl_event_loop, &server->session);
 | 
			
		||||
	server->backend = wlr_backend_autocreate(server->wl_display);
 | 
			
		||||
	if (server->backend == NULL) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Failed to create backend"));
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,11 +24,6 @@ bool wb_create_backend(struct wb_server* server) {
 | 
			
		|||
         * The renderer is responsible for defining the various pixel formats it
 | 
			
		||||
         * supports for shared memory, this configures that for clients. */
 | 
			
		||||
	server->renderer = wlr_renderer_autocreate(server->backend);
 | 
			
		||||
	if (server->renderer == NULL) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Failed to create renderer"));
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_renderer_init_wl_display(server->renderer, server->wl_display);
 | 
			
		||||
 | 
			
		||||
        /* Autocreates an allocator for us.
 | 
			
		||||
| 
						 | 
				
			
			@ -51,15 +31,13 @@ bool wb_create_backend(struct wb_server* server) {
 | 
			
		|||
         * handles the buffer creation, allowing wlroots to render onto the
 | 
			
		||||
         * screen */
 | 
			
		||||
        server->allocator = wlr_allocator_autocreate(server->backend, server->renderer);
 | 
			
		||||
	if (server->allocator == NULL) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "%s", _("Failed to create allocator"));
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	server->compositor =
 | 
			
		||||
		wlr_compositor_create(server->wl_display, 5, server->renderer);
 | 
			
		||||
	server->compositor = wlr_compositor_create(server->wl_display,
 | 
			
		||||
			server->renderer);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	server->subcompositor = wlr_subcompositor_create(server->wl_display);
 | 
			
		||||
	server->output_layout = wlr_output_layout_create(server->wl_display);
 | 
			
		||||
#endif
 | 
			
		||||
	server->output_layout = wlr_output_layout_create();
 | 
			
		||||
	server->seat = wb_seat_create(server);
 | 
			
		||||
	server->cursor = wb_cursor_create(server);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -71,17 +49,10 @@ bool wb_create_backend(struct wb_server* server) {
 | 
			
		|||
 | 
			
		||||
bool wb_start_server(struct wb_server* server) {
 | 
			
		||||
	init_config(server);
 | 
			
		||||
	init_output(server);
 | 
			
		||||
	wl_list_init(&server->outputs);
 | 
			
		||||
 | 
			
		||||
	/* Create a scene graph. This is a wlroots abstraction that handles all
 | 
			
		||||
	 * rendering and damage tracking. All the compositor author needs to do
 | 
			
		||||
	 * is add things that should be rendered to the scene graph at the proper
 | 
			
		||||
	 * positions and then call wlr_scene_output_commit() to render a frame if
 | 
			
		||||
	 * necessary.
 | 
			
		||||
	 */
 | 
			
		||||
	server->scene = wlr_scene_create();
 | 
			
		||||
	server->scene_layout =
 | 
			
		||||
		wlr_scene_attach_output_layout(server->scene, server->output_layout);
 | 
			
		||||
	server->new_output.notify = new_output_notify;
 | 
			
		||||
	wl_signal_add(&server->backend->events.new_output, &server->new_output);
 | 
			
		||||
 | 
			
		||||
	const char *socket = wl_display_add_socket_auto(server->wl_display);
 | 
			
		||||
	if (!socket) {
 | 
			
		||||
| 
						 | 
				
			
			@ -99,67 +70,27 @@ bool wb_start_server(struct wb_server* server) {
 | 
			
		|||
	wlr_log(WLR_INFO, "%s: WAYLAND_DISPLAY=%s", _("Running Wayland compositor on Wayland display"), socket);
 | 
			
		||||
	setenv("WAYLAND_DISPLAY", socket, true);
 | 
			
		||||
 | 
			
		||||
	wlr_data_control_manager_v1_create(server->wl_display);
 | 
			
		||||
	wlr_data_device_manager_create(server->wl_display);
 | 
			
		||||
 | 
			
		||||
	server->foreign_toplevel_list =
 | 
			
		||||
		wlr_ext_foreign_toplevel_list_v1_create(server->wl_display, 1);
 | 
			
		||||
 | 
			
		||||
	server->gamma_control_manager =
 | 
			
		||||
	wlr_gamma_control_manager_v1_create(server->wl_display);
 | 
			
		||||
	server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma;
 | 
			
		||||
	wl_signal_add(&server->gamma_control_manager->events.set_gamma, &server->gamma_control_set_gamma);
 | 
			
		||||
 | 
			
		||||
	wlr_screencopy_manager_v1_create(server->wl_display);
 | 
			
		||||
	create_idle_manager(server);
 | 
			
		||||
	wlr_idle_create(server->wl_display);
 | 
			
		||||
 | 
			
		||||
	wl_list_init(&server->toplevels);
 | 
			
		||||
	wlr_data_device_manager_create(server->wl_display);
 | 
			
		||||
	wl_list_init(&server->views);
 | 
			
		||||
	init_xdg_decoration(server);
 | 
			
		||||
	init_layer_shell(server);
 | 
			
		||||
 | 
			
		||||
	/* Set up the xdg-shell. The xdg-shell is a Wayland protocol which is used
 | 
			
		||||
	 * for application windows. For more detail on shells, refer to
 | 
			
		||||
	 * https://drewdevault.com/2018/07/29/Wayland-shells.html
 | 
			
		||||
	 */
 | 
			
		||||
	init_xdg_shell(server);
 | 
			
		||||
 | 
			
		||||
	wlr_fractional_scale_manager_v1_create(server->wl_display, 1);
 | 
			
		||||
	wlr_viewporter_create(server->wl_display);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 19, 0)
 | 
			
		||||
	struct wlr_xdg_toplevel_icon_manager_v1 * icon_manager = wlr_xdg_toplevel_icon_manager_v1_create(server->wl_display, 1);
 | 
			
		||||
	int sizes[] = {16, 24, 32, 48, 64};
 | 
			
		||||
	wlr_xdg_toplevel_icon_manager_v1_set_sizes(icon_manager, (int *) sizes, 5);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool wb_terminate(struct wb_server* server) {
 | 
			
		||||
	wb_cursor_destroy(server->cursor);
 | 
			
		||||
	wl_list_remove(&server->new_xdg_decoration.link); /* wb_decoration_destroy */
 | 
			
		||||
	wb_seat_destroy(server->seat);
 | 
			
		||||
	deinit_config(server->config);
 | 
			
		||||
	wl_display_destroy_clients(server->wl_display);
 | 
			
		||||
	wlr_output_layout_destroy(server->output_layout);
 | 
			
		||||
	wlr_allocator_destroy(server->allocator);
 | 
			
		||||
	wlr_renderer_destroy(server->renderer);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&server->new_input.link);
 | 
			
		||||
	wl_list_remove(&server->new_output.link);
 | 
			
		||||
	wl_list_remove(&server->output_configuration_applied.link);
 | 
			
		||||
	wl_list_remove(&server->output_configuration_tested.link);
 | 
			
		||||
	wl_list_remove(&server->new_inhibitor.link);
 | 
			
		||||
	wl_list_remove(&server->inhibitors);
 | 
			
		||||
	wl_list_remove(&server->destroy_inhibit_manager.link);
 | 
			
		||||
	wl_list_remove(&server->gamma_control_set_gamma.link);
 | 
			
		||||
	wl_list_remove(&server->new_layer_surface.link);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&server->new_xdg_toplevel.link);
 | 
			
		||||
	wl_list_remove(&server->new_xdg_popup.link);
 | 
			
		||||
 | 
			
		||||
	wlr_backend_destroy(server->backend);
 | 
			
		||||
	wb_seat_destroy(server->seat);
 | 
			
		||||
	wl_display_destroy(server->wl_display);
 | 
			
		||||
	wlr_scene_node_destroy(&server->scene->tree.node);
 | 
			
		||||
	wlr_output_layout_destroy(server->output_layout);
 | 
			
		||||
 | 
			
		||||
	wlr_log(WLR_INFO, "%s", _("Display destroyed"));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,335 +1,228 @@
 | 
			
		|||
#include "idle.h"
 | 
			
		||||
#include "waybox/xdg_shell.h"
 | 
			
		||||
 | 
			
		||||
struct wb_toplevel *get_toplevel_at(
 | 
			
		||||
		struct wb_server *server, double lx, double ly,
 | 
			
		||||
		struct wlr_surface **surface, double *sx, double *sy) {
 | 
			
		||||
	/* This returns the topmost node in the scene at the given layout coords.
 | 
			
		||||
	 * we only care about surface nodes as we are specifically looking for a
 | 
			
		||||
	 * surface in the surface tree of a wb_toplevel. */
 | 
			
		||||
	struct wlr_scene_node *node =
 | 
			
		||||
		wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy);
 | 
			
		||||
	if (node == NULL || node->type != WLR_SCENE_NODE_BUFFER) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
 | 
			
		||||
	struct wlr_scene_surface *scene_surface =
 | 
			
		||||
		wlr_scene_surface_try_from_buffer(scene_buffer);
 | 
			
		||||
	if (!scene_surface) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*surface = scene_surface->surface;
 | 
			
		||||
	/* Find the node corresponding to the wb_toplevel at the root of this
 | 
			
		||||
	 * surface tree, it is the only one for which we set the data field. */
 | 
			
		||||
	struct wlr_scene_tree *tree = node->parent;
 | 
			
		||||
	while (tree != NULL && tree->node.data == NULL) {
 | 
			
		||||
		tree = tree->node.parent;
 | 
			
		||||
	}
 | 
			
		||||
	return tree->node.data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void focus_toplevel(struct wb_toplevel *toplevel) {
 | 
			
		||||
void focus_view(struct wb_view *view, struct wlr_surface *surface) {
 | 
			
		||||
	/* Note: this function only deals with keyboard focus. */
 | 
			
		||||
	if (toplevel == NULL || toplevel->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
 | 
			
		||||
	if (view == NULL || surface == NULL || !wlr_surface_is_xdg_surface(surface)) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wlr_surface *surface = toplevel->xdg_toplevel->base->surface;
 | 
			
		||||
	struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_try_from_wlr_surface(surface);
 | 
			
		||||
	if (xdg_surface != NULL)
 | 
			
		||||
	struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_from_wlr_surface(surface);
 | 
			
		||||
	if (xdg_surface)
 | 
			
		||||
		wlr_log(WLR_INFO, "%s: %s", _("Keyboard focus is now on surface"),
 | 
			
		||||
				xdg_surface->toplevel->app_id);
 | 
			
		||||
 | 
			
		||||
	struct wb_server *server = toplevel->server;
 | 
			
		||||
	if (server->seat->focused_layer != NULL) {
 | 
			
		||||
		/* If a layer is focused, don't focus a toplevel. */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct wb_server *server = view->server;
 | 
			
		||||
	struct wlr_seat *seat = server->seat->seat;
 | 
			
		||||
	struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface;
 | 
			
		||||
	if (prev_surface == surface) {
 | 
			
		||||
		/* Don't focus a surface that's already focused. */
 | 
			
		||||
		/* Don't re-focus an already focused surface. */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (prev_surface != NULL) {
 | 
			
		||||
	if (prev_surface) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Deactivate the previously focused surface. This lets the client know
 | 
			
		||||
		 * it no longer has focus and the client will repaint accordingly, e.g.
 | 
			
		||||
		 * stop displaying a caret.
 | 
			
		||||
		 */
 | 
			
		||||
		struct wlr_xdg_toplevel *prev_toplevel =
 | 
			
		||||
			wlr_xdg_toplevel_try_from_wlr_surface(prev_surface);
 | 
			
		||||
		if (prev_toplevel != NULL) {
 | 
			
		||||
			wlr_xdg_toplevel_set_activated(prev_toplevel, false);
 | 
			
		||||
		struct wlr_xdg_surface *previous = wlr_xdg_surface_from_wlr_surface(
 | 
			
		||||
					seat->keyboard_state.focused_surface);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
		wlr_xdg_toplevel_set_activated(previous->toplevel, false);
 | 
			
		||||
#else
 | 
			
		||||
		wlr_xdg_toplevel_set_activated(previous, false);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
	/* Move the toplevel to the front */
 | 
			
		||||
	wlr_scene_node_raise_to_top(&toplevel->scene_tree->node);
 | 
			
		||||
	wl_list_remove(&toplevel->link);
 | 
			
		||||
	wl_list_insert(&server->toplevels, &toplevel->link);
 | 
			
		||||
	struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat);
 | 
			
		||||
	/* Move the view to the front */
 | 
			
		||||
	wl_list_remove(&view->link);
 | 
			
		||||
	wl_list_insert(&server->views, &view->link);
 | 
			
		||||
	/* Activate the new surface */
 | 
			
		||||
	wlr_xdg_toplevel_set_activated(toplevel->xdg_toplevel, true);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	wlr_xdg_toplevel_set_activated(view->xdg_toplevel, true);
 | 
			
		||||
#else
 | 
			
		||||
	wlr_xdg_toplevel_set_activated(view->xdg_surface, true);
 | 
			
		||||
#endif
 | 
			
		||||
	/*
 | 
			
		||||
	 * Tell the seat to have the keyboard enter this surface. wlroots will keep
 | 
			
		||||
	 * track of this and automatically send key events to the appropriate
 | 
			
		||||
	 * clients without additional work on your part.
 | 
			
		||||
	 */
 | 
			
		||||
	seat_focus_surface(server->seat, surface);
 | 
			
		||||
	wlr_seat_keyboard_notify_enter(seat, view->xdg_toplevel->base->surface,
 | 
			
		||||
		keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct wlr_output *get_active_output(struct wb_toplevel *toplevel) {
 | 
			
		||||
static struct wlr_box get_usable_area(struct wb_view *view) {
 | 
			
		||||
	double closest_x, closest_y;
 | 
			
		||||
	struct wlr_output *output = NULL;
 | 
			
		||||
	wlr_output_layout_closest_point(toplevel->server->output_layout, output,
 | 
			
		||||
			toplevel->geometry.x + toplevel->geometry.width / 2,
 | 
			
		||||
			toplevel->geometry.y + toplevel->geometry.height / 2,
 | 
			
		||||
			&closest_x, &closest_y);
 | 
			
		||||
	return wlr_output_layout_output_at(toplevel->server->output_layout, closest_x, closest_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wlr_box get_usable_area(struct wb_toplevel *toplevel) {
 | 
			
		||||
	struct wlr_output *output = get_active_output(toplevel);
 | 
			
		||||
	struct wlr_box usable_area = {0};
 | 
			
		||||
	wlr_output_layout_closest_point(view->server->output_layout, output,
 | 
			
		||||
			view->current_position.x + view->current_position.width / 2,
 | 
			
		||||
			view->current_position.y + view->current_position.height / 2,
 | 
			
		||||
			&closest_x, &closest_y);
 | 
			
		||||
	output = wlr_output_layout_output_at(view->server->output_layout, closest_x, closest_y);
 | 
			
		||||
	wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height);
 | 
			
		||||
	return usable_area;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_map(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called when the surface is mapped, or ready to display on-screen. */
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, map);
 | 
			
		||||
	if (toplevel->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
static void xdg_surface_commit(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called after the surface is committed */
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, surface_commit);
 | 
			
		||||
	struct wlr_xdg_surface *xdg_surface = view->xdg_toplevel->base;
 | 
			
		||||
	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL ||
 | 
			
		||||
			xdg_surface->toplevel->requested.minimized)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	struct wb_config *config = toplevel->server->config;
 | 
			
		||||
	struct wlr_box usable_area = get_usable_area(toplevel);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 19, 0)
 | 
			
		||||
	struct wlr_box geo_box = toplevel->xdg_toplevel->base->geometry;
 | 
			
		||||
#else
 | 
			
		||||
	struct wlr_box geo_box = {0};
 | 
			
		||||
	wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	struct wb_config *config = view->server->config;
 | 
			
		||||
	int left_margin, top_margin;
 | 
			
		||||
	if (config) {
 | 
			
		||||
		toplevel->geometry.height = MIN(geo_box.height,
 | 
			
		||||
				usable_area.height - config->margins.top - config->margins.bottom);
 | 
			
		||||
		toplevel->geometry.width = MIN(geo_box.width,
 | 
			
		||||
				usable_area.width - config->margins.left - config->margins.right);
 | 
			
		||||
		toplevel->geometry.x = config->margins.left;
 | 
			
		||||
		toplevel->geometry.y = config->margins.top;
 | 
			
		||||
		left_margin = config->margins.left;
 | 
			
		||||
		top_margin = config->margins.top;
 | 
			
		||||
	} else {
 | 
			
		||||
		toplevel->geometry.height = MIN(geo_box.height, usable_area.height);
 | 
			
		||||
		toplevel->geometry.width = MIN(geo_box.width, usable_area.width);
 | 
			
		||||
		toplevel->geometry.x = 0;
 | 
			
		||||
		toplevel->geometry.y = 0;
 | 
			
		||||
		left_margin = 0;
 | 
			
		||||
		top_margin = 0;
 | 
			
		||||
	}
 | 
			
		||||
	struct wlr_box geo_box = {0};
 | 
			
		||||
	wlr_xdg_surface_get_geometry(xdg_surface, &geo_box);
 | 
			
		||||
	if (geo_box.x < 0 && view->current_position.x - left_margin < 1)
 | 
			
		||||
		view->current_position.x += -geo_box.x;
 | 
			
		||||
	if (geo_box.y < 0 && view->current_position.y - top_margin < 1) {
 | 
			
		||||
		view->decoration_height = -geo_box.y;
 | 
			
		||||
		view->current_position.y += view->decoration_height;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel,
 | 
			
		||||
			toplevel->geometry.width, toplevel->geometry.height);
 | 
			
		||||
	focus_toplevel(toplevel);
 | 
			
		||||
 | 
			
		||||
	wlr_scene_node_set_position(&toplevel->scene_tree->node,
 | 
			
		||||
			toplevel->geometry.x, toplevel->geometry.y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called when the surface is unmapped, and should no longer be shown. */
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, unmap);
 | 
			
		||||
	if (toplevel->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
static void xdg_surface_map(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called when the surface is mapped, or ready to display on-screen. */
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, map);
 | 
			
		||||
	view->mapped = true;
 | 
			
		||||
	if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
		return;
 | 
			
		||||
	reset_cursor_mode(toplevel->server);
 | 
			
		||||
 | 
			
		||||
	/* Focus the next toplevel, if any. */
 | 
			
		||||
	if (wl_list_length(&toplevel->link) > 1) {
 | 
			
		||||
		struct wb_toplevel *next_toplevel = wl_container_of(toplevel->link.next, next_toplevel, link);
 | 
			
		||||
		if (next_toplevel && next_toplevel->xdg_toplevel && next_toplevel->scene_tree && next_toplevel->scene_tree->node.enabled) {
 | 
			
		||||
			wlr_log(WLR_INFO, "%s: %s", _("Focusing next toplevel"),
 | 
			
		||||
					next_toplevel->xdg_toplevel->app_id);
 | 
			
		||||
			focus_toplevel(next_toplevel);
 | 
			
		||||
	struct wb_config *config = view->server->config;
 | 
			
		||||
	struct wlr_box geo_box = {0};
 | 
			
		||||
	wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
 | 
			
		||||
	view->current_position = geo_box;
 | 
			
		||||
	if (config) {
 | 
			
		||||
		struct wlr_box usable_area = get_usable_area(view);
 | 
			
		||||
		view->current_position.height = MIN(view->current_position.height,
 | 
			
		||||
				usable_area.height - config->margins.top - config->margins.bottom);
 | 
			
		||||
		view->current_position.width = MIN(view->current_position.width,
 | 
			
		||||
				usable_area.width - config->margins.left - config->margins.right);
 | 
			
		||||
		view->current_position.x = config->margins.left;
 | 
			
		||||
		view->current_position.y = config->margins.top;
 | 
			
		||||
	}
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->current_position.width, view->current_position.height);
 | 
			
		||||
#else
 | 
			
		||||
	wlr_xdg_toplevel_set_size(view->xdg_surface, view->current_position.width, view->current_position.height);
 | 
			
		||||
#endif
 | 
			
		||||
	focus_view(view, view->xdg_toplevel->base->surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_surface_unmap(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called when the surface is unmapped, and should no longer be shown. */
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, unmap);
 | 
			
		||||
	view->mapped = false;
 | 
			
		||||
 | 
			
		||||
	struct wb_view *current_view = wl_container_of(view->server->views.next, current_view, link);
 | 
			
		||||
	struct wb_view *next_view = wl_container_of(current_view->link.next, next_view, link);
 | 
			
		||||
	if (current_view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* If the current view is mapped, focus it. */
 | 
			
		||||
	if (current_view->mapped) {
 | 
			
		||||
		wlr_log(WLR_INFO, "%s: %s", _("Focusing current view"),
 | 
			
		||||
				current_view->xdg_toplevel->app_id);
 | 
			
		||||
		focus_view(current_view, current_view->xdg_toplevel->base->surface);
 | 
			
		||||
	}
 | 
			
		||||
	/* Otherwise, focus the next view, if any. */
 | 
			
		||||
	else if (next_view->xdg_toplevel->base->surface &&
 | 
			
		||||
			wlr_surface_is_xdg_surface(next_view->xdg_toplevel->base->surface)) {
 | 
			
		||||
		wlr_log(WLR_INFO, "%s: %s", _("Focusing next view"),
 | 
			
		||||
				next_view->xdg_toplevel->app_id);
 | 
			
		||||
		focus_view(next_view, next_view->xdg_toplevel->base->surface);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void update_fractional_scale(struct wlr_surface *surface) {
 | 
			
		||||
	float scale = 1;
 | 
			
		||||
	struct wlr_surface_output *surface_output;
 | 
			
		||||
	wl_list_for_each(surface_output, &surface->current_outputs, link) {
 | 
			
		||||
		if (surface_output->output->scale > scale) {
 | 
			
		||||
			scale = surface_output->output->scale;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	wlr_fractional_scale_v1_notify_scale(surface, scale);
 | 
			
		||||
	wlr_surface_set_preferred_buffer_scale(surface, ceil(scale));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_commit(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, commit);
 | 
			
		||||
	struct wlr_xdg_surface *base = toplevel->xdg_toplevel->base;
 | 
			
		||||
 | 
			
		||||
	struct wlr_output *output = get_active_output(toplevel);
 | 
			
		||||
	wlr_surface_send_enter(base->surface, output);
 | 
			
		||||
	update_fractional_scale(base->surface);
 | 
			
		||||
 | 
			
		||||
	if (base->initial_commit) {
 | 
			
		||||
		wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0);
 | 
			
		||||
		if (toplevel->decoration != NULL)
 | 
			
		||||
			wl_signal_emit(&toplevel->decoration->events.request_mode, toplevel->decoration);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called when the xdg_toplevel is destroyed and should never be shown again. */
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, destroy);
 | 
			
		||||
 | 
			
		||||
	struct wlr_output *output = get_active_output(toplevel);
 | 
			
		||||
	struct wlr_xdg_surface *base = toplevel->xdg_toplevel->base;
 | 
			
		||||
	wlr_surface_send_leave(base->surface, output);
 | 
			
		||||
	update_fractional_scale(base->surface);
 | 
			
		||||
	wlr_ext_foreign_toplevel_handle_v1_destroy(toplevel->foreign_toplevel_handle);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&toplevel->map.link);
 | 
			
		||||
	wl_list_remove(&toplevel->unmap.link);
 | 
			
		||||
	wl_list_remove(&toplevel->commit.link);
 | 
			
		||||
	wl_list_remove(&toplevel->destroy.link);
 | 
			
		||||
	wl_list_remove(&toplevel->new_popup.link);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&toplevel->request_fullscreen.link);
 | 
			
		||||
	wl_list_remove(&toplevel->request_minimize.link);
 | 
			
		||||
	wl_list_remove(&toplevel->request_maximize.link);
 | 
			
		||||
	wl_list_remove(&toplevel->request_move.link);
 | 
			
		||||
	wl_list_remove(&toplevel->request_resize.link);
 | 
			
		||||
	wl_list_remove(&toplevel->set_app_id.link);
 | 
			
		||||
	wl_list_remove(&toplevel->set_title.link);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&toplevel->link);
 | 
			
		||||
	free(toplevel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_set_app_id(
 | 
			
		||||
		struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_toplevel *toplevel =
 | 
			
		||||
		wl_container_of(listener, toplevel, set_app_id);
 | 
			
		||||
	toplevel->foreign_toplevel_state.app_id = toplevel->xdg_toplevel->app_id;
 | 
			
		||||
	wlr_ext_foreign_toplevel_handle_v1_update_state(
 | 
			
		||||
			toplevel->foreign_toplevel_handle, &toplevel->foreign_toplevel_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_set_title(
 | 
			
		||||
		struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_toplevel *toplevel =
 | 
			
		||||
		wl_container_of(listener, toplevel, set_title);
 | 
			
		||||
	toplevel->foreign_toplevel_state.title = toplevel->xdg_toplevel->title;
 | 
			
		||||
	wlr_ext_foreign_toplevel_handle_v1_update_state(
 | 
			
		||||
			toplevel->foreign_toplevel_handle, &toplevel->foreign_toplevel_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_request_fullscreen(
 | 
			
		||||
		struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* This event is raised when a client would like to set itself to
 | 
			
		||||
	 * fullscreen. */
 | 
			
		||||
	struct wb_toplevel *toplevel =
 | 
			
		||||
		wl_container_of(listener, toplevel, request_fullscreen);
 | 
			
		||||
	bool is_fullscreen = toplevel->xdg_toplevel->current.fullscreen;
 | 
			
		||||
	if (!is_fullscreen) {
 | 
			
		||||
		struct wlr_output *wlr_output = get_active_output(toplevel);
 | 
			
		||||
		struct wb_output *output = wlr_output->data;
 | 
			
		||||
		toplevel->previous_geometry = toplevel->geometry;
 | 
			
		||||
		toplevel->geometry.x = 0;
 | 
			
		||||
		toplevel->geometry.y = 0;
 | 
			
		||||
		toplevel->geometry.height = output->geometry.height;
 | 
			
		||||
		toplevel->geometry.width = output->geometry.width;
 | 
			
		||||
		wlr_scene_node_raise_to_top(&toplevel->scene_tree->node);
 | 
			
		||||
	} else {
 | 
			
		||||
		toplevel->geometry = toplevel->previous_geometry;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, toplevel->geometry.width, toplevel->geometry.height);
 | 
			
		||||
	wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, !is_fullscreen);
 | 
			
		||||
	wlr_scene_node_set_position(&toplevel->scene_tree->node, toplevel->geometry.x, toplevel->geometry.y);
 | 
			
		||||
static void xdg_surface_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* Called when the surface is destroyed and should never be shown again. */
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, destroy);
 | 
			
		||||
	if (view->xdg_toplevel->base->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
		wl_list_remove(&view->link);
 | 
			
		||||
	free(view);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* This event is raised when a client would like to maximize itself,
 | 
			
		||||
	 * typically because the user clicked on the maximize button on
 | 
			
		||||
	 * client-side decorations.
 | 
			
		||||
	 */
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize);
 | 
			
		||||
	struct wlr_box usable_area = get_usable_area(toplevel);
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, request_maximize);
 | 
			
		||||
	struct wlr_box usable_area = get_usable_area(view);
 | 
			
		||||
 | 
			
		||||
	bool is_maximized = toplevel->xdg_toplevel->current.maximized;
 | 
			
		||||
	bool is_maximized = view->xdg_toplevel->current.maximized;
 | 
			
		||||
	if (!is_maximized) {
 | 
			
		||||
		struct wb_config *config = toplevel->server->config;
 | 
			
		||||
		toplevel->previous_geometry = toplevel->geometry;
 | 
			
		||||
		struct wb_config *config = view->server->config;
 | 
			
		||||
		view->previous_position = view->current_position;
 | 
			
		||||
		if (config) {
 | 
			
		||||
			toplevel->geometry.x = config->margins.left;
 | 
			
		||||
			toplevel->geometry.y = config->margins.top;
 | 
			
		||||
			view->current_position.x = config->margins.left;
 | 
			
		||||
			view->current_position.y = config->margins.top + view->decoration_height;
 | 
			
		||||
			usable_area.height -= config->margins.top + config->margins.bottom;
 | 
			
		||||
			usable_area.width -= config->margins.left + config->margins.right;
 | 
			
		||||
		} else {
 | 
			
		||||
			toplevel->geometry.x = 0;
 | 
			
		||||
			toplevel->geometry.y = 0;
 | 
			
		||||
			view->current_position.x = 0;
 | 
			
		||||
			view->current_position.y = view->decoration_height;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		usable_area = toplevel->previous_geometry;
 | 
			
		||||
		toplevel->geometry.x = toplevel->previous_geometry.x;
 | 
			
		||||
		toplevel->geometry.y = toplevel->previous_geometry.y;
 | 
			
		||||
		usable_area = view->previous_position;
 | 
			
		||||
		view->current_position.x = view->previous_position.x;
 | 
			
		||||
		view->current_position.y = view->previous_position.y;
 | 
			
		||||
	}
 | 
			
		||||
	wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, usable_area.width, usable_area.height);
 | 
			
		||||
	wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, !is_maximized);
 | 
			
		||||
	wlr_scene_node_set_position(&toplevel->scene_tree->node,
 | 
			
		||||
			toplevel->geometry.x, toplevel->geometry.y);
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable_area.width, usable_area.height);
 | 
			
		||||
	wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, !is_maximized);
 | 
			
		||||
#else
 | 
			
		||||
	wlr_xdg_toplevel_set_size(view->xdg_surface, usable_area.width, usable_area.height);
 | 
			
		||||
	wlr_xdg_toplevel_set_maximized(view->xdg_surface, !is_maximized);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_minimize);
 | 
			
		||||
	bool minimize_requested = toplevel->xdg_toplevel->requested.minimized;
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, request_minimize);
 | 
			
		||||
	bool minimize_requested = view->xdg_toplevel->requested.minimized;
 | 
			
		||||
	if (minimize_requested) {
 | 
			
		||||
		toplevel->previous_geometry = toplevel->geometry;
 | 
			
		||||
		toplevel->geometry.y = -toplevel->geometry.height;
 | 
			
		||||
 | 
			
		||||
		struct wb_toplevel *next_toplevel = wl_container_of(toplevel->link.next, next_toplevel, link);
 | 
			
		||||
		if (wl_list_length(&toplevel->link) > 1)
 | 
			
		||||
			focus_toplevel(next_toplevel);
 | 
			
		||||
		else
 | 
			
		||||
			focus_toplevel(toplevel);
 | 
			
		||||
		view->previous_position.height = view->current_position.height;
 | 
			
		||||
		view->current_position.y = 0 -
 | 
			
		||||
			view->decoration_height * 2 - view->current_position.height;
 | 
			
		||||
	} else {
 | 
			
		||||
		toplevel->geometry = toplevel->previous_geometry;
 | 
			
		||||
		view->current_position = view->previous_position;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_scene_node_set_position(&toplevel->scene_tree->node,
 | 
			
		||||
			toplevel->geometry.x, toplevel->geometry.y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void begin_interactive(struct wb_toplevel *toplevel,
 | 
			
		||||
static void begin_interactive(struct wb_view *view,
 | 
			
		||||
		enum wb_cursor_mode mode, uint32_t edges) {
 | 
			
		||||
	/* This function sets up an interactive move or resize operation, where the
 | 
			
		||||
	 * compositor stops propagating pointer events to clients and instead
 | 
			
		||||
	 * consumes them itself, to move or resize windows. */
 | 
			
		||||
	struct wb_server *server = toplevel->server;
 | 
			
		||||
	server->grabbed_toplevel = toplevel;
 | 
			
		||||
	struct wb_server *server = view->server;
 | 
			
		||||
	struct wlr_surface *focused_surface =
 | 
			
		||||
		server->seat->seat->pointer_state.focused_surface;
 | 
			
		||||
	if (view->xdg_toplevel->base->surface != wlr_surface_get_root_surface(focused_surface)) {
 | 
			
		||||
		/* Deny move/resize requests from unfocused clients. */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	server->grabbed_view = view;
 | 
			
		||||
	server->cursor->cursor_mode = mode;
 | 
			
		||||
 | 
			
		||||
	if (mode == WB_CURSOR_MOVE) {
 | 
			
		||||
		server->grab_x = server->cursor->cursor->x - toplevel->geometry.x;
 | 
			
		||||
		server->grab_y = server->cursor->cursor->y - toplevel->geometry.y;
 | 
			
		||||
		server->grab_x = server->cursor->cursor->x - view->current_position.x;
 | 
			
		||||
		server->grab_y = server->cursor->cursor->y - view->current_position.y;
 | 
			
		||||
	} else if (mode == WB_CURSOR_RESIZE) {
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 19, 0)
 | 
			
		||||
		struct wlr_box geo_box = toplevel->xdg_toplevel->base->geometry;
 | 
			
		||||
#else
 | 
			
		||||
		struct wlr_box geo_box;
 | 
			
		||||
		wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box);
 | 
			
		||||
#endif
 | 
			
		||||
		wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
 | 
			
		||||
 | 
			
		||||
		double border_x = (toplevel->geometry.x + geo_box.x) +
 | 
			
		||||
			((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
 | 
			
		||||
		double border_y = (toplevel->geometry.y + geo_box.y) +
 | 
			
		||||
			((edges & WLR_EDGE_BOTTOM) ? geo_box.height : 0);
 | 
			
		||||
		double border_x = (view->current_position.x + geo_box.x) + ((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
 | 
			
		||||
		double border_y = (view->current_position.y + geo_box.y) + ((edges & WLR_EDGE_BOTTOM) ? geo_box.height : 0);
 | 
			
		||||
		server->grab_x = server->cursor->cursor->x - border_x;
 | 
			
		||||
		server->grab_y = server->cursor->cursor->y - border_y;
 | 
			
		||||
 | 
			
		||||
		server->grab_geo_box = geo_box;
 | 
			
		||||
		server->grab_geo_box.x += toplevel->geometry.x;
 | 
			
		||||
		server->grab_geo_box.y += toplevel->geometry.y;
 | 
			
		||||
		server->grab_geo_box.x += view->current_position.x;
 | 
			
		||||
		server->grab_geo_box.y += view->current_position.y;
 | 
			
		||||
 | 
			
		||||
		server->resize_edges = edges;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -340,8 +233,8 @@ static void xdg_toplevel_request_move(
 | 
			
		|||
	/* This event is raised when a client would like to begin an interactive
 | 
			
		||||
	 * move, typically because the user clicked on their client-side
 | 
			
		||||
	 * decorations. */
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_move);
 | 
			
		||||
	begin_interactive(toplevel, WB_CURSOR_MOVE, 0);
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, request_move);
 | 
			
		||||
	begin_interactive(view, WB_CURSOR_MOVE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_toplevel_request_resize(
 | 
			
		||||
| 
						 | 
				
			
			@ -350,135 +243,128 @@ static void xdg_toplevel_request_resize(
 | 
			
		|||
	 * resize, typically because the user clicked on their client-side
 | 
			
		||||
	 * decorations. */
 | 
			
		||||
	struct wlr_xdg_toplevel_resize_event *event = data;
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_resize);
 | 
			
		||||
	begin_interactive(toplevel, WB_CURSOR_RESIZE, event->edges);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_popup_commit(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_popup *popup = wl_container_of(listener, popup, commit);
 | 
			
		||||
	if (!popup->xdg_popup) return;
 | 
			
		||||
	struct wlr_xdg_surface *base = popup->xdg_popup->base;
 | 
			
		||||
 | 
			
		||||
	if (base && base->initial_commit) {
 | 
			
		||||
		update_fractional_scale(base->surface);
 | 
			
		||||
		wlr_xdg_surface_schedule_configure(base);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void xdg_popup_destroy(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wb_popup *popup = wl_container_of(listener, popup, destroy);
 | 
			
		||||
	if (popup->xdg_popup)
 | 
			
		||||
		update_fractional_scale(popup->xdg_popup->base->surface);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&popup->commit.link);
 | 
			
		||||
	wl_list_remove(&popup->destroy.link);
 | 
			
		||||
	free(popup);
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, request_resize);
 | 
			
		||||
	begin_interactive(view, WB_CURSOR_RESIZE, event->edges);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_new_popup(struct wl_listener *listener, void *data) {
 | 
			
		||||
	struct wlr_xdg_popup *popup = data;
 | 
			
		||||
	struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, new_popup);
 | 
			
		||||
	struct wb_view *view = wl_container_of(listener, view, new_popup);
 | 
			
		||||
	struct wlr_output_layout *output_layout = view->server->output_layout;
 | 
			
		||||
 | 
			
		||||
	struct wlr_output *wlr_output = wlr_output_layout_output_at(
 | 
			
		||||
			toplevel->server->output_layout,
 | 
			
		||||
			toplevel->geometry.x + popup->current.geometry.x,
 | 
			
		||||
			toplevel->geometry.y + popup->current.geometry.y);
 | 
			
		||||
 | 
			
		||||
	if (!wlr_output) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct wb_output *output = wlr_output->data;
 | 
			
		||||
 | 
			
		||||
	int top_margin = (toplevel->server->config) ?
 | 
			
		||||
		toplevel->server->config->margins.top : 0;
 | 
			
		||||
	struct wlr_output *wlr_output = wlr_output_layout_output_at(output_layout,
 | 
			
		||||
			view->current_position.x + popup->geometry.x,
 | 
			
		||||
			view->current_position.y + popup->geometry.y);
 | 
			
		||||
	struct wlr_box output_box;
 | 
			
		||||
#if WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	wlr_output_layout_get_box(output_layout, wlr_output, &output_box);
 | 
			
		||||
#else
 | 
			
		||||
	output_box = (*wlr_output_layout_get_box(output_layout, wlr_output));
 | 
			
		||||
#endif
 | 
			
		||||
	struct wlr_box output_toplevel_box = {
 | 
			
		||||
		.x = output->geometry.x - toplevel->geometry.x,
 | 
			
		||||
		.y = output->geometry.y - toplevel->geometry.y,
 | 
			
		||||
		.width = output->geometry.width,
 | 
			
		||||
		.height = output->geometry.height - top_margin,
 | 
			
		||||
		.x = output_box.x - view->current_position.x,
 | 
			
		||||
		.y = output_box.y - view->current_position.y,
 | 
			
		||||
		.width = output_box.width,
 | 
			
		||||
		.height = output_box.height,
 | 
			
		||||
	};
 | 
			
		||||
	wlr_xdg_popup_unconstrain_from_box(popup, &output_toplevel_box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_new_xdg_popup(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* We must add xdg popups to the scene graph so they get rendered. The
 | 
			
		||||
	 * wlroots scene graph provides a helper for this, but to use it we must
 | 
			
		||||
	 * provide the proper parent scene node of the xdg popup. To enable this,
 | 
			
		||||
	 * we always set the user data field of xdg_surfaces to the corresponding
 | 
			
		||||
	 * scene node. */
 | 
			
		||||
	struct wlr_xdg_popup *xdg_popup = data;
 | 
			
		||||
	if (xdg_popup->parent) {
 | 
			
		||||
		struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(
 | 
			
		||||
			xdg_popup->parent);
 | 
			
		||||
		if (parent != NULL) {
 | 
			
		||||
			struct wlr_scene_tree *parent_tree = parent->data;
 | 
			
		||||
			xdg_popup->base->data = wlr_scene_xdg_surface_create(
 | 
			
		||||
				parent_tree, xdg_popup->base);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wb_popup *popup = calloc(1, sizeof(struct wb_popup));
 | 
			
		||||
	popup->commit.notify = xdg_popup_commit;
 | 
			
		||||
	wl_signal_add(&xdg_popup->base->surface->events.commit, &popup->commit);
 | 
			
		||||
 | 
			
		||||
	popup->destroy.notify = xdg_popup_destroy;
 | 
			
		||||
	wl_signal_add(&xdg_popup->events.destroy, &popup->destroy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_new_xdg_toplevel(struct wl_listener *listener, void *data) {
 | 
			
		||||
static void handle_new_xdg_surface(struct wl_listener *listener, void *data) {
 | 
			
		||||
	/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
 | 
			
		||||
	 * client, either a toplevel (application window) or popup. */
 | 
			
		||||
	struct wb_server *server =
 | 
			
		||||
		wl_container_of(listener, server, new_xdg_toplevel);
 | 
			
		||||
	struct wlr_xdg_toplevel *xdg_toplevel = data;
 | 
			
		||||
		wl_container_of(listener, server, new_xdg_surface);
 | 
			
		||||
	struct wlr_xdg_surface *xdg_surface = data;
 | 
			
		||||
	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Allocate a wb_toplevel for this toplevel */
 | 
			
		||||
	struct wb_toplevel *toplevel =
 | 
			
		||||
		calloc(1, sizeof(struct wb_toplevel));
 | 
			
		||||
	toplevel->server = server;
 | 
			
		||||
	toplevel->xdg_toplevel = xdg_toplevel;
 | 
			
		||||
 | 
			
		||||
	toplevel->foreign_toplevel_handle = wlr_ext_foreign_toplevel_handle_v1_create(
 | 
			
		||||
			server->foreign_toplevel_list, &toplevel->foreign_toplevel_state);
 | 
			
		||||
	/* Allocate a wb_view for this surface */
 | 
			
		||||
	struct wb_view *view =
 | 
			
		||||
		calloc(1, sizeof(struct wb_view));
 | 
			
		||||
	view->server = server;
 | 
			
		||||
	view->xdg_toplevel = xdg_surface->toplevel;
 | 
			
		||||
#if !WLR_CHECK_VERSION(0, 16, 0)
 | 
			
		||||
	view->xdg_surface = xdg_surface;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Listen to the various events it can emit */
 | 
			
		||||
	toplevel->map.notify = xdg_toplevel_map;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel->map);
 | 
			
		||||
	toplevel->unmap.notify = xdg_toplevel_unmap;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->base->surface->events.unmap, &toplevel->unmap);
 | 
			
		||||
	toplevel->commit.notify = xdg_toplevel_commit;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->base->surface->events.commit, &toplevel->commit);
 | 
			
		||||
	toplevel->destroy.notify = xdg_toplevel_destroy;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.destroy, &toplevel->destroy);
 | 
			
		||||
	toplevel->new_popup.notify = handle_new_popup;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->base->events.new_popup, &toplevel->new_popup);
 | 
			
		||||
	view->surface_commit.notify = xdg_surface_commit;
 | 
			
		||||
	wl_signal_add(&xdg_surface->surface->events.commit, &view->surface_commit);
 | 
			
		||||
 | 
			
		||||
	toplevel->scene_tree = wlr_scene_xdg_surface_create(
 | 
			
		||||
		&toplevel->server->scene->tree, xdg_toplevel->base);
 | 
			
		||||
	toplevel->scene_tree->node.data = toplevel;
 | 
			
		||||
	xdg_toplevel->base->data = toplevel->scene_tree;
 | 
			
		||||
	view->map.notify = xdg_surface_map;
 | 
			
		||||
	wl_signal_add(&xdg_surface->events.map, &view->map);
 | 
			
		||||
	view->unmap.notify = xdg_surface_unmap;
 | 
			
		||||
	wl_signal_add(&xdg_surface->events.unmap, &view->unmap);
 | 
			
		||||
	view->destroy.notify = xdg_surface_destroy;
 | 
			
		||||
	wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
 | 
			
		||||
	view->new_popup.notify = handle_new_popup;
 | 
			
		||||
	wl_signal_add(&xdg_surface->events.new_popup, &view->new_popup);
 | 
			
		||||
 | 
			
		||||
	toplevel->request_fullscreen.notify = xdg_toplevel_request_fullscreen;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.request_fullscreen, &toplevel->request_fullscreen);
 | 
			
		||||
	toplevel->request_maximize.notify = xdg_toplevel_request_maximize;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.request_maximize, &toplevel->request_maximize);
 | 
			
		||||
	toplevel->request_minimize.notify = xdg_toplevel_request_minimize;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.request_minimize, &toplevel->request_minimize);
 | 
			
		||||
	toplevel->request_move.notify = xdg_toplevel_request_move;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.request_move, &toplevel->request_move);
 | 
			
		||||
	toplevel->request_resize.notify = xdg_toplevel_request_resize;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.request_resize, &toplevel->request_resize);
 | 
			
		||||
	toplevel->set_app_id.notify = xdg_toplevel_set_app_id;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.set_app_id, &toplevel->set_app_id);
 | 
			
		||||
	toplevel->set_title.notify = xdg_toplevel_set_title;
 | 
			
		||||
	wl_signal_add(&xdg_toplevel->events.set_title, &toplevel->set_title);
 | 
			
		||||
	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
 | 
			
		||||
		struct wlr_xdg_toplevel *toplevel = view->xdg_toplevel;
 | 
			
		||||
		view->request_maximize.notify = xdg_toplevel_request_maximize;
 | 
			
		||||
		wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize);
 | 
			
		||||
		view->request_minimize.notify = xdg_toplevel_request_minimize;
 | 
			
		||||
		wl_signal_add(&toplevel->events.request_minimize, &view->request_minimize);
 | 
			
		||||
		view->request_move.notify = xdg_toplevel_request_move;
 | 
			
		||||
		wl_signal_add(&toplevel->events.request_move, &view->request_move);
 | 
			
		||||
		view->request_resize.notify = xdg_toplevel_request_resize;
 | 
			
		||||
		wl_signal_add(&toplevel->events.request_resize, &view->request_resize);
 | 
			
		||||
 | 
			
		||||
	wl_list_insert(&toplevel->server->toplevels, &toplevel->link);
 | 
			
		||||
		/* Add it to the list of views. */
 | 
			
		||||
		wl_list_insert(&server->views, &view->link);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool view_at(struct wb_view *view,
 | 
			
		||||
		double lx, double ly, struct wlr_surface **surface,
 | 
			
		||||
		double *sx, double *sy) {
 | 
			
		||||
	/*
 | 
			
		||||
	 * XDG toplevels may have nested surfaces, such as popup windows for context
 | 
			
		||||
	 * menus or tooltips. This function tests if any of those are underneath the
 | 
			
		||||
	 * coordinates lx and ly (in output Layout Coordinates). If so, it sets the
 | 
			
		||||
	 * surface pointer to that wlr_surface and the sx and sy coordinates to the
 | 
			
		||||
	 * coordinates relative to that surface's top-left corner.
 | 
			
		||||
	 */
 | 
			
		||||
	if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	double view_sx = lx - view->current_position.x;
 | 
			
		||||
	double view_sy = ly - view->current_position.y;
 | 
			
		||||
 | 
			
		||||
	double _sx, _sy;
 | 
			
		||||
	struct wlr_surface *_surface = NULL;
 | 
			
		||||
	_surface = wlr_xdg_surface_surface_at(
 | 
			
		||||
			view->xdg_toplevel->base, view_sx, view_sy, &_sx, &_sy);
 | 
			
		||||
 | 
			
		||||
	if (_surface != NULL) {
 | 
			
		||||
		*sx = _sx;
 | 
			
		||||
		*sy = _sy;
 | 
			
		||||
		*surface = _surface;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct wb_view *desktop_view_at(
 | 
			
		||||
		struct wb_server *server, double lx, double ly,
 | 
			
		||||
		struct wlr_surface **surface, double *sx, double *sy) {
 | 
			
		||||
	/* This iterates over all of our surfaces and attempts to find one under the
 | 
			
		||||
	 * cursor. This relies on server->views being ordered from top-to-bottom. */
 | 
			
		||||
	struct wb_view *view;
 | 
			
		||||
	wl_list_for_each(view, &server->views, link) {
 | 
			
		||||
		if (view_at(view, lx, ly, surface, sx, sy)) {
 | 
			
		||||
			return view;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_xdg_shell(struct wb_server *server) {
 | 
			
		||||
	/* xdg-shell version 3 */
 | 
			
		||||
	server->xdg_shell = wlr_xdg_shell_create(server->wl_display, 3);
 | 
			
		||||
	server->new_xdg_popup.notify = handle_new_xdg_popup;
 | 
			
		||||
	wl_signal_add(&server->xdg_shell->events.new_popup, &server->new_xdg_popup);
 | 
			
		||||
	server->new_xdg_toplevel.notify = handle_new_xdg_toplevel;
 | 
			
		||||
	wl_signal_add(&server->xdg_shell->events.new_toplevel, &server->new_xdg_toplevel);
 | 
			
		||||
	server->xdg_shell = wlr_xdg_shell_create(server->wl_display);
 | 
			
		||||
	server->new_xdg_surface.notify = handle_new_xdg_surface;
 | 
			
		||||
	wl_signal_add(&server->xdg_shell->events.new_surface, &server->new_xdg_surface);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue