mirror of
https://github.com/wizbright/waybox.git
synced 2025-10-29 05:40:20 -04:00
Compare commits
72 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62dd0a5c8b | ||
|
|
557bb4ae05 | ||
|
|
4c6a762e12 | ||
|
|
b802cadffa | ||
|
|
ac626fc5d5 | ||
|
|
f6ebf16a95 | ||
|
|
606663a390 | ||
|
|
db79d83076 | ||
|
|
b2e686171f | ||
|
|
a6e9a04495 | ||
|
|
d4d033e685 | ||
|
|
d7f4d1001f | ||
|
|
80bc1d51cd | ||
|
|
73eb94d18a | ||
|
|
3e000a9087 | ||
|
|
19339ac6a0 | ||
|
|
88ce9ad366 | ||
|
|
4cf3ee8a05 | ||
|
|
0f9461c4c0 | ||
|
|
2643966144 | ||
|
|
3f0814fd56 | ||
|
|
ca2587f4f9 | ||
|
|
7a679988ac | ||
|
|
77652741b5 | ||
|
|
c9b187afc8 | ||
|
|
35b3e5af11 | ||
|
|
3a64d3955c | ||
|
|
f967bfae17 | ||
|
|
fb3c8eb152 | ||
|
|
cf2c1a97a7 | ||
|
|
b7e7cde0a5 | ||
|
|
fb3a845354 | ||
|
|
bce423cd72 | ||
|
|
0294b25f27 | ||
|
|
fa36852a58 | ||
|
|
b274485c9c | ||
|
|
b5f4055904 | ||
|
|
3687099182 | ||
|
|
d139b41259 | ||
|
|
ead6648438 | ||
|
|
ae42d9d2f7 | ||
|
|
bceafa5b6b | ||
|
|
7fb889d171 | ||
|
|
2b38536dec | ||
|
|
fd0c5b04d3 | ||
|
|
6dc905d758 | ||
|
|
e6bac6d366 | ||
|
|
f50ab866f9 | ||
|
|
4eb4536b28 | ||
|
|
3f2a6f7b6c | ||
|
|
8fa589a132 | ||
|
|
e938552d15 | ||
|
|
0df03fcd9d | ||
|
|
bf0f9215dc | ||
|
|
e4b603a082 | ||
|
|
6c6d0214b4 | ||
|
|
b4a05ca65b | ||
|
|
3319f82249 | ||
|
|
5122dbf35f | ||
|
|
00d8451178 | ||
|
|
0c2f744dbf | ||
|
|
31d0ef57e5 | ||
|
|
4f0f564e27 | ||
|
|
18950eb844 | ||
|
|
9fa7060dd4 | ||
|
|
5e95882436 | ||
|
|
df38ee39e0 | ||
|
|
553096a611 | ||
|
|
ac01aefe32 | ||
|
|
579a2d2084 | ||
|
|
5a3ac6055d | ||
|
|
d7b799ab80 |
82 changed files with 2174 additions and 1477 deletions
19
.build.yml
19
.build.yml
|
|
@ -3,20 +3,27 @@
|
|||
#
|
||||
image: archlinux
|
||||
packages:
|
||||
- meson
|
||||
- wayland
|
||||
- wayland-protocols
|
||||
- clang
|
||||
- gcc
|
||||
- libevdev
|
||||
- libinput
|
||||
- libxkbcommon
|
||||
- libxml2
|
||||
- wlroots
|
||||
- meson
|
||||
- wayland
|
||||
- wayland-protocols
|
||||
- wlroots-git
|
||||
- xorg-server-xwayland
|
||||
sources:
|
||||
- https://github.com/wizbright/waybox
|
||||
tasks:
|
||||
- setup: |
|
||||
cd waybox
|
||||
meson build
|
||||
CC=gcc meson setup build-gcc
|
||||
- build: |
|
||||
cd waybox
|
||||
ninja -C build
|
||||
ninja -C build-gcc
|
||||
- clang: |
|
||||
cd waybox
|
||||
CC=clang meson setup build-clang
|
||||
ninja -C build-clang
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ block_comment_start = /*
|
|||
block_comment_end = */
|
||||
|
||||
curly_bracket_next_line = false
|
||||
max_line_length = 80
|
||||
max_line_length = 100
|
||||
spaces_around_brackets = outside
|
||||
spaces_around_operators = true
|
||||
|
||||
|
|
|
|||
20
.github/workflows/build.yml
vendored
20
.github/workflows/build.yml
vendored
|
|
@ -12,18 +12,18 @@ on: [push, pull_request]
|
|||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: archlinux:base-devel
|
||||
container: alpine:edge
|
||||
steps:
|
||||
- name: packages
|
||||
run: |
|
||||
pacman-key --init
|
||||
pacman -Syu --noconfirm
|
||||
pacman -S --noconfirm git meson libxkbcommon libinput libxml2 wayland wayland-protocols wlroots xorg-server-xwayland
|
||||
# actions/checkout@v2 clones the repository
|
||||
- uses: actions/checkout@v2
|
||||
- name: setup
|
||||
apk add clang gcc libevdev-dev libinput-dev libxkbcommon-dev libxml2-dev meson musl-dev wayland-dev wayland-protocols wlroots wlroots-dev xwayland
|
||||
# actions/checkout@v4 clones the repository
|
||||
- uses: actions/checkout@v4
|
||||
- name: build-gcc
|
||||
run: |
|
||||
meson build
|
||||
- name: build
|
||||
CC=gcc meson setup build-gcc
|
||||
ninja -C build-gcc
|
||||
- name: build-clang
|
||||
run: |
|
||||
ninja -C build
|
||||
CC=clang meson setup build-clang
|
||||
ninja -C build-clang
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ If you already have your own pull request habits, feel free to use them. If you
|
|||
don't, however, allow me to make a suggestion: feature branches pulled from
|
||||
upstream. Try this:
|
||||
|
||||
1. Fork waybox
|
||||
1. Fork Waybox
|
||||
2. `git clone https://github.com/username/waybox && cd waybox`
|
||||
3. `git remote add upstream https://github.com/wizbright/waybox`
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ process is:
|
|||
|
||||
## Style Reference
|
||||
|
||||
waybox is written in C with a style similar to the [kernel
|
||||
Waybox is written in C with a style similar to the [kernel
|
||||
style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but
|
||||
with a few notable differences.
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ Try to break the line in the place which you think is the most appropriate.
|
|||
|
||||
### Line Length
|
||||
|
||||
Try to keep your lines under 80 columns, but you can go up to 100 if it
|
||||
Try to keep your lines under 100 columns, but you can break this rule if it
|
||||
improves readability. Don't break lines indiscriminately, try to find nice
|
||||
breaking points so your code is easy to read.
|
||||
|
||||
|
|
|
|||
45
README.md
45
README.md
|
|
@ -1,8 +1,10 @@
|
|||
# Waybox
|
||||
An Openbox clone on Wayland (WIP)
|
||||
|
||||
A \*box-style (minimalist) Wayland compositor modeled largely on Openbox (WIP)
|
||||
|
||||
### 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
|
||||
|
||||
|
|
@ -11,22 +13,47 @@ contributing.](https://github.com/wizbright/waybox/blob/master/CONTRIBUTING.md)
|
|||
|
||||
### Dependencies
|
||||
|
||||
* [Meson](https://mesonbuild.com/)
|
||||
* [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots/)
|
||||
* [libxml2](http://xmlsoft.org/)
|
||||
* [Meson](https://mesonbuild.com/) or [muon](http://muon.build)
|
||||
* [Wayland](https://wayland.freedesktop.org/)
|
||||
* [libevdev](https://www.freedesktop.org/wiki/Software/libevdev/)
|
||||
* [libinput](http://www.freedesktop.org/wiki/Software/libinput)
|
||||
* [libxml2](http://xmlsoft.org/)
|
||||
* [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots/)
|
||||
* [xkbcommon](https://xkbcommon.org/)
|
||||
|
||||
### Build instructions
|
||||
|
||||
```
|
||||
meson build
|
||||
meson setup build
|
||||
cd build
|
||||
ninja
|
||||
```
|
||||
|
||||
After that, you should have an executable as waybox/waybox
|
||||
|
||||
For those who don't want to use a Python-based build system, it's also possible
|
||||
to use muon instead of Meson.
|
||||
|
||||
### Screenshots
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

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