Compare commits

..

No commits in common. "master" and "0.2.0" have entirely different histories.

82 changed files with 1470 additions and 2167 deletions

View file

@ -3,27 +3,20 @@
# #
image: archlinux image: archlinux
packages: packages:
- clang
- gcc
- libevdev
- libinput
- libxkbcommon
- libxml2
- meson - meson
- wayland - wayland
- wayland-protocols - wayland-protocols
- wlroots-git - libinput
- libxkbcommon
- libxml2
- wlroots
- xorg-server-xwayland - xorg-server-xwayland
sources: sources:
- https://github.com/wizbright/waybox - https://github.com/wizbright/waybox
tasks: tasks:
- setup: | - setup: |
cd waybox cd waybox
CC=gcc meson setup build-gcc meson build
- build: | - build: |
cd waybox cd waybox
ninja -C build-gcc ninja -C build
- clang: |
cd waybox
CC=clang meson setup build-clang
ninja -C build-clang

View file

@ -14,7 +14,7 @@ block_comment_start = /*
block_comment_end = */ block_comment_end = */
curly_bracket_next_line = false curly_bracket_next_line = false
max_line_length = 100 max_line_length = 80
spaces_around_brackets = outside spaces_around_brackets = outside
spaces_around_operators = true spaces_around_operators = true

View file

@ -12,18 +12,18 @@ on: [push, pull_request]
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: alpine:edge container: archlinux:base-devel
steps: steps:
- name: packages - name: packages
run: | run: |
apk add clang gcc libevdev-dev libinput-dev libxkbcommon-dev libxml2-dev meson musl-dev wayland-dev wayland-protocols wlroots wlroots-dev xwayland pacman-key --init
# actions/checkout@v4 clones the repository pacman -Syu --noconfirm
- uses: actions/checkout@v4 pacman -S --noconfirm git meson libxkbcommon libinput libxml2 wayland wayland-protocols wlroots xorg-server-xwayland
- name: build-gcc # actions/checkout@v2 clones the repository
- uses: actions/checkout@v2
- name: setup
run: | run: |
CC=gcc meson setup build-gcc meson build
ninja -C build-gcc - name: build
- name: build-clang
run: | run: |
CC=clang meson setup build-clang ninja -C build
ninja -C build-clang

View file

@ -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 don't, however, allow me to make a suggestion: feature branches pulled from
upstream. Try this: upstream. Try this:
1. Fork Waybox 1. Fork waybox
2. `git clone https://github.com/username/waybox && cd waybox` 2. `git clone https://github.com/username/waybox && cd waybox`
3. `git remote add upstream https://github.com/wizbright/waybox` 3. `git remote add upstream https://github.com/wizbright/waybox`
@ -87,7 +87,7 @@ process is:
## Style Reference ## 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 style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but
with a few notable differences. 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 ### 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 improves readability. Don't break lines indiscriminately, try to find nice
breaking points so your code is easy to read. breaking points so your code is easy to read.

View file

@ -1,10 +1,8 @@
# Waybox # Waybox
An Openbox clone on Wayland (WIP)
A \*box-style (minimalist) Wayland compositor modeled largely on Openbox (WIP)
### Goals ### Goals
The main goal of this project is to provide a similar feel to Openbox but on Wayland
The main goal of this project is to provide a similar feel to \*box-style window managers but on Wayland
### Contributing ### Contributing
@ -13,47 +11,22 @@ contributing.](https://github.com/wizbright/waybox/blob/master/CONTRIBUTING.md)
### Dependencies ### Dependencies
* [Meson](https://mesonbuild.com/) or [muon](http://muon.build) * [Meson](https://mesonbuild.com/)
* [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/)
* [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots/) * [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots/)
* [libxml2](http://xmlsoft.org/)
* [Wayland](https://wayland.freedesktop.org/)
* [xkbcommon](https://xkbcommon.org/) * [xkbcommon](https://xkbcommon.org/)
### Build instructions ### Build instructions
``` ```
meson setup build meson build
cd build cd build
ninja ninja
``` ```
After that, you should have an executable as waybox/waybox 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
![Plain desktop with wallpaper, panel, and dock](../../raw/master/screenshots/emptydesktop.png)
![Showing Firefox and some of the Waybox source code](../../raw/master/screenshots/work.png)
![All work and no play](../../raw/master/screenshots/play.png)
### 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 ### Contact
I can be found as wiz on Rizon and wizbright on Libera. I can be found as wiz on Rizon and WizBright on Freenode.
Join [#waybox](https://libera.chat/guides/connect) for discussion Join [#waybox](http://webchat.freenode.net/?channels=waybox) for discussion

View file

@ -23,48 +23,15 @@ cairo-dock &
mako & mako &
# Load a random wallpaper # Load a random wallpaper
get_random_wallpaper()
{
oldifs=$IFS oldifs=$IFS
IFS=: IFS=:
data_dirs=${XDG_DATA_DIRS:-${datadir:-/usr/share}}:${XDG_DATA_HOME:-~/.local/share} data_dirs=${XDG_DATA_DIRS:-${datadir:-/usr/share}}:${XDG_DATA_HOME:-~/.local/share}
for data_dir in $data_dirs;do for data_dir in $data_dirs;
IFS=$oldifs do
wpdir="$data_dir/wallpapers" wpdir="$data_dir/wallpapers"
test -d "$wpdir" && \ test -d "$wpdir" && \
find $wpdir -name '*.jpg' -o -name '*.png' -o -name '*.svg' find $wpdir -name '*.jpg' -o -name '*.png' -o -name '*.svg'
done | (shuf -n 1 || tail -n 1) done | (shuf -n 1 || tail -n 1) | xargs swaybg -m fill -i &
} IFS=$oldifs
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 &
# vim: ft=sh # vim: ft=sh

View file

@ -21,7 +21,7 @@
#export ECORE_IMF_MODULE=uim #export ECORE_IMF_MODULE=uim
# Current compositor. Needed for Wayland security negotiation. # Current compositor. Needed for Wayland security negotiation.
export XDG_CURRENT_DESKTOP=Waybox export XDG_CURRENT_DESKTOP=waybox
export XDG_SESSION_TYPE=wayland export XDG_SESSION_TYPE=wayland
# Make sure to run the X initialization if started through a display manager # 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 then
for f in /etc/X11/xinit/xinitrc.d/*.sh; for f in /etc/X11/xinit/xinitrc.d/*.sh;
do do
test -r "$f" && . "$f" test -f "$f" && . "$f"
done done
fi fi
# Emerging standard, used by i.a. modern GTK versions instead of the obsolete # Get the preferred terminal from GNOME (if you use mostly GTK apps)
# org.gnome.default-applications.terminal.exec gsetting (which is now ignored) TERMINAL=$(gsettings get org.gnome.desktop.default-applications.terminal exec | tr -d \')
# 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 KDE (if you use mostly Qt apps) # Get the preferred terminal from KDE (if you use mostly Qt apps)
#TERMINAL=$(kreadconfig5 --file kdeglobals --group General --key TerminalApplication --default "konsole") #TERMINAL=$(kreadconfig5 --file kdeglobals --group General --key TerminalApplication --default "konsole")
# Or just set it hard: # Or just set it hard:
#TERMINAL=kitty #TERMINAL=kitty
export TERMINAL export TERMINAL
if command -v xdg-autostart >/dev/null 2>&1;
then
export XDG_CURRENT_DESTKOP=OPENBOX
else
# Use autostart scripts for these environments # Use autostart scripts for these environments
export WB_AUTOSTART_ENVIRONMENT=GNOME:KDE:OPENBOX export WB_AUTOSTART_ENVIRONMENT=GNOME:KDE
fi

View file

@ -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)

View file

@ -1,5 +1,4 @@
cfdata = configuration_data() cfdata = configuration_data()
cfdata.set('bindir', get_option('prefix') / get_option('bindir'))
cfdata.set('libexecdir', get_option('prefix') / get_option('libexecdir')) cfdata.set('libexecdir', get_option('prefix') / get_option('libexecdir'))
cfdata.set('localedir', get_option('prefix') / get_option('localedir')) cfdata.set('localedir', get_option('prefix') / get_option('localedir'))
cfdata.set('sysconfdir', get_option('prefix') / get_option('sysconfdir')) cfdata.set('sysconfdir', get_option('prefix') / get_option('sysconfdir'))
@ -34,21 +33,8 @@ install_data(
install_mode: 'rw-r--r--', 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( install_data(
'waybox.desktop', 'waybox.desktop',
install_dir: get_option('prefix') / get_option('datadir') + '/wayland-sessions', install_dir: get_option('prefix') / get_option('datadir') + '/wayland-sessions',
install_mode: 'rw-r--r--', install_mode: 'rw-r--r--',
) )
install_data(
'menu',
install_dir: get_option('prefix') / get_option('bindir'),
install_mode: 'rwxr-xr-x',
rename: ['waybox-menu']
)

View file

@ -9,15 +9,15 @@
<right>0</right> <right>0</right>
</margins> </margins>
<keyboard> <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 --> <!-- You can use the XKB_* environment variables instead -->
<!-- <xkb> <!-- <keyboardLayout>
<model>105</model> <model>105</model>
<layout>us</layout> <layout>us</layout>
<options>ctrl:swapcaps,esperanto:dvorak,lv3:ralt_switch_multikey</options> <options>ctrl:swapcaps,esperanto:dvorak,lv3:ralt_switch_multikey</options>
<rules>evdev</rules> <rules>evdev</rules>
<variant>dvorak</variant> <variant>dvorak</variant>
</xkb> --> </keyboardLayout> -->
<!-- Keybindings for windows --> <!-- Keybindings for windows -->
<keybind key="A-F4"> <keybind key="A-F4">
<action name="Close"/> <action name="Close"/>
@ -42,16 +42,16 @@
</keybind> </keybind>
<!-- Keybindings for window switching --> <!-- Keybindings for window switching -->
<keybind key="A-Tab"> <keybind key="A-Tab">
<action name="NextWindow"/> <action name="NextWindow">
<action name="Unshade"/> </action>
</keybind> </keybind>
<keybind key="A-S-ISO_Left_Tab"> <keybind key="A-S-ISO_Left_Tab">
<action name="PreviousWindow"/> <action name="PreviousWindow">
<action name="Unshade"/> </action>
</keybind> </keybind>
<keybind key="C-A-Tab"> <keybind key="C-A-Tab">
<action name="NextWindow"/> <action name="NextWindow">
<action name="Unshade"/> </action>
</keybind> </keybind>
<!-- Keybindings for running applications --> <!-- Keybindings for running applications -->
<keybind key="W-Return"> <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> <execute>grim "$(xdg-user-dir PICTURES)/$(date +'%Y-%m-%d-%H%M%S_grim_fs.png')"</execute>
</action> </action>
</keybind> </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"> <keybind key="A-F2">
<action name="Execute"> <action name="Execute">
<execute>obrun l</execute> <execute>obrun l</execute>
@ -112,26 +101,4 @@
</action> </action>
</keybind> </keybind>
</keyboard> </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> </openbox_config>

View file

@ -4,5 +4,4 @@ Comment=An Openbox-like compositor for Wayland
Comment[de]=Ein Wayland-Compositor ähnlich zu Openbox Comment[de]=Ein Wayland-Compositor ähnlich zu Openbox
Comment[eo]=Komponilo de Wayland, kiu similas je Openbox Comment[eo]=Komponilo de Wayland, kiu similas je Openbox
Exec=waybox Exec=waybox
Icon=waybox
Type=Application Type=Application

View file

@ -60,12 +60,7 @@ then
fi fi
# And the XDG autostart script # And the XDG autostart script
if command -v xdg-autostart >/dev/null 2>&1; if test -x $WB_USER_CONF_DIR/xdg-autostart;
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;
then then
WB_XDG_AUTOSTART=$WB_USER_CONF_DIR/xdg-autostart; WB_XDG_AUTOSTART=$WB_USER_CONF_DIR/xdg-autostart;
elif test -x $WB_SYS_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"; WB_XDG_AUTOSTART="@libexecdir@/openbox-autostart OPENBOX";
fi 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; if test -f $WB_USER_CONF_DIR/rc.xml;
then then
WB_RC_XML=$WB_USER_CONF_DIR/rc.xml 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; if which dbus-launch >/dev/null 2>&1;
then then
DBUS_LAUNCH="dbus-launch --exit-with-session" DBUS_LANCH="dbus-launch --exit-with-session"
fi fi
export PATH=@bindir@:$PATH
# No need to export these to Waybox # No need to export these to Waybox
unset TEXTDOMAIN TEXTDOMAINDIR unset TEXTDOMAIN TEXTDOMAINDIR
$DBUS_LAUNCH @libexecdir@/waybox --startup "${WB_AUTOSTART:-true}; ${WB_XDG_AUTOSTART:-true}" "$@" $DBUS_LAUNCH @libexecdir@/waybox --startup "${WB_AUTOSTART:-true}; ${WB_XDG_AUTOSTART:-true}" "$@"

View file

@ -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

View file

@ -66,8 +66,6 @@ do
then then
show_in=0 show_in=0
break 2 break 2
else
show_in=1
fi fi
done done
done done
@ -90,7 +88,7 @@ do
then then
# Don't run the Exec key if a non-empty TryExec command can't be found # 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'); 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 then
continue continue
fi fi

View file

@ -30,6 +30,5 @@ struct wb_cursor {
struct wb_cursor *wb_cursor_create(struct wb_server *server); struct wb_cursor *wb_cursor_create(struct wb_server *server);
void wb_cursor_destroy(struct wb_cursor *cursor); void wb_cursor_destroy(struct wb_cursor *cursor);
void reset_cursor_mode(struct wb_server *server);
#endif /* cursor.h */ #endif /* cursor.h */

View file

@ -1,36 +1,55 @@
#ifndef _WB_OUTPUT_H #ifndef _WB_OUTPUT_H
#define _WB_OUTPUT_H #define _WB_OUTPUT_H
#include <stdlib.h>
#include <time.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 "waybox/server.h"
#include <wlr/types/wlr_output_management_v1.h>
struct wb_output { struct wb_output {
struct wlr_output *wlr_output; struct wlr_output *wlr_output;
struct wb_server *server; struct wb_server *server;
struct { struct wl_list layers[4];
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_listener destroy; struct wl_listener destroy;
struct wl_listener frame; struct wl_listener frame;
struct wl_listener request_state;
struct wl_list link; struct wl_list link;
}; };
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data); 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_frame_notify(struct wl_listener* listener, void *data);
void output_destroy_notify(struct wl_listener* listener, void *data); void output_destroy_notify(struct wl_listener* listener, void *data);
void init_output(struct wb_server *server); void new_output_notify(struct wl_listener* listener, void *data);
#endif /* output.h */ #endif /* output.h */

View file

@ -1,13 +1,16 @@
#ifndef _WB_SEAT_H #ifndef _WB_SEAT_H
#define _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> #include <wlr/types/wlr_seat.h>
struct wb_server;
struct wb_seat { struct wb_seat {
struct wlr_seat *seat; struct wlr_seat *seat;
struct wlr_layer_surface_v1 *focused_layer;
struct wl_list keyboards; struct wl_list keyboards;
struct wl_listener request_set_primary_selection; struct wl_listener request_set_primary_selection;
@ -17,16 +20,13 @@ struct wb_seat {
struct wb_keyboard { struct wb_keyboard {
struct wl_list link; struct wl_list link;
struct wb_server *server; struct wb_server *server;
struct wlr_keyboard *keyboard; struct wlr_input_device *device;
struct wl_listener destroy;
struct wl_listener modifiers; struct wl_listener modifiers;
struct wl_listener key; struct wl_listener key;
}; };
struct wb_server; struct wb_server;
struct wb_seat *wb_seat_create(struct wb_server *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); void wb_seat_destroy(struct wb_seat *seat);
#endif #endif

View file

@ -1,30 +1,30 @@
#ifndef _WB_SERVER_H #ifndef _WB_SERVER_H
#define _WB_SERVER_H #define _WB_SERVER_H
#include <stdio.h>
#define MAX(a, b) ((a > b) ? (a) : (b)) #define MAX(a, b) ((a > b) ? (a) : (b))
#define MIN(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> #include <wlr/version.h>
#define WLR_CHECK_VERSION(major, minor, micro) (WLR_VERSION_NUM >= ((major << 16) | (minor << 8) | (micro))) #define WLR_CHECK_VERSION(major, minor, micro) (WLR_VERSION_NUM >= ((major << 16) | (minor << 8) | (micro)))
#include <wlr/backend.h> #include <wlr/backend.h>
#include <wlr/render/allocator.h> #include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
#include <wlr/render/wlr_texture.h>
#include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h> #include <wlr/types/wlr_idle.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_screencopy_v1.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_subcompositor.h>
#include <wlr/types/wlr_xdg_output_v1.h> #endif
#include <wlr/types/wlr_xdg_shell.h> #include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include <stdlib.h>
#ifdef USE_NLS #ifdef USE_NLS
# include <libintl.h> # include <libintl.h>
# include <locale.h> # include <locale.h>
@ -37,27 +37,21 @@
#include "waybox/cursor.h" #include "waybox/cursor.h"
#include "decoration.h" #include "decoration.h"
#include "layer_shell.h" #include "layer_shell.h"
#include "waybox/xdg_shell.h" #include "waybox/output.h"
#include "waybox/seat.h" #include "waybox/seat.h"
struct wb_server { struct wb_server {
struct wl_display *wl_display; struct wl_display *wl_display;
struct wl_event_loop *wl_event_loop;
struct wlr_allocator *allocator; struct wlr_allocator *allocator;
struct wlr_backend *backend; struct wlr_backend *backend;
struct wlr_compositor *compositor; 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_output_layout *output_layout;
struct wlr_xdg_output_manager_v1 *output_manager; struct wlr_xdg_output_manager_v1 *output_manager;
struct wlr_renderer *renderer; struct wlr_renderer *renderer;
struct wlr_scene *scene; #if WLR_CHECK_VERSION(0, 16, 0)
struct wlr_scene_output_layout *scene_layout;
struct wlr_session *session;
struct wlr_subcompositor *subcompositor; struct wlr_subcompositor *subcompositor;
struct wlr_output_manager_v1 *wlr_output_manager; #endif
struct wb_config *config; struct wb_config *config;
char *config_file; char *config_file;
@ -65,31 +59,21 @@ struct wb_server {
struct wb_cursor *cursor; struct wb_cursor *cursor;
struct wb_seat *seat; struct wb_seat *seat;
struct wb_toplevel *grabbed_toplevel; struct wb_view *grabbed_view;
struct wlr_box grab_geo_box; struct wlr_box grab_geo_box;
double grab_x, grab_y; double grab_x, grab_y;
uint32_t resize_edges; uint32_t resize_edges;
struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list; struct wl_list views;
struct wl_list toplevels;
struct wlr_layer_shell_v1 *layer_shell; struct wlr_layer_shell_v1 *layer_shell;
struct wlr_xdg_shell *xdg_shell; struct wlr_xdg_shell *xdg_shell;
struct wl_listener gamma_control_set_gamma;
struct wl_listener new_layer_surface; struct wl_listener new_layer_surface;
struct wl_listener new_xdg_surface;
struct wl_listener new_xdg_decoration; 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_input;
struct wl_listener new_output; struct wl_listener new_output;
struct wl_listener output_configuration_applied;
struct wl_listener output_configuration_tested;
struct wl_list outputs; /* wb_output::link */ struct wl_list outputs; /* wb_output::link */
}; };

View file

@ -1,49 +1,11 @@
#ifndef _WB_XDG_SHELL_H #ifndef _WB_XDG_SHELL_H
#define _WB_XDG_SHELL_H #define _WB_XDG_SHELL_H
#include <wlr/types/wlr_fractional_scale_v1.h>
#include "waybox/server.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 init_xdg_shell(struct wb_server *server);
void focus_toplevel(struct wb_toplevel *toplevel); void focus_view(struct wb_view *view, struct wlr_surface *surface);
struct wlr_output *get_active_output(struct wb_toplevel *toplevel); struct wb_view *desktop_view_at(
struct wb_toplevel *get_toplevel_at(
struct wb_server *server, double lx, double ly, struct wb_server *server, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy); struct wlr_surface **surface, double *sx, double *sy);
#endif #endif

View file

@ -1,9 +1,9 @@
project( project(
'Waybox', 'Waybox',
'c', 'c',
version: '0.2.3', version: '0.2.0',
license: 'MIT', license: 'MIT',
meson_version: '>=0.60.0', meson_version: '>=0.52.0',
default_options: [ default_options: [
'c_std=c11', 'c_std=c11',
'warning_level=2', 'warning_level=2',
@ -15,7 +15,6 @@ add_project_arguments(
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-D_DEFAULT_SOURCE', '-D_DEFAULT_SOURCE',
'-D_POSIX_C_SOURCE=200112L', '-D_POSIX_C_SOURCE=200112L',
'-DWL_HIDE_DEPRECATED', # Hide the deprecated parts of the Wayland API
'-DWLR_USE_UNSTABLE', '-DWLR_USE_UNSTABLE',
'-DPACKAGE_NAME="' + meson.project_name() + '"', '-DPACKAGE_NAME="' + meson.project_name() + '"',
'-DPACKAGE_VERSION="' + meson.project_version() + '"', '-DPACKAGE_VERSION="' + meson.project_version() + '"',
@ -26,27 +25,16 @@ cc = meson.get_compiler('c')
# Adding include directory # Adding include directory
inc_dir = include_directories('include') 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') 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') 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') xkbcommon = dependency('xkbcommon')
if libinput.found()
add_project_arguments('-DHAS_LIBINPUT', language: 'c')
endif
msgfmt = find_program('msgfmt', required: false) msgfmt = find_program('msgfmt', required: false)
if msgfmt.found() if msgfmt.found()
source_root = meson.current_source_dir() source_root = meson.current_source_dir()
add_project_arguments('-DUSE_NLS=1', language: 'c')
subdir('po') subdir('po')
endif endif

View file

@ -1 +0,0 @@
option('wlroots-version', type: 'string', value: '', description: 'The version of wlroots with which to compile the compositor')

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:03-0400\n"
"Last-Translator: aspersieman <aspersieman@gmail.com>\n" "Last-Translator: aspersieman <aspersieman@gmail.com>\n"
"Language-Team: Afrikaans\n" "Language-Team: Afrikaans\n"
@ -110,6 +110,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -128,12 +134,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -146,6 +146,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:03-0400\n"
"Last-Translator: كريم اولاد الشلحة <herr.linux88@gmail.com>\n" "Last-Translator: كريم اولاد الشلحة <herr.linux88@gmail.com>\n"
"Language-Team: Arabic <herr.linux88@gmail.com>\n" "Language-Team: Arabic <herr.linux88@gmail.com>\n"
@ -110,6 +110,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -128,12 +134,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -146,6 +146,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:03-0400\n"
"Last-Translator: Mikalai Udodau <crom-a@tut.by>\n" "Last-Translator: Mikalai Udodau <crom-a@tut.by>\n"
"Language-Team: Belarusian <i18n@mova.org>\n" "Language-Team: Belarusian <i18n@mova.org>\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:06-0400\n"
"Last-Translator: Runa Bhattacharjee <runabh@gmail.com>\n" "Last-Translator: Runa Bhattacharjee <runabh@gmail.com>\n"
"Language-Team: Bengali (India) <en@li.org>\n" "Language-Team: Bengali (India) <en@li.org>\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:06-0400\n"
"Last-Translator: David Majà Martínez <davidmaja@gmail.com>\n" "Last-Translator: David Majà Martínez <davidmaja@gmail.com>\n"
"Language-Team: catalan\n" "Language-Team: catalan\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:06-0400\n"
"Last-Translator: David Kolibac <david@kolibac.cz>\n" "Last-Translator: David Kolibac <david@kolibac.cz>\n"
"Language-Team: Czech <cs@li.org>\n" "Language-Team: Czech <cs@li.org>\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2022-02-18 17:43-0500\n"
"Last-Translator: Jesper Sander <sander.contrib@gmail.com>\n" "Last-Translator: Jesper Sander <sander.contrib@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

115
po/de.po
View file

@ -11,8 +11,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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: 2024-01-25 21:34-0500\n" "PO-Revision-Date: 2022-02-22 21:21-0500\n"
"Last-Translator: Volker Ribbert <volker.nospam@netcologne.de>\n" "Last-Translator: Volker Ribbert <volker.nospam@netcologne.de>\n"
"Language-Team: <de@li.org>\n" "Language-Team: <de@li.org>\n"
"Language: de\n" "Language: de\n"
@ -22,10 +22,10 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "WARNING: Using files from Openbox. These may not work correctly." 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." msgid "ERROR: No configuration file found."
msgstr "FEHLER: Keine Konfigurationsdatei gefunden." msgstr "FEHLER: Keine Einstellungsdatei gefunden."
msgid "Unable to evaluate expression" msgid "Unable to evaluate expression"
msgstr "Konnte den Ausdruck nicht evaluieren" msgstr "Konnte den Ausdruck nicht evaluieren"
@ -39,18 +39,18 @@ msgstr "Kein nodeset"
msgid "" msgid ""
"Unable to parse the configuration file. Consult stderr for more information." "Unable to parse the configuration file. Consult stderr for more information."
msgstr "" msgstr ""
"Kann die Konfigurationsdatei nicht verarbeiten. Für weitere Informationen siehe " "Kann nicht die Einstullungsdatei analisieren. Für mehr Informationen die "
"die Standardfehlerausgabe." "Standardfehlerausgabe lesen."
msgid "Couldn't create new context!" 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" msgid "Couldn't register the namespace"
msgstr "Konnte den Namensraum nicht registrieren" msgstr "Konte dem Namensnraum nicht registrieren"
#, c-format #, c-format
msgid "Syntax: %s [options]\n" msgid "Syntax: %s [options]\n"
msgstr "Syntax: %s [Optionen]\n" msgstr "Eingabe: %s [Optionen]\n"
#, c-format #, c-format
msgid "" msgid ""
@ -75,7 +75,7 @@ msgstr " --config-file DATEI Pfad zur Konfigurationsdatei\n"
#, c-format #, c-format
msgid " --sm-disable Disable connection to the session manager\n" 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 #, c-format
msgid " --startup CMD Run CMD after starting\n" msgid " --startup CMD Run CMD after starting\n"
@ -83,7 +83,7 @@ msgstr " --startup CMD CMD nach Start ausführen\n"
#, c-format #, c-format
msgid " --debug Display debugging output\n" msgid " --debug Display debugging output\n"
msgstr " --debug Ausgabe von Debug-Informationen\n" msgstr " --debug Fehlersuche-Ergebnis anzeigen\n"
#, c-format #, c-format
msgid "" msgid ""
@ -92,8 +92,8 @@ msgid ""
"on Wayland.\n" "on Wayland.\n"
msgstr "" msgstr ""
"\n" "\n"
"Weitere Openbox-Optionen werden nicht angenommen, da sie überwiegend " "Weitere Openbox-Optionen sind nicht angenommen, meistens wegen sie sind "
"sinnlos unter Wayland sind.\n" "sinnlos auf Wayland.\n"
#, c-format #, c-format
msgid "%s requires an argument\n" msgid "%s requires an argument\n"
@ -101,25 +101,31 @@ msgstr "%s erfordert einen Parameter\n"
#, c-format #, c-format
msgid "%s hasn't been implemented yet.\n" 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" msgid "Successfully created backend"
msgstr "Das Backend wurde erfolgreich erstellt" msgstr "Das Backend wurde erfolgreich hergestellt"
msgid "Failed to create backend" msgid "Failed to create backend"
msgstr "Das Backend wurde nicht erstellt" msgstr "Das Backend wurde nicht erfolgreich hergestellt"
msgid "Successfully started server" msgid "Successfully started server"
msgstr "Der Server wurde erfolgreich gestartet" msgstr "Der Server wurde erfolgreich gestartet"
msgid "Failed to start server" 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" msgid "New output device detected"
msgstr "Neues Ausgabegerät entdeckt" msgstr "Neue Ausgabegerät entdeckt"
msgid "Could not add an output layout." msgid "Couldn't commit pending frame to output"
msgstr "Konnte keine neue Ausgabenanordnung hinzufügen." msgstr "Konnte sich nicht an den anstehenden Rahmen an die Ausgabe eintragen"
msgid "New keyboard detected" msgid "New keyboard detected"
msgstr "Neue Tastatur entdeckt" msgstr "Neue Tastatur entdeckt"
@ -128,25 +134,16 @@ msgid "New pointer detected"
msgstr "Neuer Zeiger entdeckt" msgstr "Neuer Zeiger entdeckt"
msgid "Unsupported input device detected" msgid "Unsupported input device detected"
msgstr "Unbekanntes Eingabegerät entdeckt" msgstr "Unerkanntes Eingabegerät entdeckt"
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "Scheiterte mit Verbindung an ein Wayland-Display" msgstr "Scheiterte an eines Wayland-Displays verbinden"
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"
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "Starten des Backend gescheitert" msgstr "Starten des Backend gescheitert"
msgid "Running Wayland compositor on Wayland display" 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" msgid "Display destroyed"
msgstr "Display zerstört" msgstr "Display zerstört"
@ -154,32 +151,18 @@ msgstr "Display zerstört"
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "Tastaturfokus ist jetzt auf Oberfläche" msgstr "Tastaturfokus ist jetzt auf Oberfläche"
msgid "Focusing next toplevel" msgid "Focusing current view"
msgstr "Fokussiere nächst höhere Ebene" msgstr "Fokussiert jetzige Ansicht"
#~ msgid "Couldn't commit pending frame to output" msgid "Focusing next view"
#~ msgstr "" msgstr "Fokussiert nächste Ansicht"
#~ "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 "Unable to parse XML file" #~ msgid "Unable to parse XML file"
#~ msgstr "Konnte die XML-Datei nicht analysieren" #~ msgstr "Konnte die XML-Datei nicht analisieren"
#, c-format #, c-format
#~ msgid "Invalid action \"%s\" requested. No such action exists." #~ 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" #~ msgid "No"
#~ msgstr "Nein" #~ msgstr "Nein"
@ -262,7 +245,7 @@ msgstr "Fokussiere nächst höhere Ebene"
#~ msgstr "Immer im _Hintergrund" #~ msgstr "Immer im _Hintergrund"
#~ msgid "_Send to desktop" #~ msgid "_Send to desktop"
#~ msgstr "_Sende an Desktop" #~ msgstr "_Verschieben nach"
#~ msgid "Client menu" #~ msgid "Client menu"
#~ msgstr "Anwendungsmenü" #~ msgstr "Anwendungsmenü"
@ -299,8 +282,8 @@ msgstr "Fokussiere nächst höhere Ebene"
#~ "Waybox was compiled without image loading support. Icons in menus will " #~ "Waybox was compiled without image loading support. Icons in menus will "
#~ "not be loaded." #~ "not be loaded."
#~ msgstr "" #~ msgstr ""
#~ "Waybox wurde ohne Unterstützung für Bilder kompiliert. Diese werden in Menüs " #~ "Waybox wurde ohne Bildladungsunterstützung kompiliert. Ikone in Menüs "
#~ "daher nicht geladen." #~ "werden nicht geladen werden."
#~ msgid "Conflict with key binding in config file" #~ msgid "Conflict with key binding in config file"
#~ msgstr "Störende Tastenkombination in Konfigurationsdatei" #~ msgstr "Störende Tastenkombination in Konfigurationsdatei"
@ -319,18 +302,18 @@ msgstr "Fokussiere nächst höhere Ebene"
#, c-format #, c-format
#~ msgid "Attempted to access menu \"%s\" but it does not exist" #~ 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..." #~ msgid "More..."
#~ msgstr "Mehr..." #~ msgstr "Mehr..."
#, c-format #, c-format
#~ msgid "Invalid button \"%s\" in mouse binding" #~ 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 #, c-format
#~ msgid "Invalid context \"%s\" in mouse binding" #~ 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 #, c-format
#~ msgid "Unable to change to home directory \"%s\": %s" #~ 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" #~ msgid "Unable to find a valid config file, using some simple defaults"
#~ msgstr "" #~ msgstr ""
#~ "Keine gültige Konfigurationsdatei vorhanden, daher werden einfache " #~ "Keine gültige Konfigurationsdatei vorhanden, benutze einfache "
#~ "Standardwerte benutzt" #~ "Standardwerte"
#~ msgid "Unable to load a theme." #~ msgid "Unable to load a theme."
#~ msgstr "Kann kein Thema laden." #~ 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" #~ msgid " --debug-focus Display debugging output for focus handling\n"
#~ msgstr "" #~ msgstr ""
#~ " --debug-focus Debug-Informationen für Fokus-Handling anzeigen\n" #~ " --debug-focus Fehlersuche-Ergebnis für Fokus-Handling anzeigen\n"
#~ msgid "" #~ msgid ""
#~ " --debug-session Display debugging output for session management\n" #~ " --debug-session Display debugging output for session management\n"
#~ msgstr "" #~ msgstr ""
#~ " --debug-session Debug-Informationen für Sitzungsmanager anzeigen\n" #~ " --debug-session Fehler-Ergebnis für Sitzungsmanager anzeigen\n"
#, c-format #, c-format
#~ msgid "" #~ msgid ""
@ -418,7 +401,7 @@ msgstr "Fokussiere nächst höhere Ebene"
#, c-format #, c-format
#~ msgid "Unable to make directory \"%s\": %s" #~ msgid "Unable to make directory \"%s\": %s"
#~ msgstr "Kann Verzeichnis \"%s\" nicht erstellen: %s" #~ msgstr "Kann nicht Verzeichnis \"%s\" machen: %s"
#, c-format #, c-format
#~ msgid "Unable to save the session to \"%s\": %s" #~ msgid "Unable to save the session to \"%s\": %s"
@ -426,10 +409,10 @@ msgstr "Fokussiere nächst höhere Ebene"
#, c-format #, c-format
#~ msgid "Error while saving the session to \"%s\": %s" #~ 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" #~ msgid "Not connected to a session manager"
#~ msgstr "Nicht mit Sitzungsmanager verbunden" #~ msgstr "An einer Sitzungsmanager nicht verbindet"
#, c-format #, c-format
#~ msgid "Running %s" #~ msgid "Running %s"
@ -437,7 +420,7 @@ msgstr "Fokussiere nächst höhere Ebene"
#, c-format #, c-format
#~ msgid "Invalid modifier key \"%s\" in key/mouse binding" #~ 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 #, c-format
#~ msgid "Invalid key code \"%s\" in key binding" #~ msgid "Invalid key code \"%s\" in key binding"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: Efstathios Iosifidis <iosifidis@opensuse.org>\n" "Last-Translator: Efstathios Iosifidis <iosifidis@opensuse.org>\n"
"Language-Team: Ελληνικά, Σύγχρονα <opensuse-translation-el@opensuse.org>\n" "Language-Team: Ελληνικά, Σύγχρονα <opensuse-translation-el@opensuse.org>\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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: 2024-01-25 21:35-0500\n" "PO-Revision-Date: 2022-02-22 21:21-0500\n"
"Last-Translator: Keith <keith@localhost>\n" "Last-Translator: Keith <keith@localhost>\n"
"Language-Team: Esperanto\n" "Language-Team: Esperanto\n"
"Language: eo\n" "Language: eo\n"
@ -24,7 +24,7 @@ msgid "ERROR: No configuration file found."
msgstr "ERARO: Neniu agordo-dosiero trovita." msgstr "ERARO: Neniu agordo-dosiero trovita."
msgid "Unable to evaluate expression" msgid "Unable to evaluate expression"
msgstr "Ne eblis taksi esprimon" msgstr "Ne povas taksi esprimon"
msgid "No nodesetval" msgid "No nodesetval"
msgstr "Neniu nodara valoro" msgstr "Neniu nodara valoro"
@ -41,7 +41,7 @@ msgid "Couldn't create new context!"
msgstr "Ne povis krei novan kuntekston!" msgstr "Ne povis krei novan kuntekston!"
msgid "Couldn't register the namespace" msgid "Couldn't register the namespace"
msgstr "Ne eblis registri la nomspacon" msgstr "Ne povas registri lo nomspacon"
#, c-format #, c-format
msgid "Syntax: %s [options]\n" msgid "Syntax: %s [options]\n"
@ -98,13 +98,13 @@ msgstr "%s postulas argumenton\n"
#, c-format #, c-format
msgid "%s hasn't been implemented yet.\n" 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" msgid "Successfully created backend"
msgstr "Sukcese kreis servilan dorson" msgstr "Sukcese kreis servilan dorson"
msgid "Failed to create backend" msgid "Failed to create backend"
msgstr "Malsukcesis krei servilan dorson" msgstr "Malsukesis krei servilan dorson"
msgid "Successfully started server" msgid "Successfully started server"
msgstr "Sukcese startigis servilon" msgstr "Sukcese startigis servilon"
@ -112,11 +112,17 @@ msgstr "Sukcese startigis servilon"
msgid "Failed to start server" msgid "Failed to start server"
msgstr "Malsukcesis startigi servilon" msgstr "Malsukcesis startigi servilon"
msgid "New output device detected" msgid "Couldn't get a surface texture"
msgstr "Nova eligilo malkovrita" msgstr "Ne povis akiri surfacan teksturon"
msgid "Could not add an output layout." msgid "Couldn't attach renderer to output"
msgstr "Ne eblis aldoni eligan aranĝon." 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" msgid "New keyboard detected"
msgstr "Nova klavaro malkovrita" msgstr "Nova klavaro malkovrita"
@ -130,17 +136,8 @@ msgstr "Nerekonata enigilo malkovrita"
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "Malsukcesis konektiĝi al Wayland-ekrano" 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" msgid "Failed to start backend"
msgstr "Malsukcesis startigi servilan dorson" msgstr "Malsukesis startigi servilan dorson"
msgid "Running Wayland compositor on Wayland display" msgid "Running Wayland compositor on Wayland display"
msgstr "Plenumas Wayland-komponilon sur Wayland-ekrano" msgstr "Plenumas Wayland-komponilon sur Wayland-ekrano"
@ -151,24 +148,11 @@ msgstr "Ekrano finigita"
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "Klavara fokuso nun estas sur surfaco" msgstr "Klavara fokuso nun estas sur surfaco"
msgid "Focusing next toplevel" msgid "Focusing current view"
msgstr "Fokusas la sekvan supran nivelon" msgstr "Fokusas nunan vidon"
#~ msgid "Couldn't commit pending frame to output" msgid "Focusing next view"
#~ msgstr "Ne eblis surmeti atendantan framon sur eligon" msgstr "Fokusas la sekvan vidon"
#, 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 "Unable to parse XML file" #~ msgid "Unable to parse XML file"
#~ msgstr "Ne povas analizi XML-dosieron" #~ msgstr "Ne povas analizi XML-dosieron"

View file

@ -11,8 +11,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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-12-06 22:35-0500\n" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: Nicolás de la Torre <ndelatorre@gmail.com>\n" "Last-Translator: Nicolás de la Torre <ndelatorre@gmail.com>\n"
"Language-Team: español <es@li.org>\n" "Language-Team: español <es@li.org>\n"
"Language: es\n" "Language: es\n"
@ -46,7 +46,7 @@ msgstr ""
msgid "Couldn't register the namespace" msgid "Couldn't register the namespace"
msgstr "" msgstr ""
#, c-format #, fuzzy, c-format
msgid "Syntax: %s [options]\n" msgid "Syntax: %s [options]\n"
msgstr "Sintaxis: % [opciones]\n" msgstr "Sintaxis: % [opciones]\n"
@ -114,6 +114,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -132,12 +138,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -150,6 +150,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: mihkel <turakas@gmail.com>\n" "Last-Translator: mihkel <turakas@gmail.com>\n"
"Language-Team: Estonian <et@li.org>\n" "Language-Team: Estonian <et@li.org>\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: Inko I. A. <inkoia@gmail.com>\n" "Last-Translator: Inko I. A. <inkoia@gmail.com>\n"
"Language-Team: 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" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -10,7 +10,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: Lauri Hakko <aperculum@gmail.com>\n" "Last-Translator: Lauri Hakko <aperculum@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: Cyrille Bagard <nocbos@gmail.com>\n" "Last-Translator: Cyrille Bagard <nocbos@gmail.com>\n"
"Language-Team: français <fr@li.org>\n" "Language-Team: français <fr@li.org>\n"
@ -113,6 +113,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -131,12 +137,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -149,6 +149,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 19:33-0400\n"
"Last-Translator: Javier Mancebo <palleiros@yahoo.es>\n" "Last-Translator: Javier Mancebo <palleiros@yahoo.es>\n"
"Language-Team: Galician\n" "Language-Team: Galician\n"
@ -106,6 +106,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -124,12 +130,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -142,6 +142,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 10:30-0400\n"
"Last-Translator: Eli Zaretskii <eliz@gnu.org>\n" "Last-Translator: Eli Zaretskii <eliz@gnu.org>\n"
"Language-Team: Rahut <genghiskhan@gmx.ca>\n" "Language-Team: Rahut <genghiskhan@gmx.ca>\n"
@ -107,6 +107,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:07-0400\n"
"Last-Translator: boljsa <asjlob AT vip.hr>\n" "Last-Translator: boljsa <asjlob AT vip.hr>\n"
"Language-Team: <asjlob AT vip.hr>\n" "Language-Team: <asjlob AT vip.hr>\n"
@ -107,6 +107,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:42-0400\n"
"Last-Translator: Laszlo Dvornik <rezuri@zoho.com>\n" "Last-Translator: Laszlo Dvornik <rezuri@zoho.com>\n"
"Language-Team: Hungarian\n" "Language-Team: Hungarian\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:42-0400\n"
"Last-Translator: Nik Kalach <nikka@fedoraproject.org>\n" "Last-Translator: Nik Kalach <nikka@fedoraproject.org>\n"
"Language-Team: Interlingua (International Auxiliary Language Association) " "Language-Team: Interlingua (International Auxiliary Language Association) "
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:08-0400\n"
"Last-Translator: Davide Truffa <davide@catoblepa.org>\n" "Last-Translator: Davide Truffa <davide@catoblepa.org>\n"
"Language-Team: Italian <tp@lists.linux.it>\n" "Language-Team: Italian <tp@lists.linux.it>\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:08-0400\n"
"Last-Translator: Ryoichiro Suzuki <ryoichiro.suzuki@gmail.com>\n" "Last-Translator: Ryoichiro Suzuki <ryoichiro.suzuki@gmail.com>\n"
"Language-Team: Japanese <ja@li.org>\n" "Language-Team: Japanese <ja@li.org>\n"
@ -107,6 +107,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:42-0400\n"
"Last-Translator: Algimantas Margevičius <margevicius.algimantas@gmail.com>\n" "Last-Translator: Algimantas Margevičius <margevicius.algimantas@gmail.com>\n"
"Language-Team: Lietuvių <>\n" "Language-Team: Lietuvių <>\n"
@ -110,6 +110,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -128,12 +134,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -146,6 +146,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:08-0400\n"
"Last-Translator: Einars Sprugis <einars8@gmail.com>\n" "Last-Translator: Einars Sprugis <einars8@gmail.com>\n"
"Language-Team: Latvian <locale@laka.lv>\n" "Language-Team: Latvian <locale@laka.lv>\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -1,9 +1,7 @@
i18n = import('i18n')
add_project_arguments('-DGETTEXT_PACKAGE="' + meson.project_name().to_lower() + '"', add_project_arguments('-DGETTEXT_PACKAGE="' + meson.project_name().to_lower() + '"',
'-DLOCALEDIR="' + get_option('prefix') / get_option('localedir') + '"', '-DLOCALEDIR="' + get_option('prefix') / get_option('localedir') + '"',
'-DUSE_NLS=1', language: 'c') language:'c')
i18n = import('i18n', required: false)
if i18n.found()
i18n.gettext(meson.project_name().to_lower(), i18n.gettext(meson.project_name().to_lower(),
args: ['--directory=' + source_root, args: ['--directory=' + source_root,
'--add-comments=TRANSLATORS', '--add-comments=TRANSLATORS',
@ -11,4 +9,3 @@ if i18n.found()
'--keyword=_', '--keyword=_',
'--msgid-bugs=https://github.com/wizbright/waybox/issues'] '--msgid-bugs=https://github.com/wizbright/waybox/issues']
) )
endif

View file

@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:08-0400\n"
"Last-Translator: Pjotr <pjotrvertaalt@gmail.com>\n" "Last-Translator: Pjotr <pjotrvertaalt@gmail.com>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n" "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@ -112,6 +112,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -130,12 +136,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -148,6 +148,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:23-0400\n"
"Last-Translator: Michael Kjelbergvik Thung <postlogic@gmail.com>\n" "Last-Translator: Michael Kjelbergvik Thung <postlogic@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -11,7 +11,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:08-0400\n"
"Last-Translator: Jakub Błażejczyk\n" "Last-Translator: Jakub Błażejczyk\n"
"Language-Team: polski <kuboslawik@gmail.com>\n" "Language-Team: polski <kuboslawik@gmail.com>\n"
@ -111,6 +111,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -129,12 +135,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -147,6 +147,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:42-0400\n"
"Last-Translator: Sérgio Marques <smarquespt@gmail.com>\n" "Last-Translator: Sérgio Marques <smarquespt@gmail.com>\n"
"Language-Team: \n" "Language-Team: \n"
@ -112,6 +112,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -130,12 +136,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -148,6 +148,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:45-0400\n"
"Last-Translator: Og Maciel <ogmaciel@gnome.org>\n" "Last-Translator: Og Maciel <ogmaciel@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-l10n-br@listas.cipsga.org.br>\n" "Language-Team: Brazilian Portuguese <gnome-l10n-br@listas.cipsga.org.br>\n"
@ -111,6 +111,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -129,12 +135,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -147,6 +147,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:09-0400\n"
"Last-Translator: Radu Feflea <rfeflea@googlemail.com>\n" "Last-Translator: Radu Feflea <rfeflea@googlemail.com>\n"
"Language-Team: none\n" "Language-Team: none\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:09-0400\n"
"Last-Translator: Moroz Sergey L. <se.seam@gmail.com>\n" "Last-Translator: Moroz Sergey L. <se.seam@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:09-0400\n"
"Last-Translator: Frantisek Elias <elias.frantisek@gmail.com>\n" "Last-Translator: Frantisek Elias <elias.frantisek@gmail.com>\n"
"Language-Team: Slovak <sk@sk.org>\n" "Language-Team: Slovak <sk@sk.org>\n"
@ -107,6 +107,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:09-0400\n"
"Last-Translator: Jay Alexander Fleming <tito.nehru.naser@gmail.com>\n" "Last-Translator: Jay Alexander Fleming <tito.nehru.naser@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -110,6 +110,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -128,12 +134,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -146,6 +146,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:09-0400\n"
"Last-Translator: Jay A. Fleming <tito.nehru.naser@gmail.com>\n" "Last-Translator: Jay A. Fleming <tito.nehru.naser@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -110,6 +110,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -128,12 +134,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -146,6 +146,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 18:42-0400\n"
"Last-Translator: Mikael Magnusson <mikachu@icculus.org>\n" "Last-Translator: Mikael Magnusson <mikachu@icculus.org>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -107,6 +107,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:09-0400\n"
"Last-Translator: Muhammet Kara <muhammet.k@gmail.com>\n" "Last-Translator: Muhammet Kara <muhammet.k@gmail.com>\n"
"Language-Team: Turkish <gnome-turk@gnome.org>\n" "Language-Team: Turkish <gnome-turk@gnome.org>\n"
@ -109,6 +109,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -127,12 +133,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -145,6 +145,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:10-0400\n"
"Last-Translator: Serhiy Lysovenko <lisovenko.s[at]gmail[dot]com>\n" "Last-Translator: Serhiy Lysovenko <lisovenko.s[at]gmail[dot]com>\n"
"Language-Team: Ukrainian <linux.org.ua>\n" "Language-Team: Ukrainian <linux.org.ua>\n"
@ -106,6 +106,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -124,12 +130,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -142,6 +142,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2022-02-01 21:17-0500\n"
"Last-Translator: Quan Tran <qeed.quan@gmail.com>\n" "Last-Translator: Quan Tran <qeed.quan@gmail.com>\n"
"Language-Team: None\n" "Language-Team: None\n"
@ -106,6 +106,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -124,12 +130,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -142,6 +142,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: waybox\n" "Project-Id-Version: waybox\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -104,10 +104,16 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
msgid "Could not add an output layout." msgid "Couldn't commit pending frame to output"
msgstr "" msgstr ""
msgid "New keyboard detected" msgid "New keyboard detected"
@ -122,15 +128,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" 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" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,5 +140,8 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing next toplevel" msgid "Focusing current view"
msgstr ""
msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2020-03-10 14:10-0400\n"
"Last-Translator: zhou sf <sxzzsf@gmail.com>\n" "Last-Translator: zhou sf <sxzzsf@gmail.com>\n"
"Language-Team: Simplified Chinese\n" "Language-Team: Simplified Chinese\n"
@ -108,6 +108,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -126,12 +132,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -144,6 +144,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Waybox 0.0.1\n" "Project-Id-Version: Waybox 0.0.1\n"
"Report-Msgid-Bugs-To: https://github.com/wizbright/waybox/issues\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" "PO-Revision-Date: 2022-02-01 21:14-0500\n"
"Last-Translator: 洪任諭 <pcman.tw@gmail.com>\n" "Last-Translator: 洪任諭 <pcman.tw@gmail.com>\n"
"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n" "Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
@ -107,6 +107,12 @@ msgstr ""
msgid "Failed to start server" msgid "Failed to start server"
msgstr "" msgstr ""
msgid "Couldn't get a surface texture"
msgstr ""
msgid "Couldn't attach renderer to output"
msgstr ""
msgid "New output device detected" msgid "New output device detected"
msgstr "" msgstr ""
@ -125,12 +131,6 @@ msgstr ""
msgid "Failed to connect to a Wayland display" msgid "Failed to connect to a Wayland display"
msgstr "" msgstr ""
msgid "Failed to create renderer"
msgstr ""
msgid "Failed to create allocator"
msgstr ""
msgid "Failed to start backend" msgid "Failed to start backend"
msgstr "" msgstr ""
@ -143,6 +143,9 @@ msgstr ""
msgid "Keyboard focus is now on surface" msgid "Keyboard focus is now on surface"
msgstr "" msgstr ""
msgid "Focusing current view"
msgstr ""
msgid "Focusing next view" msgid "Focusing next view"
msgstr "" msgstr ""

49
protocol/idle.xml Normal file
View 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>

View file

@ -1,7 +1,6 @@
wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir') wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir')
wayland_scanner_dep = dependency('wayland-scanner', version: '>=1.15') wayland_scanner = find_program('wayland-scanner', version: '>= 1.15')
wayland_scanner = find_program(wayland_scanner_dep.get_variable(pkgconfig: 'wayland_scanner'))
wayland_scanner_server = generator( wayland_scanner_server = generator(
wayland_scanner, wayland_scanner,
@ -23,20 +22,23 @@ wayland_scanner_client = generator(
protocols = [ protocols = [
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], [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/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/primary-selection/primary-selection-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-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'], [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
'wlr-gamma-control-unstable-v1.xml', 'wlr-gamma-control-unstable-v1.xml',
'wlr-layer-shell-unstable-v1.xml', 'idle.xml',
'wlr-screencopy-unstable-v1.xml', 'wlr-screencopy-unstable-v1.xml',
'wlr-layer-shell-unstable-v1.xml',
] ]
client_protocols = [ client_protocols = [
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.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-screencopy-unstable-v1.xml',
'wlr-layer-shell-unstable-v1.xml',
] ]
wl_protos_src = [] 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

View file

@ -1,15 +1,8 @@
#include <libxml/parser.h>
#include <libxml/xpath.h> #include <libxml/xpath.h>
#include <libxml/xpathInternals.h> #include <libxml/xpathInternals.h>
#include "config.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) { static char *parse_xpath_expr(char *expr, xmlXPathContextPtr ctxt) {
xmlXPathObjectPtr object = xmlXPathEvalExpression((xmlChar *) expr, ctxt); xmlXPathObjectPtr object = xmlXPathEvalExpression((xmlChar *) expr, ctxt);
if (object == NULL) { if (object == NULL) {
@ -32,7 +25,7 @@ static xmlChar *get_attribute(xmlNode *node, char *attr_name) {
xmlAttr *attr = node->properties; xmlAttr *attr = node->properties;
while (attr && strcmp((char *) attr->name, attr_name) != 0) while (attr && strcmp((char *) attr->name, attr_name) != 0)
attr = attr->next; 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) { 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); key_bind->cmd = (char *) xmlStrdup(cur_node->children->content);
} }
} }
} }
static bool parse_key_bindings(struct wb_config *config, xmlXPathContextPtr ctxt) { 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); doc = xmlReadFile(rc_file, NULL, XML_PARSE_RECOVER);
wlr_log(WLR_INFO, "Using config file %s", rc_file); wlr_log(WLR_INFO, "Using config file %s", rc_file);
setenv("WAYBOX_CONFIG_FILE", rc_file, true);
free(rc_file); free(rc_file);
if (doc == NULL) { if (doc == NULL) {
wlr_log(WLR_ERROR, "%s", _("Unable to parse the configuration file. Consult stderr for more information.")); 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")); 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) { if (config->keyboard_layout.use_config) {
config->keyboard_layout.layout = parse_xpath_expr("//ob:keyboard//ob:xkb//ob:layout", 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:xkb//ob:model", 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:xkb//ob:options", 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:xkb//ob:rules", 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:xkb//ob:variant", 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)) { if (!parse_key_bindings(config, ctxt)) {
xmlFreeDoc(doc); xmlFreeDoc(doc);
return false; return false;
} }
config->margins.bottom = strtoulong(parse_xpath_expr("//ob:margins/ob:bottom", ctxt)); config->margins.bottom = strtoul(parse_xpath_expr("//ob:margins/ob:bottom", ctxt), NULL, 10);
config->margins.left = strtoulong(parse_xpath_expr("//ob:margins/ob:left", ctxt)); config->margins.left = strtoul(parse_xpath_expr("//ob:margins/ob:left", ctxt), NULL, 10);
config->margins.right = strtoulong(parse_xpath_expr("//ob:margins/ob:right", ctxt)); config->margins.right = strtoul(parse_xpath_expr("//ob:margins/ob:right", ctxt), NULL, 10);
config->margins.top = strtoulong(parse_xpath_expr("//ob:margins/ob:top", ctxt)); config->margins.top = strtoul(parse_xpath_expr("//ob:margins/ob:top", ctxt), NULL, 10);
server->config = config; server->config = config;

View file

@ -4,16 +4,16 @@
#include "waybox/server.h" #include "waybox/server.h"
enum action_type { enum action_type {
ACTION_EXIT = 1 << 0, ACTION_CLOSE = 1,
ACTION_NEXT_WINDOW = 1 << 1, ACTION_EXECUTE = 2,
ACTION_EXECUTE = 1 << 2, ACTION_EXIT = 4,
ACTION_PREVIOUS_WINDOW = 1 << 3, ACTION_ICONIFY = 8,
ACTION_CLOSE = 1 << 4, ACTION_NEXT_WINDOW = 16,
ACTION_RECONFIGURE = 1 << 5, ACTION_PREVIOUS_WINDOW = 32,
ACTION_TOGGLE_MAXIMIZE = 1 << 6, ACTION_RECONFIGURE = 64,
ACTION_ICONIFY = 1 << 7, ACTION_SHADE = 128,
ACTION_SHADE = 1 << 8, ACTION_TOGGLE_MAXIMIZE = 256,
ACTION_UNSHADE = 1 << 9, ACTION_UNSHADE = 512,
}; };
struct wb_config { struct wb_config {
@ -27,26 +27,6 @@ struct wb_config {
bool use_config; bool use_config;
} keyboard_layout; } 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 { struct {
int bottom; int bottom;
int left; int left;

View file

@ -1,25 +1,15 @@
#include <stdlib.h>
#include "waybox/cursor.h" #include "waybox/cursor.h"
#include "waybox/xdg_shell.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) { static void process_cursor_move(struct wb_server *server) {
/* Move the grabbed toplevel to the new position. */ /* Move the grabbed view to the new position. */
struct wb_toplevel *toplevel = server->grabbed_toplevel; server->grabbed_view->current_position.x = server->cursor->cursor->x - server->grab_x;
if (toplevel->scene_tree->node.type == WLR_SCENE_NODE_TREE) { server->grabbed_view->current_position.y = server->cursor->cursor->y - server->grab_y;
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);
}
} }
static void process_cursor_resize(struct wb_server *server) { 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_x = server->cursor->cursor->x - server->grab_x;
double border_y = server->cursor->cursor->y - server->grab_y; double border_y = server->cursor->cursor->y - server->grab_y;
int new_left = server->grab_geo_box.x; 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; struct wlr_box geo_box;
wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box); wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
#endif view->current_position.x = new_left - geo_box.x;
toplevel->geometry.x = new_left - geo_box.x; view->current_position.y = new_top - geo_box.y;
toplevel->geometry.y = new_top - geo_box.y;
wlr_scene_node_set_position(&toplevel->scene_tree->node,
toplevel->geometry.x, toplevel->geometry.y);
int new_width = new_right - new_left; int new_width = new_right - new_left;
int new_height = new_bottom - new_top; 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) { 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; 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; double sx, sy;
struct wlr_seat *seat = server->seat->seat; struct wlr_seat *seat = server->seat->seat;
struct wlr_surface *surface = NULL; 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); server->cursor->cursor->x, server->cursor->cursor->y, &surface, &sx, &sy);
if (!toplevel) { if (!view) {
/* If there's no toplevel under the cursor, set the cursor image to a /* 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 * default. This is what makes the cursor image appear when you move it
* around the screen, not over any toplevels. */ * around the screen, not over any views. */
wlr_cursor_set_xcursor( wlr_xcursor_manager_set_cursor_image(
server->cursor->cursor, server->cursor->xcursor_manager, "default"); server->cursor->xcursor_manager, "left_ptr", server->cursor->cursor);
} }
if (surface) { 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. */ * the last client to have the cursor over it. */
wlr_seat_pointer_clear_focus(seat); 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) { static void handle_cursor_motion(struct wl_listener *listener, void *data) {
struct wb_cursor *cursor = struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_motion);
wl_container_of(listener, cursor, cursor_motion); struct wlr_event_pointer_motion *event = data;
struct wlr_pointer_motion_event *event = data; wlr_cursor_move(cursor->cursor, event->device, event->delta_x, event->delta_y);
wlr_cursor_move(cursor->cursor, &event->pointer->base,
event->delta_x, event->delta_y);
process_cursor_motion(cursor->server, event->time_msec); process_cursor_motion(cursor->server, event->time_msec);
} }
static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) {
struct wb_cursor *cursor = struct wb_cursor *cursor = wl_container_of(listener, cursor, cursor_motion_absolute);
wl_container_of(listener, cursor, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data;
struct wlr_pointer_motion_absolute_event *event = data; wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
wlr_cursor_warp_absolute(cursor->cursor, &event->pointer->base,
event->x, event->y);
process_cursor_motion(cursor->server, event->time_msec); process_cursor_motion(cursor->server, event->time_msec);
} }
@ -132,23 +114,21 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
* event. */ * event. */
struct wb_cursor *cursor = struct wb_cursor *cursor =
wl_container_of(listener, cursor, cursor_button); 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 */ /* Notify the client with pointer focus that a button press has occurred */
wlr_seat_pointer_notify_button(cursor->server->seat->seat, wlr_seat_pointer_notify_button(cursor->server->seat->seat,
event->time_msec, event->button, event->state); event->time_msec, event->button, event->state);
double sx, sy; double sx, sy;
struct wlr_surface *surface = NULL; 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); 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. */ /* If you released any buttons, we exit interactive move/resize mode. */
reset_cursor_mode(cursor->server); cursor->cursor_mode = WB_CURSOR_PASSTHROUGH;
} else { } else {
/* Focus that client if the button was _pressed_ */ /* 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) { 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. */ * for example when you move the scroll wheel. */
struct wb_cursor *cursor = struct wb_cursor *cursor =
wl_container_of(listener, cursor, cursor_axis); 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. */ /* Notify the client with pointer focus of the axis event. */
wlr_seat_pointer_notify_axis(cursor->server->seat->seat, wlr_seat_pointer_notify_axis(cursor->server->seat->seat,
event->time_msec, event->orientation, event->delta, 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) { 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 *wb_cursor_create(struct wb_server *server) {
struct wb_cursor *cursor = malloc(sizeof(struct wb_cursor)); struct wb_cursor *cursor = malloc(sizeof(struct wb_cursor));
cursor->cursor = wlr_cursor_create(); cursor->cursor = wlr_cursor_create();
cursor->cursor_mode = WB_CURSOR_PASSTHROUGH;
cursor->server = server; cursor->server = server;
const char *xcursor_size = getenv("XCURSOR_SIZE"); const char *xcursor_size = getenv("XCURSOR_SIZE");
cursor->xcursor_manager = wlr_xcursor_manager_create(getenv("XCURSOR_THEME"), cursor->xcursor_manager = wlr_xcursor_manager_create(getenv("XCURSOR_THEME"),
xcursor_size ? strtoul(xcursor_size, (char **) NULL, 10) : 24); xcursor_size ? strtoul(xcursor_size, (char **) NULL, 10) : 24);
wlr_xcursor_manager_load(cursor->xcursor_manager, 1);
cursor->cursor_motion.notify = handle_cursor_motion; cursor->cursor_motion.notify = handle_cursor_motion;
wl_signal_add(&cursor->cursor->events.motion, &cursor->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; 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_xcursor_manager_destroy(cursor->xcursor_manager);
wlr_cursor_destroy(cursor->cursor); wlr_cursor_destroy(cursor->cursor);
free(cursor); free(cursor);

View file

@ -1,27 +1,30 @@
#include "decoration.h" #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); struct wb_decoration *decoration = wl_container_of(listener, decoration, toplevel_decoration_destroy);
wl_list_remove(&decoration->toplevel_decoration_destroy.link); wl_list_remove(&decoration->toplevel_decoration_destroy.link);
free(decoration); 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); struct wb_decoration *decoration = wl_container_of(listener, decoration, mode_destroy);
wl_list_remove(&decoration->mode_destroy.link); wl_list_remove(&decoration->mode_destroy.link);
wl_list_remove(&decoration->request_mode.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 wlr_xdg_toplevel_decoration_v1 *toplevel_decoration = data;
struct wb_decoration *decoration = wl_container_of(listener, decoration, request_mode); struct wb_decoration *decoration = wl_container_of(listener, decoration, request_mode);
struct wb_toplevel *toplevel = wl_container_of(decoration->server->toplevels.next, toplevel, link); struct wb_view *view = wl_container_of(decoration->server->views.next, view, link);
if (toplevel->xdg_toplevel->base->initialized)
wlr_xdg_toplevel_decoration_v1_set_mode(toplevel_decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); 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_decoration *decoration = (struct wb_decoration *) calloc(1, sizeof(struct wb_decoration));
struct wb_server *server = wl_container_of(listener, server, new_xdg_decoration); struct wb_server *server = wl_container_of(listener, server, new_xdg_decoration);
decoration->server = server; 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); wl_signal_add(&toplevel_decoration->events.request_mode, &decoration->request_mode);
decoration->mode_destroy.notify = free_xdg_decoration_mode; decoration->mode_destroy.notify = free_xdg_decoration_mode;
wl_signal_add(&toplevel_decoration->events.destroy, &decoration->mode_destroy); 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); 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; server->new_xdg_decoration.notify = handle_new_xdg_toplevel_decoration;
wl_signal_add(&decoration->events.new_toplevel_decoration, &server->new_xdg_decoration); wl_signal_add(&decoration->events.new_toplevel_decoration, &server->new_xdg_decoration);

View file

@ -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;
}

View file

@ -1,3 +0,0 @@
#include "waybox/server.h"
bool create_idle_manager(struct wb_server *server);

View file

@ -1,369 +1,282 @@
/* /*
* More or less taken verbatim from wio <https://git.sr.ht/~sircmpwn/wio>. * More or less taken verbatim from wio <https://git.sr.ht/~sircmpwn/wio>, so in
* Additional material taken from sway <https://github.com/swaywm/sway>. * accordance with its MIT license:
* *
* Copyright 2019 Drew DeVault * Copyright 2019 Drew DeVault
* Copyright 2022 Sway Developers
*/ */
#include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_scene.h>
#include "waybox/xdg_shell.h" #include "waybox/xdg_shell.h"
static void descriptor_destroy(struct wb_scene_descriptor *desc) { static void apply_exclusive(struct wlr_box *usable_area,
if (!desc) { 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; return;
} }
struct {
wl_list_remove(&desc->destroy.link); uint32_t anchors;
int *positive_axis;
free(desc); 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) { static void arrange_layer(struct wlr_output *output,
struct wb_scene_descriptor *desc = struct wl_list *list /* struct *wb_layer_surface */,
wl_container_of(listener, desc, destroy); struct wlr_box *usable_area, bool exclusive) {
struct wb_layer_surface *wb_surface;
descriptor_destroy(desc); 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;
} }
void assign_scene_descriptor(struct wlr_scene_node *node, /* Apply */
enum wb_scene_descriptor_type type, void *data) { wb_surface->geo = box;
struct wb_scene_descriptor *desc = apply_exclusive(usable_area, state->anchor, state->exclusive_zone,
calloc(1, sizeof(struct wb_scene_descriptor)); state->margin.top, state->margin.right,
state->margin.bottom, state->margin.left);
if (!desc) { wlr_layer_surface_v1_configure(layer, box.width, box.height);
return;
}
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);
}
} }
} }
void arrange_layers(struct wb_output *output) { void arrange_layers(struct wb_output *output) {
struct wlr_box usable_area = { 0 }; struct wlr_box usable_area = { 0 };
struct wlr_box full_area;
wlr_output_effective_resolution(output->wlr_output, wlr_output_effective_resolution(output->wlr_output,
&usable_area.width, &usable_area.height); &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 non-exlusive surfaces from top->bottom */
arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom); arrange_layer(output->wlr_output,
arrange_surface(output, &full_area, &usable_area, output->layers.shell_top); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
arrange_surface(output, &full_area, &usable_area, output->layers.shell_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);
/* 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;
}
} }
static struct wlr_scene_tree *wb_layer_get_scene(struct wb_output *output, /* TODO: Focus topmost layer */
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;
} }
/* Unreachable */ static void handle_output_destroy(struct wl_listener *listener, void *data) {
return NULL; struct wb_layer_surface *layer =
} wl_container_of(listener, layer, output_destroy);
layer->layer_surface->output = NULL;
static struct wb_layer_surface *wb_layer_surface_create( wl_list_remove(&layer->output_destroy.link);
struct wlr_scene_layer_surface_v1 *scene) { wlr_layer_surface_v1_destroy(layer->layer_surface);
struct wb_layer_surface *surface = calloc(1, sizeof(struct wb_layer_surface));
if (!surface) {
return NULL;
}
surface->scene = scene;
return surface;
} }
static void handle_surface_commit(struct wl_listener *listener, void *data) { static void handle_surface_commit(struct wl_listener *listener, void *data) {
struct wb_layer_surface *surface = struct wb_layer_surface *layer =
wl_container_of(listener, surface, surface_commit); wl_container_of(listener, layer, surface_commit);
struct wb_toplevel *current_toplevel = struct wlr_layer_surface_v1 *layer_surface = layer->layer_surface;
wl_container_of(surface->server->toplevels.next, current_toplevel, link); struct wlr_output *wlr_output = layer_surface->output;
if (wlr_output != NULL) {
if (!surface->output || current_toplevel->xdg_toplevel->current.fullscreen) { struct wb_output *output = wlr_output->data;
return; 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) { static void handle_destroy(struct wl_listener *listener, void *data) {
struct wb_layer_surface *surface = struct wb_layer_surface *layer = wl_container_of(
wl_container_of(listener, surface, destroy); listener, layer, destroy);
wl_list_remove(&layer->link);
if (surface->output) { wl_list_remove(&layer->destroy.link);
arrange_layers(surface->output); 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);
}
free(layer);
} }
wl_list_remove(&surface->new_popup.link); static void handle_map(struct wl_listener *listener, void *data) {
wb_layer_surface_destroy(surface);
}
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 = &current->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) {
struct wlr_layer_surface_v1 *layer_surface = 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) { if (!layer_surface->output) {
/* Assign last active output */ struct wlr_output *output = wlr_output_layout_output_at(
layer_surface->output = output->wlr_output; server->output_layout, server->cursor->cursor->x, server->cursor->cursor->y);
layer_surface->output = output;
} }
struct wb_output *output = layer_surface->output->data;
enum zwlr_layer_shell_v1_layer layer_type = layer_surface->pending.layer; struct wb_layer_surface *wb_surface =
struct wlr_scene_tree *output_layer = wb_layer_get_scene( calloc(1, sizeof(struct wb_layer_surface));
output, layer_type); if (!wb_surface) {
struct wlr_scene_layer_surface_v1 *scene_surface =
wlr_scene_layer_surface_v1_create(output_layer, layer_surface);
if (!scene_surface) {
return; return;
} }
wb_surface->layer_surface = layer_surface;
layer_surface->data = wb_surface;
wb_surface->server = server;
struct wb_layer_surface *surface = wb_surface->surface_commit.notify = handle_surface_commit;
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;
wl_signal_add(&layer_surface->surface->events.commit, wl_signal_add(&layer_surface->surface->events.commit,
&surface->surface_commit); &wb_surface->surface_commit);
surface->map.notify = handle_map; wb_surface->output_destroy.notify = handle_output_destroy;
wl_signal_add(&layer_surface->surface->events.map, &surface->map); wl_signal_add(&layer_surface->output->events.destroy,
surface->unmap.notify = handle_unmap; &wb_surface->output_destroy);
wl_signal_add(&layer_surface->surface->events.unmap, &surface->unmap); wb_surface->destroy.notify = handle_destroy;
surface->destroy.notify = handle_destroy; wl_signal_add(&layer_surface->events.destroy, &wb_surface->destroy);
wl_signal_add(&layer_surface->events.destroy, &surface->destroy); wb_surface->map.notify = handle_map;
surface->new_popup.notify = handle_new_popup; wl_signal_add(&layer_surface->events.map, &wb_surface->map);
wl_signal_add(&layer_surface->events.new_popup, &surface->new_popup); /* 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 /* Temporarily set the layer's current state to pending
* So that we can easily arrange it */ * So that we can easily arrange it */
struct wlr_layer_surface_v1_state old_state = layer_surface->current; 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; layer_surface->current = old_state;
} }
void init_layer_shell(struct wb_server *server) { 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; 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, wl_signal_add(&server->layer_shell->events.new_surface,
&server->new_layer_surface); &server->new_layer_surface);
} }

View file

@ -2,51 +2,21 @@
#define _WB_LAYERS_H #define _WB_LAYERS_H
#include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_layer_shell_v1.h>
#include "waybox/output.h" struct wb_server;
struct wb_layer_surface { struct wb_layer_surface {
struct wb_output *output; struct wlr_layer_surface_v1 *layer_surface;
struct wb_server *server; struct wb_server *server;
struct wl_list link;
struct wlr_scene_layer_surface_v1 *scene;
bool mapped;
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener map; struct wl_listener map;
struct wl_listener unmap;
struct wl_listener surface_commit; struct wl_listener surface_commit;
struct wl_listener new_popup; struct wl_listener output_destroy;
};
struct wb_layer_popup { struct wlr_box geo;
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;
}; };
void init_layer_shell(struct wb_server *server); 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 #endif

View file

@ -4,7 +4,8 @@
#include "waybox/server.h" #include "waybox/server.h"
bool show_help(char *name) { bool show_help(char *name)
{
printf(_("Syntax: %s [options]\n"), name); printf(_("Syntax: %s [options]\n"), name);
printf(_("\nOptions:\n")); printf(_("\nOptions:\n"));
printf(_(" --help Display this help and exit\n")); printf(_(" --help Display this help and exit\n"));
@ -21,15 +22,16 @@ bool show_help(char *name) {
} }
struct wb_server server = {0}; struct wb_server server = {0};
void signal_handler(int sig) { void signal_handler(int sig)
{
switch (sig) { switch (sig) {
case SIGINT: case SIGINT:
case SIGTERM: case SIGTERM:
wl_display_terminate(server.wl_display); wl_display_terminate(server.wl_display);
break; break;
case SIGUSR1: case SIGUSR1:
/* Openbox uses SIGUSR1 to restart and SIGUSR2 to reconfigure. /* Openbox uses SIGUSR1 to restart. I'm not sure of the
* What's the difference? * difference between restarting and reconfiguring.
*/ */
case SIGUSR2: case SIGUSR2:
deinit_config(server.config); deinit_config(server.config);
@ -113,7 +115,6 @@ int main(int argc, char **argv) {
sigaction(SIGTERM, &sa, NULL); sigaction(SIGTERM, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGUSR2, &sa, NULL); sigaction(SIGUSR2, &sa, NULL);
wl_display_run(server.wl_display); wl_display_run(server.wl_display);
wb_terminate(&server); wb_terminate(&server);

View file

@ -2,7 +2,6 @@ wb_src = files(
'config.c', 'config.c',
'cursor.c', 'cursor.c',
'decoration.c', 'decoration.c',
'idle.c',
'layer_shell.c', 'layer_shell.c',
'main.c', 'main.c',
'output.c', 'output.c',
@ -12,8 +11,6 @@ wb_src = files(
) )
wb_dep = [ wb_dep = [
libevdev,
libinput,
libxml2, libxml2,
wayland_server, wayland_server,
wlroots, wlroots,
@ -27,5 +24,4 @@ executable(
dependencies: [wb_dep, wlr_protos], dependencies: [wb_dep, wlr_protos],
install: true, install: true,
install_dir: get_option('prefix') / get_option('libexecdir'), install_dir: get_option('prefix') / get_option('libexecdir'),
link_args: ['-Wl,-lm'],
) )

View file

@ -1,92 +1,163 @@
#include "waybox/output.h" #include "waybox/output.h"
void output_frame_notify(struct wl_listener *listener, void *data) { struct render_data {
/* This function is called every time an output is ready to display a frame, struct wlr_output *output;
* generally at the output's refresh rate (e.g. 60Hz). */ struct wlr_renderer *renderer;
struct wb_output *output = wl_container_of(listener, output, frame); struct wb_view *view;
struct wlr_scene *scene = output->server->scene; struct timespec *when;
struct wlr_scene_output *scene_output = };
wlr_scene_get_scene_output(scene, output->wlr_output);
wlr_output_layout_get_box(output->server->output_layout, static void render_surface(struct wlr_surface *surface,
output->wlr_output, &output->geometry); 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) { /* We first obtain a wlr_texture, which is a GPU resource. wlroots
output->gamma_lut_changed = false; * automatically handles negotiating these with the client. The underlying
struct wlr_gamma_control_v1 *gamma_control = * resource could be an opaque handle passed from the client, or the client
wlr_gamma_control_manager_v1_get_control(output->server->gamma_control_manager, * could have sent a pixel buffer which we copied to the GPU, or a few other
output->wlr_output); * means. You don't have to worry about this, wlroots takes care of it. */
struct wlr_output_state pending; struct wlr_texture *texture = wlr_surface_get_texture(surface);
if (!wlr_scene_output_build_state(scene_output, &pending, NULL)) if (texture == NULL) {
return; wlr_log(WLR_ERROR, "%s", _("Couldn't get a surface texture"));
if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
wlr_output_state_finish(&pending);
return; return;
} }
if (!wlr_output_test_state(output->wlr_output, &pending)) { /* The view has a position in layout coordinates. If you have two displays,
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); * one next to the other, both 1080p, a view on the rightmost display might
wlr_output_state_finish(&pending); * have layout coordinates of 2000,100. We need to translate that to
return; * 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 /* This lets the client know that we've displayed that frame and it can
* prepare another one now if it likes. */ * 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; struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &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) { static void render_layer(
struct wb_server *server = wl_container_of(listener, server, wlr_output_manager); struct wb_output *output, struct wl_list *layer_surfaces) {
struct wlr_output_configuration_v1 *configuration = data; struct wb_layer_surface *layer_surface;
wlr_output_configuration_v1_send_succeeded(configuration); 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) { void output_frame_notify(struct wl_listener *listener, void *data) {
output_configuration_applied(listener, data); struct wb_output *output = wl_container_of(listener, output, frame);
struct wlr_renderer *renderer = output->server->renderer;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
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);
float color[4] = {0.4f, 0.4f, 0.4f, 1.0f};
wlr_renderer_clear(renderer, color);
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);
} }
void output_request_state_notify(struct wl_listener *listener, void *data) { render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
struct wb_output *output = wl_container_of(listener, output, request_state); render_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
const struct wlr_output_event_request_state *event = data;
struct wlr_output_configuration_v1 *configuration = wlr_output_configuration_v1_create(); wlr_output_render_software_cursors(output->wlr_output, NULL);
wlr_output_manager_v1_set_configuration(output->server->wlr_output_manager, configuration); wlr_renderer_end(renderer);
wlr_output_commit(output->wlr_output);
wlr_output_commit_state(output->wlr_output, event->state);
}
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);
} }
void output_destroy_notify(struct wl_listener *listener, void *data) { void output_destroy_notify(struct wl_listener *listener, void *data) {
struct wb_output *output = wl_container_of(listener, output, destroy); 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->destroy.link);
wl_list_remove(&output->frame.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); free(output);
} }
@ -101,38 +172,32 @@ void new_output_notify(struct wl_listener *listener, void *data) {
* and our renderer */ * and our renderer */
wlr_output_init_render(wlr_output, server->allocator, server->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_mode *mode = wlr_output_preferred_mode(wlr_output);
struct wlr_output_state state; wlr_output_set_mode(wlr_output, mode);
wlr_output_state_init(&state); wlr_output_enable(wlr_output, true);
wlr_output_state_set_enabled(&state, true);
if (mode != NULL) { if (!wlr_output_commit(wlr_output)) {
wlr_output_state_set_mode(&state, mode); 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)); struct wb_output *output = calloc(1, sizeof(struct wb_output));
output->server = server; output->server = server;
output->wlr_output = wlr_output; output->wlr_output = wlr_output;
wlr_output->data = 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_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; output->destroy.notify = output_destroy_notify;
wl_signal_add(&wlr_output->events.destroy, &output->destroy); wl_signal_add(&wlr_output->events.destroy, &output->destroy);
output->frame.notify = output_frame_notify; output->frame.notify = output_frame_notify;
wl_signal_add(&wlr_output->events.frame, &output->frame); 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 /* Adds this to the output layout. The add_auto function arranges outputs
* from left-to-right in the order they appear. A more sophisticated * 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 * display, which Wayland clients can see to find out information about the
* output (such as DPI, scale factor, manufacturer, etc). * 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); 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);
} }

View file

@ -1,58 +1,43 @@
#include <libevdev/libevdev.h>
#include <unistd.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/seat.h"
#include "waybox/xdg_shell.h" #include "waybox/xdg_shell.h"
static void deiconify_toplevel(struct wb_toplevel *toplevel) { static void deiconify_view(struct wb_view *view) {
if (toplevel->xdg_toplevel->requested.minimized) { if (view->xdg_toplevel->requested.minimized) {
toplevel->xdg_toplevel->requested.minimized = false; view->xdg_toplevel->requested.minimized = false;
wl_signal_emit(&toplevel->xdg_toplevel->events.request_minimize, NULL); wl_signal_emit(&view->xdg_toplevel->events.request_minimize, NULL);
} }
} }
static void cycle_toplevels(struct wb_server *server) { static void cycle_views(struct wb_server *server) {
/* Cycle to the next toplevel */ /* Cycle to the next view */
if (wl_list_length(&server->toplevels) < 1) { if (wl_list_length(&server->views) < 1) {
return; return;
} }
struct wb_view *current_view = wl_container_of(
struct wb_toplevel *current_toplevel = wl_container_of( server->views.prev, current_view, link);
server->toplevels.prev, current_toplevel, link); deiconify_view(current_view);
deiconify_toplevel(current_toplevel); focus_view(current_view, current_view->xdg_toplevel->base->surface);
focus_toplevel(current_toplevel); /* Move the current view to the beginning of the list */
wl_list_remove(&current_view->link);
/* Move the current toplevel to the beginning of the list */ wl_list_insert(&server->views, &current_view->link);
wl_list_remove(&current_toplevel->link);
wl_list_insert(&server->toplevels, &current_toplevel->link);
} }
static void cycle_toplevels_reverse(struct wb_server *server) { static void cycle_views_reverse(struct wb_server *server) {
/* Cycle to the previous toplevel */ /* Cycle to the previous view */
if (wl_list_length(&server->toplevels) < 1) { if (wl_list_length(&server->views) < 1) {
return; return;
} }
struct wb_view *current_view = wl_container_of(
struct wb_toplevel *current_toplevel = wl_container_of( server->views.next, current_view, link);
server->toplevels.next, current_toplevel, link); struct wb_view *next_view = wl_container_of(
struct wb_toplevel *next_toplevel = wl_container_of( current_view->link.next, next_view, link);
current_toplevel->link.next, next_toplevel, link); deiconify_view(next_view);
deiconify_toplevel(next_toplevel); focus_view(next_view, next_view->xdg_toplevel->base->surface);
focus_toplevel(next_toplevel); /* Move the current view to after the previous view in the list */
wl_list_remove(&current_view->link);
/* Move the current toplevel to after the previous toplevel in the list */ wl_list_insert(server->views.prev, &current_view->link);
wl_list_remove(&current_toplevel->link);
wl_list_insert(server->toplevels.prev, &current_toplevel->link);
} }
static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32_t modifiers) { 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 * Returns true if the keybinding is handled, false to send it to the
* client. * 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) { if (!server->config) {
/* Some default key bindings, when the rc.xml file can't be /* Some default key bindings, when the rc.xml file can't be
* parsed. */ * parsed. */
if (modifiers & WLR_MODIFIER_ALT && sym == XKB_KEY_Tab) if (modifiers & WLR_MODIFIER_ALT && sym == XKB_KEY_Tab)
cycle_toplevels(server); cycle_views(server);
else if (modifiers & (WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT) && else if (modifiers & (WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT) &&
sym == XKB_KEY_Tab) sym == XKB_KEY_Tab)
cycle_toplevels_reverse(server); cycle_views_reverse(server);
else if (sym == XKB_KEY_Escape && modifiers & WLR_MODIFIER_CTRL) else if (sym == XKB_KEY_Escape && modifiers & WLR_MODIFIER_CTRL)
wl_display_terminate(server->wl_display); wl_display_terminate(server->wl_display);
else 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) { wl_list_for_each(key_binding, &server->config->key_bindings, link) {
if (sym == key_binding->sym && modifiers == key_binding->modifiers) { if (sym == key_binding->sym && modifiers == key_binding->modifiers) {
if (key_binding->action & ACTION_NEXT_WINDOW) if (key_binding->action & ACTION_NEXT_WINDOW)
cycle_toplevels(server); cycle_views(server);
if (key_binding->action & ACTION_PREVIOUS_WINDOW) if (key_binding->action & ACTION_PREVIOUS_WINDOW)
cycle_toplevels_reverse(server); cycle_views_reverse(server);
if (key_binding->action & ACTION_CLOSE) { if (key_binding->action & ACTION_CLOSE) {
struct wb_toplevel *current_toplevel = wl_container_of( struct wb_view *current_view = wl_container_of(
server->toplevels.next, current_toplevel, link); server->views.next, current_view, link);
if (current_toplevel->scene_tree->node.enabled) if (current_view->mapped)
wlr_xdg_toplevel_send_close(current_toplevel->xdg_toplevel); #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 (key_binding->action & ACTION_EXECUTE) {
if (fork() == 0) { 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) { if (key_binding->action & ACTION_TOGGLE_MAXIMIZE) {
struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link); struct wb_view *view = wl_container_of(server->views.next, view, link);
if (toplevel->scene_tree->node.enabled) if (view->mapped)
wl_signal_emit(&toplevel->xdg_toplevel->events.request_maximize, NULL); wl_signal_emit(&view->xdg_toplevel->events.request_maximize, NULL);
} }
if (key_binding->action & ACTION_ICONIFY) { if (key_binding->action & ACTION_ICONIFY) {
struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link); struct wb_view *view = wl_container_of(server->views.next, view, link);
if (toplevel->scene_tree->node.enabled) { if (view->mapped) {
toplevel->xdg_toplevel->requested.minimized = true; view->xdg_toplevel->requested.minimized = true;
wl_signal_emit(&toplevel->xdg_toplevel->events.request_minimize, NULL); 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) { if (key_binding->action & ACTION_SHADE) {
struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link); struct wb_view *view = wl_container_of(server->views.next, view, link);
if (toplevel->scene_tree->node.enabled) { if (view->mapped) {
#if WLR_CHECK_VERSION(0, 19, 0) view->previous_position = view->current_position;
struct wlr_box geo_box = toplevel->xdg_toplevel->base->geometry; #if WLR_CHECK_VERSION(0, 16, 0)
wlr_xdg_toplevel_set_size(view->xdg_toplevel,
view->current_position.width, view->decoration_height);
#else #else
struct wlr_box geo_box; wlr_xdg_toplevel_set_size(view->xdg_surface,
wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box); view->current_position.width, view->decoration_height);
#endif #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) { if (key_binding->action & ACTION_UNSHADE) {
struct wb_toplevel *toplevel = wl_container_of(server->toplevels.next, toplevel, link); struct wb_view *view = wl_container_of(server->views.next, view, link);
if (toplevel->previous_geometry.height > 0 && toplevel->previous_geometry.width > 0 && toplevel->scene_tree->node.enabled) { if (view->mapped) {
wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, #if WLR_CHECK_VERSION(0, 16, 0)
toplevel->previous_geometry.width, toplevel->previous_geometry.height); 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) { 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; 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( static void keyboard_handle_modifiers(
struct wl_listener *listener, void *data) { struct wl_listener *listener, void *data) {
/* This event is raised when a modifier key, such as shift or alt, is /* 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 * same seat. You can swap out the underlying wlr_keyboard like this and
* wlr_seat handles this transparently. * 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. */ /* Send modifiers to the client. */
wlr_seat_keyboard_notify_modifiers(keyboard->server->seat->seat, wlr_seat_keyboard_notify_modifiers(keyboard->server->seat->seat,
&keyboard->keyboard->modifiers); &keyboard->device->keyboard->modifiers);
} }
static void keyboard_handle_key( static void keyboard_handle_key(
@ -192,7 +161,7 @@ static void keyboard_handle_key(
struct wb_keyboard *keyboard = struct wb_keyboard *keyboard =
wl_container_of(listener, keyboard, key); wl_container_of(listener, keyboard, key);
struct wb_server *server = keyboard->server; 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; struct wlr_seat *seat = server->seat->seat;
/* Translate libinput keycode -> xkbcommon */ /* 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 */ /* Get a list of keysyms based on the keymap for this keyboard */
const xkb_keysym_t *syms; const xkb_keysym_t *syms;
int nsyms = xkb_state_key_get_syms( int nsyms = xkb_state_key_get_syms(
keyboard->keyboard->xkb_state, keycode, &syms); keyboard->device->keyboard->xkb_state, keycode, &syms);
bool handled = false; 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) { if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
for (int i = 0; i < nsyms; i++) { for (int i = 0; i < nsyms; i++) {
handled = handle_keybinding(server, syms[i], modifiers); handled = handle_keybinding(server, syms[i], modifiers);
@ -212,12 +181,10 @@ static void keyboard_handle_key(
if (!handled) { if (!handled) {
/* Otherwise, we pass it along to the client. */ /* 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, wlr_seat_keyboard_notify_key(seat, event->time_msec,
event->keycode, event->state); event->keycode, event->state);
} }
wlr_idle_notifier_v1_notify_activity(server->idle_notifier, seat);
} }
static void handle_new_keyboard(struct wb_server *server, 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 = struct wb_keyboard *keyboard =
calloc(1, sizeof(struct wb_keyboard)); calloc(1, sizeof(struct wb_keyboard));
keyboard->server = server; 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. */ /* We need to prepare an XKB keymap and assign it to the keyboard. */
struct xkb_rule_names *rules = malloc(sizeof(struct xkb_rule_names)); 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); XKB_KEYMAP_COMPILE_NO_FLAGS);
if (keymap != NULL) { if (keymap != NULL) {
wlr_keyboard_set_keymap(keyboard->keyboard, keymap); wlr_keyboard_set_keymap(device->keyboard, keymap);
wlr_keyboard_set_repeat_info(keyboard->keyboard, 25, 600); wlr_keyboard_set_repeat_info(device->keyboard, 25, 600);
} }
free(rules); free(rules);
xkb_keymap_unref(keymap); xkb_keymap_unref(keymap);
xkb_context_unref(context); xkb_context_unref(context);
/* Here we set up listeners for keyboard events. */ /* 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; 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; 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 */ /* And add the keyboard to our list of keyboards */
wl_list_insert(&server->seat->keyboards, &keyboard->link); 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) { static void new_input_notify(struct wl_listener *listener, void *data) {
struct wlr_input_device *device = data; struct wlr_input_device *device = data;
struct wb_server *server = wl_container_of(listener, server, new_input); 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; break;
case WLR_INPUT_DEVICE_POINTER: case WLR_INPUT_DEVICE_POINTER:
wlr_log(WLR_INFO, "%s: %s", _("New pointer detected"), device->name); 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; break;
default: default:
wlr_log(WLR_INFO, "%s: %s", _("Unsupported input device detected"), device->name); 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); 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, static void handle_request_set_primary_selection(struct wl_listener *listener,
void *data) { void *data) {
struct wb_seat *seat = 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) { 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_primary_selection.link);
wl_list_remove(&seat->request_set_selection.link); wl_list_remove(&seat->request_set_selection.link);
wlr_seat_destroy(seat->seat);
free(seat); free(seat);
} }

View file

@ -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/server.h"
#include "waybox/xdg_shell.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) { bool wb_create_backend(struct wb_server* server) {
/* The Wayland display is managed by libwayland. It handles accepting /* The Wayland display is managed by libwayland. It handles accepting
@ -18,19 +10,12 @@ bool wb_create_backend(struct wb_server* server) {
return false; 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 /* The backend is a wlroots feature which abstracts the underlying input and
* output hardware. The autocreate option will choose the most suitable * output hardware. The autocreate option will choose the most suitable
* backend based on the current environment, such as opening an X11 window * backend based on the current environment, such as opening an X11 window
* if an X11 server is running. */ * 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) { if (server->backend == NULL) {
wlr_log(WLR_ERROR, "%s", _("Failed to create backend"));
return false; 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 * The renderer is responsible for defining the various pixel formats it
* supports for shared memory, this configures that for clients. */ * supports for shared memory, this configures that for clients. */
server->renderer = wlr_renderer_autocreate(server->backend); 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); wlr_renderer_init_wl_display(server->renderer, server->wl_display);
/* Autocreates an allocator for us. /* 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 * handles the buffer creation, allowing wlroots to render onto the
* screen */ * screen */
server->allocator = wlr_allocator_autocreate(server->backend, server->renderer); 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 = server->compositor = wlr_compositor_create(server->wl_display,
wlr_compositor_create(server->wl_display, 5, server->renderer); server->renderer);
#if WLR_CHECK_VERSION(0, 16, 0)
server->subcompositor = wlr_subcompositor_create(server->wl_display); 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->seat = wb_seat_create(server);
server->cursor = wb_cursor_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) { bool wb_start_server(struct wb_server* server) {
init_config(server); init_config(server);
init_output(server); wl_list_init(&server->outputs);
/* Create a scene graph. This is a wlroots abstraction that handles all server->new_output.notify = new_output_notify;
* rendering and damage tracking. All the compositor author needs to do wl_signal_add(&server->backend->events.new_output, &server->new_output);
* 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);
const char *socket = wl_display_add_socket_auto(server->wl_display); const char *socket = wl_display_add_socket_auto(server->wl_display);
if (!socket) { 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); wlr_log(WLR_INFO, "%s: WAYLAND_DISPLAY=%s", _("Running Wayland compositor on Wayland display"), socket);
setenv("WAYLAND_DISPLAY", socket, true); 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); 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); 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_xdg_decoration(server);
init_layer_shell(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); 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; return true;
} }
bool wb_terminate(struct wb_server* server) { bool wb_terminate(struct wb_server* server) {
wb_cursor_destroy(server->cursor); wb_cursor_destroy(server->cursor);
wl_list_remove(&server->new_xdg_decoration.link); /* wb_decoration_destroy */ wl_list_remove(&server->new_xdg_decoration.link); /* wb_decoration_destroy */
wb_seat_destroy(server->seat);
deinit_config(server->config); deinit_config(server->config);
wl_display_destroy_clients(server->wl_display); 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); 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")); wlr_log(WLR_INFO, "%s", _("Display destroyed"));

View file

@ -1,335 +1,228 @@
#include "idle.h"
#include "waybox/xdg_shell.h" #include "waybox/xdg_shell.h"
struct wb_toplevel *get_toplevel_at( void focus_view(struct wb_view *view, struct wlr_surface *surface) {
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) {
/* Note: this function only deals with keyboard focus. */ /* 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; return;
} }
struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_from_wlr_surface(surface);
struct wlr_surface *surface = toplevel->xdg_toplevel->base->surface; if (xdg_surface)
struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_try_from_wlr_surface(surface);
if (xdg_surface != NULL)
wlr_log(WLR_INFO, "%s: %s", _("Keyboard focus is now on surface"), wlr_log(WLR_INFO, "%s: %s", _("Keyboard focus is now on surface"),
xdg_surface->toplevel->app_id); xdg_surface->toplevel->app_id);
struct wb_server *server = view->server;
struct wb_server *server = toplevel->server;
if (server->seat->focused_layer != NULL) {
/* If a layer is focused, don't focus a toplevel. */
return;
}
struct wlr_seat *seat = server->seat->seat; struct wlr_seat *seat = server->seat->seat;
struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface; struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface;
if (prev_surface == surface) { if (prev_surface == surface) {
/* Don't focus a surface that's already focused. */ /* Don't re-focus an already focused surface. */
return; return;
} }
if (prev_surface != NULL) { if (prev_surface) {
/* /*
* Deactivate the previously focused surface. This lets the client know * Deactivate the previously focused surface. This lets the client know
* it no longer has focus and the client will repaint accordingly, e.g. * it no longer has focus and the client will repaint accordingly, e.g.
* stop displaying a caret. * stop displaying a caret.
*/ */
struct wlr_xdg_toplevel *prev_toplevel = struct wlr_xdg_surface *previous = wlr_xdg_surface_from_wlr_surface(
wlr_xdg_toplevel_try_from_wlr_surface(prev_surface); seat->keyboard_state.focused_surface);
if (prev_toplevel != NULL) { #if WLR_CHECK_VERSION(0, 16, 0)
wlr_xdg_toplevel_set_activated(prev_toplevel, false); wlr_xdg_toplevel_set_activated(previous->toplevel, false);
#else
wlr_xdg_toplevel_set_activated(previous, false);
#endif
} }
} struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat);
/* Move the toplevel to the front */ /* Move the view to the front */
wlr_scene_node_raise_to_top(&toplevel->scene_tree->node); wl_list_remove(&view->link);
wl_list_remove(&toplevel->link); wl_list_insert(&server->views, &view->link);
wl_list_insert(&server->toplevels, &toplevel->link);
/* Activate the new surface */ /* 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 * Tell the seat to have the keyboard enter this surface. wlroots will keep
* track of this and automatically send key events to the appropriate * track of this and automatically send key events to the appropriate
* clients without additional work on your part. * 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; double closest_x, closest_y;
struct wlr_output *output = NULL; 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}; 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); wlr_output_effective_resolution(output, &usable_area.width, &usable_area.height);
return usable_area; return usable_area;
} }
static void xdg_toplevel_map(struct wl_listener *listener, void *data) { static void xdg_surface_commit(struct wl_listener *listener, void *data) {
/* Called when the surface is mapped, or ready to display on-screen. */ /* Called after the surface is committed */
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, map); struct wb_view *view = wl_container_of(listener, view, surface_commit);
if (toplevel->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) 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; return;
struct wb_config *config = toplevel->server->config; struct wb_config *config = view->server->config;
struct wlr_box usable_area = get_usable_area(toplevel); int left_margin, top_margin;
#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
if (config) { if (config) {
toplevel->geometry.height = MIN(geo_box.height, left_margin = config->margins.left;
usable_area.height - config->margins.top - config->margins.bottom); top_margin = config->margins.top;
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;
} else { } else {
toplevel->geometry.height = MIN(geo_box.height, usable_area.height); left_margin = 0;
toplevel->geometry.width = MIN(geo_box.width, usable_area.width); top_margin = 0;
toplevel->geometry.x = 0; }
toplevel->geometry.y = 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, static void xdg_surface_map(struct wl_listener *listener, void *data) {
toplevel->geometry.width, toplevel->geometry.height); /* Called when the surface is mapped, or ready to display on-screen. */
focus_toplevel(toplevel); struct wb_view *view = wl_container_of(listener, view, map);
view->mapped = true;
wlr_scene_node_set_position(&toplevel->scene_tree->node, if (view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
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)
return; return;
reset_cursor_mode(toplevel->server);
/* Focus the next toplevel, if any. */ struct wb_config *config = view->server->config;
if (wl_list_length(&toplevel->link) > 1) { struct wlr_box geo_box = {0};
struct wb_toplevel *next_toplevel = wl_container_of(toplevel->link.next, next_toplevel, link); wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
if (next_toplevel && next_toplevel->xdg_toplevel && next_toplevel->scene_tree && next_toplevel->scene_tree->node.enabled) { view->current_position = geo_box;
wlr_log(WLR_INFO, "%s: %s", _("Focusing next toplevel"), if (config) {
next_toplevel->xdg_toplevel->app_id); struct wlr_box usable_area = get_usable_area(view);
focus_toplevel(next_toplevel); 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 update_fractional_scale(struct wlr_surface *surface) { static void xdg_surface_unmap(struct wl_listener *listener, void *data) {
float scale = 1; /* Called when the surface is unmapped, and should no longer be shown. */
struct wlr_surface_output *surface_output; struct wb_view *view = wl_container_of(listener, view, unmap);
wl_list_for_each(surface_output, &surface->current_outputs, link) { view->mapped = false;
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_view *current_view = wl_container_of(view->server->views.next, current_view, link);
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, commit); struct wb_view *next_view = wl_container_of(current_view->link.next, next_view, link);
struct wlr_xdg_surface *base = toplevel->xdg_toplevel->base; if (current_view->xdg_toplevel->base->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
return;
struct wlr_output *output = get_active_output(toplevel); /* If the current view is mapped, focus it. */
wlr_surface_send_enter(base->surface, output); if (current_view->mapped) {
update_fractional_scale(base->surface); wlr_log(WLR_INFO, "%s: %s", _("Focusing current view"),
current_view->xdg_toplevel->app_id);
if (base->initial_commit) { focus_view(current_view, current_view->xdg_toplevel->base->surface);
wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0); }
if (toplevel->decoration != NULL) /* Otherwise, focus the next view, if any. */
wl_signal_emit(&toplevel->decoration->events.request_mode, toplevel->decoration); 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 xdg_toplevel_destroy(struct wl_listener *listener, void *data) { static void xdg_surface_destroy(struct wl_listener *listener, void *data) {
/* Called when the xdg_toplevel is destroyed and should never be shown again. */ /* Called when the surface is destroyed and should never be shown again. */
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, destroy); struct wb_view *view = wl_container_of(listener, view, destroy);
if (view->xdg_toplevel->base->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
struct wlr_output *output = get_active_output(toplevel); wl_list_remove(&view->link);
struct wlr_xdg_surface *base = toplevel->xdg_toplevel->base; free(view);
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_toplevel_request_maximize(struct wl_listener *listener, void *data) { static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *data) {
/* This event is raised when a client would like to maximize itself, struct wb_view *view = wl_container_of(listener, view, request_maximize);
* typically because the user clicked on the maximize button on struct wlr_box usable_area = get_usable_area(view);
* client-side decorations.
*/
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize);
struct wlr_box usable_area = get_usable_area(toplevel);
bool is_maximized = toplevel->xdg_toplevel->current.maximized; bool is_maximized = view->xdg_toplevel->current.maximized;
if (!is_maximized) { if (!is_maximized) {
struct wb_config *config = toplevel->server->config; struct wb_config *config = view->server->config;
toplevel->previous_geometry = toplevel->geometry; view->previous_position = view->current_position;
if (config) { if (config) {
toplevel->geometry.x = config->margins.left; view->current_position.x = config->margins.left;
toplevel->geometry.y = config->margins.top; view->current_position.y = config->margins.top + view->decoration_height;
usable_area.height -= config->margins.top + config->margins.bottom; usable_area.height -= config->margins.top + config->margins.bottom;
usable_area.width -= config->margins.left + config->margins.right; usable_area.width -= config->margins.left + config->margins.right;
} else { } else {
toplevel->geometry.x = 0; view->current_position.x = 0;
toplevel->geometry.y = 0; view->current_position.y = view->decoration_height;
} }
} else { } else {
usable_area = toplevel->previous_geometry; usable_area = view->previous_position;
toplevel->geometry.x = toplevel->previous_geometry.x; view->current_position.x = view->previous_position.x;
toplevel->geometry.y = toplevel->previous_geometry.y; view->current_position.y = view->previous_position.y;
} }
wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, usable_area.width, usable_area.height); #if WLR_CHECK_VERSION(0, 16, 0)
wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, !is_maximized); wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable_area.width, usable_area.height);
wlr_scene_node_set_position(&toplevel->scene_tree->node, wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, !is_maximized);
toplevel->geometry.x, toplevel->geometry.y); #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) { static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *data) {
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_minimize); struct wb_view *view = wl_container_of(listener, view, request_minimize);
bool minimize_requested = toplevel->xdg_toplevel->requested.minimized; bool minimize_requested = view->xdg_toplevel->requested.minimized;
if (minimize_requested) { if (minimize_requested) {
toplevel->previous_geometry = toplevel->geometry; view->previous_position.height = view->current_position.height;
toplevel->geometry.y = -toplevel->geometry.height; view->current_position.y = 0 -
view->decoration_height * 2 - view->current_position.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);
} else { } else {
toplevel->geometry = toplevel->previous_geometry; view->current_position = view->previous_position;
}
} }
wlr_scene_node_set_position(&toplevel->scene_tree->node, static void begin_interactive(struct wb_view *view,
toplevel->geometry.x, toplevel->geometry.y);
}
static void begin_interactive(struct wb_toplevel *toplevel,
enum wb_cursor_mode mode, uint32_t edges) { enum wb_cursor_mode mode, uint32_t edges) {
/* This function sets up an interactive move or resize operation, where the /* This function sets up an interactive move or resize operation, where the
* compositor stops propagating pointer events to clients and instead * compositor stops propagating pointer events to clients and instead
* consumes them itself, to move or resize windows. */ * consumes them itself, to move or resize windows. */
struct wb_server *server = toplevel->server; struct wb_server *server = view->server;
server->grabbed_toplevel = toplevel; 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; server->cursor->cursor_mode = mode;
if (mode == WB_CURSOR_MOVE) { if (mode == WB_CURSOR_MOVE) {
server->grab_x = server->cursor->cursor->x - toplevel->geometry.x; server->grab_x = server->cursor->cursor->x - view->current_position.x;
server->grab_y = server->cursor->cursor->y - toplevel->geometry.y; server->grab_y = server->cursor->cursor->y - view->current_position.y;
} else if (mode == WB_CURSOR_RESIZE) { } 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; struct wlr_box geo_box;
wlr_xdg_surface_get_geometry(toplevel->xdg_toplevel->base, &geo_box); wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
#endif
double border_x = (toplevel->geometry.x + geo_box.x) + double border_x = (view->current_position.x + geo_box.x) + ((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
((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);
double border_y = (toplevel->geometry.y + geo_box.y) +
((edges & WLR_EDGE_BOTTOM) ? geo_box.height : 0);
server->grab_x = server->cursor->cursor->x - border_x; server->grab_x = server->cursor->cursor->x - border_x;
server->grab_y = server->cursor->cursor->y - border_y; server->grab_y = server->cursor->cursor->y - border_y;
server->grab_geo_box = geo_box; server->grab_geo_box = geo_box;
server->grab_geo_box.x += toplevel->geometry.x; server->grab_geo_box.x += view->current_position.x;
server->grab_geo_box.y += toplevel->geometry.y; server->grab_geo_box.y += view->current_position.y;
server->resize_edges = edges; 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 /* This event is raised when a client would like to begin an interactive
* move, typically because the user clicked on their client-side * move, typically because the user clicked on their client-side
* decorations. */ * decorations. */
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_move); struct wb_view *view = wl_container_of(listener, view, request_move);
begin_interactive(toplevel, WB_CURSOR_MOVE, 0); begin_interactive(view, WB_CURSOR_MOVE, 0);
} }
static void xdg_toplevel_request_resize( 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 * resize, typically because the user clicked on their client-side
* decorations. */ * decorations. */
struct wlr_xdg_toplevel_resize_event *event = data; struct wlr_xdg_toplevel_resize_event *event = data;
struct wb_toplevel *toplevel = wl_container_of(listener, toplevel, request_resize); struct wb_view *view = wl_container_of(listener, view, request_resize);
begin_interactive(toplevel, WB_CURSOR_RESIZE, event->edges); begin_interactive(view, 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);
} }
static void handle_new_popup(struct wl_listener *listener, void *data) { static void handle_new_popup(struct wl_listener *listener, void *data) {
struct wlr_xdg_popup *popup = 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( struct wlr_output *wlr_output = wlr_output_layout_output_at(output_layout,
toplevel->server->output_layout, view->current_position.x + popup->geometry.x,
toplevel->geometry.x + popup->current.geometry.x, view->current_position.y + popup->geometry.y);
toplevel->geometry.y + popup->current.geometry.y); struct wlr_box output_box;
#if WLR_CHECK_VERSION(0, 16, 0)
if (!wlr_output) { wlr_output_layout_get_box(output_layout, wlr_output, &output_box);
return; #else
} output_box = (*wlr_output_layout_get_box(output_layout, wlr_output));
struct wb_output *output = wlr_output->data; #endif
int top_margin = (toplevel->server->config) ?
toplevel->server->config->margins.top : 0;
struct wlr_box output_toplevel_box = { struct wlr_box output_toplevel_box = {
.x = output->geometry.x - toplevel->geometry.x, .x = output_box.x - view->current_position.x,
.y = output->geometry.y - toplevel->geometry.y, .y = output_box.y - view->current_position.y,
.width = output->geometry.width, .width = output_box.width,
.height = output->geometry.height - top_margin, .height = output_box.height,
}; };
wlr_xdg_popup_unconstrain_from_box(popup, &output_toplevel_box); wlr_xdg_popup_unconstrain_from_box(popup, &output_toplevel_box);
} }
static void handle_new_xdg_popup(struct wl_listener *listener, void *data) { static void handle_new_xdg_surface(struct wl_listener *listener, void *data) {
/* We must add xdg popups to the scene graph so they get rendered. The /* This event is raised when wlr_xdg_shell receives a new xdg surface from a
* wlroots scene graph provides a helper for this, but to use it we must * client, either a toplevel (application window) or popup. */
* 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) {
struct wb_server *server = struct wb_server *server =
wl_container_of(listener, server, new_xdg_toplevel); wl_container_of(listener, server, new_xdg_surface);
struct wlr_xdg_toplevel *xdg_toplevel = data; struct wlr_xdg_surface *xdg_surface = data;
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE) {
return;
}
/* Allocate a wb_toplevel for this toplevel */ /* Allocate a wb_view for this surface */
struct wb_toplevel *toplevel = struct wb_view *view =
calloc(1, sizeof(struct wb_toplevel)); calloc(1, sizeof(struct wb_view));
toplevel->server = server; view->server = server;
toplevel->xdg_toplevel = xdg_toplevel; view->xdg_toplevel = xdg_surface->toplevel;
#if !WLR_CHECK_VERSION(0, 16, 0)
toplevel->foreign_toplevel_handle = wlr_ext_foreign_toplevel_handle_v1_create( view->xdg_surface = xdg_surface;
server->foreign_toplevel_list, &toplevel->foreign_toplevel_state); #endif
/* Listen to the various events it can emit */ /* Listen to the various events it can emit */
toplevel->map.notify = xdg_toplevel_map; view->surface_commit.notify = xdg_surface_commit;
wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel->map); wl_signal_add(&xdg_surface->surface->events.commit, &view->surface_commit);
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);
toplevel->scene_tree = wlr_scene_xdg_surface_create( view->map.notify = xdg_surface_map;
&toplevel->server->scene->tree, xdg_toplevel->base); wl_signal_add(&xdg_surface->events.map, &view->map);
toplevel->scene_tree->node.data = toplevel; view->unmap.notify = xdg_surface_unmap;
xdg_toplevel->base->data = toplevel->scene_tree; 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; if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
wl_signal_add(&xdg_toplevel->events.request_fullscreen, &toplevel->request_fullscreen); struct wlr_xdg_toplevel *toplevel = view->xdg_toplevel;
toplevel->request_maximize.notify = xdg_toplevel_request_maximize; view->request_maximize.notify = xdg_toplevel_request_maximize;
wl_signal_add(&xdg_toplevel->events.request_maximize, &toplevel->request_maximize); wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize);
toplevel->request_minimize.notify = xdg_toplevel_request_minimize; view->request_minimize.notify = xdg_toplevel_request_minimize;
wl_signal_add(&xdg_toplevel->events.request_minimize, &toplevel->request_minimize); wl_signal_add(&toplevel->events.request_minimize, &view->request_minimize);
toplevel->request_move.notify = xdg_toplevel_request_move; view->request_move.notify = xdg_toplevel_request_move;
wl_signal_add(&xdg_toplevel->events.request_move, &toplevel->request_move); wl_signal_add(&toplevel->events.request_move, &view->request_move);
toplevel->request_resize.notify = xdg_toplevel_request_resize; view->request_resize.notify = xdg_toplevel_request_resize;
wl_signal_add(&xdg_toplevel->events.request_resize, &toplevel->request_resize); wl_signal_add(&toplevel->events.request_resize, &view->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);
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) { void init_xdg_shell(struct wb_server *server) {
/* xdg-shell version 3 */ server->xdg_shell = wlr_xdg_shell_create(server->wl_display);
server->xdg_shell = wlr_xdg_shell_create(server->wl_display, 3); server->new_xdg_surface.notify = handle_new_xdg_surface;
server->new_xdg_popup.notify = handle_new_xdg_popup; wl_signal_add(&server->xdg_shell->events.new_surface, &server->new_xdg_surface);
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);
} }