Merge branch 'master' into indonesian_translation

This commit is contained in:
Nicholas Sebastian Husin 2019-06-04 23:38:01 -05:00 committed by GitHub
commit 418d27c41d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
163 changed files with 7510 additions and 3668 deletions

View file

@ -12,7 +12,6 @@ packages:
- meson - meson
- pango-dev - pango-dev
- pixman-dev - pixman-dev
- scdoc
- wayland-dev - wayland-dev
- wayland-protocols - wayland-protocols
- xcb-util-image-dev - xcb-util-image-dev
@ -20,7 +19,12 @@ packages:
sources: sources:
- https://github.com/swaywm/sway - https://github.com/swaywm/sway
- https://github.com/swaywm/wlroots - https://github.com/swaywm/wlroots
- https://git.sr.ht/~sircmpwn/scdoc
tasks: tasks:
- scdoc: |
cd scdoc
make PREFIX=/usr
sudo make install PREFIX=/usr
- wlroots: | - wlroots: |
cd wlroots cd wlroots
meson --prefix=/usr build -Drootston=false -Dexamples=false meson --prefix=/usr build -Drootston=false -Dexamples=false
@ -28,7 +32,7 @@ tasks:
sudo ninja -C build install sudo ninja -C build install
- setup: | - setup: |
cd sway cd sway
meson build meson build -Dauto_features=enabled -Dtray=disabled
- build: | - build: |
cd sway cd sway
ninja -C build ninja -C build

View file

@ -8,7 +8,6 @@ packages:
- libxkbcommon - libxkbcommon
- meson - meson
- pango - pango
- scdoc
- wayland - wayland
- wayland-protocols - wayland-protocols
- xcb-util-image - xcb-util-image
@ -16,7 +15,12 @@ packages:
sources: sources:
- https://github.com/swaywm/sway - https://github.com/swaywm/sway
- https://github.com/swaywm/wlroots - https://github.com/swaywm/wlroots
- https://git.sr.ht/~sircmpwn/scdoc
tasks: tasks:
- scdoc: |
cd scdoc
make PREFIX=/usr
sudo make install PREFIX=/usr
- wlroots: | - wlroots: |
cd wlroots cd wlroots
meson --prefix=/usr build -Drootston=false -Dexamples=false meson --prefix=/usr build -Drootston=false -Dexamples=false
@ -24,7 +28,7 @@ tasks:
sudo ninja -C build install sudo ninja -C build install
- setup: | - setup: |
cd sway cd sway
meson build meson build -Dauto_features=enabled
- build: | - build: |
cd sway cd sway
ninja -C build ninja -C build

View file

@ -8,7 +8,6 @@ packages:
- graphics/gdk-pixbuf2 - graphics/gdk-pixbuf2
- graphics/wayland - graphics/wayland
- graphics/wayland-protocols - graphics/wayland-protocols
- textproc/scdoc
- x11-toolkits/pango - x11-toolkits/pango
- x11/libxcb - x11/libxcb
- x11/libxkbcommon - x11/libxkbcommon
@ -22,10 +21,17 @@ packages:
- x11/libX11 - x11/libX11
- x11/pixman - x11/pixman
- x11/xcb-util-wm - x11/xcb-util-wm
# scdoc dependencies
- devel/gmake
sources: sources:
- https://github.com/swaywm/sway - https://github.com/swaywm/sway
- https://github.com/swaywm/wlroots - https://github.com/swaywm/wlroots
- https://git.sr.ht/~sircmpwn/scdoc
tasks: tasks:
- scdoc: |
cd scdoc
gmake PREFIX=/usr/local
sudo gmake install PREFIX=/usr/local
- fixup_epoll: | - fixup_epoll: |
cat << 'EOF' | sudo tee /usr/local/libdata/pkgconfig/epoll-shim.pc cat << 'EOF' | sudo tee /usr/local/libdata/pkgconfig/epoll-shim.pc
prefix=/usr/local prefix=/usr/local

4
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,4 @@
# These are supported funding model platforms
patreon: sircmpwn
custom: https://drewdevault.com/donate

View file

@ -5,6 +5,8 @@ If you are using the nvidia proprietary driver for any reason, you have two choi
If `lsmod | grep nvidia | wc -l` shows anything other than zero, your bug report is not welcome here. If `lsmod | grep nvidia | wc -l` shows anything other than zero, your bug report is not welcome here.
Additionally, problems with Firefox are almost certainly Firefox bugs, not sway bugs. Start by submitting your issue to the Firefox bugzilla and come back here only after they confirm otherwise.
Otherwise, please include the following four components in your bug report: sway version, debug log, configuration (if applicable), and an explanation of steps taken to reproduce the issue. If sway crashes, also include a stack trace. Otherwise, please include the following four components in your bug report: sway version, debug log, configuration (if applicable), and an explanation of steps taken to reproduce the issue. If sway crashes, also include a stack trace.
Obtain your version like so: Obtain your version like so:

View file

@ -1,78 +0,0 @@
# sway
Sway е в процес на разработка, съвместим с i3,
[Wayland](http://wayland.freedesktop.org/) композитор. Прочетете
[FAQ](https://github.com/swaywm/sway/wiki). Присъединете се в [IRC
канала](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway на
irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png)
Ако желаете, може да дарите на [Patreon страницата на автора](https://patreon.com/sircmpwn), което ще помогне за цялостното здраве и развитие на проекта.
## Помощ
Ако имате нужда от помощ - влезте в IRC канала. Ако не ви отговорят в IRC или желаете кореспонденция по и-мейл - [fokditkak](mailto:martin.kalchev@mail.ru)
може да отговаря на основни въпроси на български език.
## Подпис
Версии подписани с ключ [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
и публикувани в [GitHub](https://github.com/swaywm/sway/releases).
## Инсталация
### От пакети
Sway съществува в репотата (хранилищата) на много дистрибуции. Пробвайте да го инсталирате със съответния пакетен мениджър на вашата дистрибуция.
В случай, че имате проблем погледнете [тази страница](https://github.com/swaywm/sway/wiki/Unsupported-packages) за помощ.
Ако желаете да пакетирате Sway за вашата дистрибуция влезте в IRC канала
или пратете и-мейл на [sir@cmpwn.com](mailto:sir@cmpwn.com) за съвет как да го направите.
### Компилиране от сорс-код
Инсталирайте следните пакети:
* meson
* [wlc](https://github.com/Cloudef/wlc)
* wayland
* xwayland
* libinput >= 1.6.0
* libcap
* pcre
* json-c >= 0.13
* pango
* cairo
* gdk-pixbuf2 *
* dbus >= 1.10 **
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (Нужен за man страници)
* git
_\*Нужен само за swaybar, swaybg_
_\*\*Нужен само за tray_
Изпълнете следните команди:
meson build
ninja -C build
sudo ninja -C build install
Ако имате logind:
sudo setcap "cap_sys_ptrace,cap_sys_tty_config=eip" /usr/local/bin/sway
Иначе:
sudo chmod a+s /usr/local/bin/sway
## Настройка
Ако имте съшествуващa конфигурация от i3, просто я копирайте в `/.config/sway/config` и би трябвало безпроблемно да работи.
В противен случай, поставете примерната конфигурация, която би трябвало да се намиреа в `/etc/sway/config`.
Напишете `man 5 sway` за повече информация.
## Пускане
Напишете 'sway' в терминала (TTY). Някои дисплей мениджъри (display managers) може и да работят, но като цяло не са поддържани от Sway.

View file

@ -1,84 +1,51 @@
# sway # Sway
Sway ist ein [i3](https://i3wm.org/)-kompatibler [Wayland](http://wayland.freedesktop.org/)-Compositor. Lies die [FAQ](https://github.com/swaywm/sway/wiki). Tritt dem [IRC Channel](http://webchat.freenode.net/?channels=sway&uio=d4) bei (#sway on irc.freenode.net; Englisch).
Der Fortschritt dieser Übersetzung kann [hier](https://github.com/swaywm/sway/issues/1318) Falls du die Entwicklung von Sway unterstützen möchtest, kannst du das auf [SirCmpwn's Patreon Seite](https://patreon.com/sircmpwn) machen.
eingesehen werden.
Sway ist ein i3-kompatibler ## Signaturen
[Wayland](http://wayland.freedesktop.org/)-Kompositor. Lies die Jedes Release wird mit dem PGP-Schlüssel [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) signiert und auf GitHub veröffentlicht.
[FAQ](https://github.com/swaywm/sway/wiki#faq). Tritt dem
[IRC-Channel](http://webchat.freenode.net/?channels=sway&uio=d4) bei (#sway in
irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png)
Falls du die Entwicklung von Sway unterstützen möchtest, kannst du das auf der
[Patreon-Seite](https://patreon.com/sircmpwn) tun, oder indem du zu
[Entwicklungsprämien](https://github.com/swaywm/sway/issues/986)
bestimmter Features beiträgst. Jeder ist dazu eingeladen, eine Prämie in Anspruch
zu nehmen oder für gewünschte Features bereitzustellen. Patreon ist eher dafür
gedacht, Sways Wartung und das Projekt generell zu unterstützen.
## Deutscher Support
refacto(UTC+2) bietet Support im IRC (unter dem Namen azarus) und auf Github an.
ParadoxSpiral(UTC+2) bietet Support im IRC und auf Github an.
## Releasesignaturen
Neue Versionen werden mit
[B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
signiert und [auf Github](https://github.com/swaywm/sway/releases) veröffentlicht.
## Installation ## Installation
### Mit der Paketverwaltung
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Das Paket sollte "sway" heißen. Falls es kein solches Paket gibt, kannst du im [Wiki](https://github.com/swaywm/sway/wiki/Unsupported-packages) (Englisch) nach mehr Informationen bezüglich deiner Distribution suchen.
### Als Paket Falls du sway für deine eigene Distribution als Paket bereitstellen möchtest, solltest du die Entwickler per IRC oder E-Mail (sir@cmpwn.com) kontaktieren.
Sway ist in vielen Distributionen verfügbar: versuche einfach, das „sway“-Paket ### Quellcode selbst kompilieren
zu installieren. Falls es nicht vorhanden ist, schaue dir
[diese Wikiseite](https://github.com/swaywm/sway/wiki/Unsupported-packages) für
distributionsspezifische Installationsinformationen an.
Wenn du Interesse hast, Sway für deine Distribution als Paket bereitzustellen, sway benötigt die folgenden Pakete:
schaue im IRC-Channel vorbei oder schreibe eine EMail an sir@cmpwn.com (nur englischsprachig).
### Kompilieren des Quellcodes * meson\*
* [wlroots](https://github.com/swaywm/wlroots)
Abhängigkeiten:
* meson
* [wlc](https://github.com/Cloudef/wlc)
* wayland * wayland
* xwayland * wayland-protocols\*
* libinput >= 1.6.0
* libcap
* pcre * pcre
* json-c >= 0.13 * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 * * gdk-pixbuf2 (Optional, wird für das Benachrichtigungsfeld (System Tray) benötigt)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (erforderlich für man pages) * [scdoc](https://git.sr.ht/~sircmpwn/scdoc)\* (Optional, wird für die Dokumentation (Man Pages) benötigt)
* git * git\*
_\*Nur erforderlich für swaybar, swaybg_ _\*Werden nur während des Kompilierens benötigt_
Führe diese Befehle aus: Führe die folgenden Befehle aus
meson build meson build
ninja -C build ninja -C build
sudo ninja -C build install sudo ninja -C build install
In Systemen ohne logind musst du `sway` das suid-Flag geben: Falls dein System nicht logind benutzt, musst du sway noch die passenden Berechtigungen geben:
sudo chmod a+s /usr/local/bin/sway sudo chmod a+s /usr/local/bin/sway
Sway läuft nur in der Startphase mit Root-Rechten.
## Konfiguration ## Konfiguration
Wenn du schon i3 benutzt, kopiere einfach deine i3 Konfiguration nach Falls du von i3 migrierst, kannst du deine Konfigurationsdatei nach `~/.config/sway/config` kopieren, und die Einstellungen sollten ohne Weiteres funktionieren. Ansonsten kannst du die Beispielkonfiguration, die normalerweise in `/etc/sway/config` liegt, nach `~/.config/sway/config` kopieren. Die Dokumentation zur Konfigurationsdatei findest du in `man 5 sway`.
`~/.config/sway/config`. Falls nicht, kannst du die Beispielkonfiguration
benutzen. Die befindet sich normalerweise unter `/etc/sway/config`.
Um mehr Informationen über die Konfiguration zu erhalten, führe `man 5 sway` aus.
## Verwendung ## Sway Starten
Sway kann einfach mit dem Befehl `sway` vom TTY gestartet werden.
Führe `sway` von einem TTY aus. Manche Displaymanager könnten funktionieren, werden aber Display-Manager werden nicht offiziell unterstützt. Es gibt aber durchaus einige, die mit Sway funktionieren. (z.B. gdm)
nicht von Sway unterstützt (gdm scheint relativ gut zu funktionieren).

View file

@ -1,73 +0,0 @@
# sway
Sway είναι ένας **υπό ανάπτυξη** [Wayland](http://wayland.freedesktop.org/) διαχειριστής παραθύρων συμβατός με τον αντίστοιχο διαχειριστή παραθύρων i3 για τον X11.
Διαβάστε τις [Συνήθεις Ερωτήσεις](https://github.com/swaywm/sway/wiki). Συνδεθείτε στο [κανάλι μας στο IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway στο
irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png)
### Η ελληνική μετάφραση ενδέχεται να είναι ελλειπής!
Η τεκμηρίωση του Sway ξεκινάει πάντα από τα Αγγλικά και στη συνέχεια μεταφράζεται, γι' αυτό ενδέχεται τα ελληνικά κείμενα να μην είναι πάντα διαθέσιμα ή ενημερωμένα.
Μπορείτε πάντα να υποδεικνύετε σφάλματα και να κάνετε ερωτήσεις σχετικά με τις ελληνικές μεταφράσεις στο [IRC](http://webchat.freenode.net/?channels=sway&uio=d4).
To username μου στο Freenode είναι kon14 και θα με βρείτε στο IRC σε ώρες GMT+2.
Δείτε [εδώ](https://github.com/swaywm/sway/issues/1318) πως μπορείτε και οι ίδιοι να βοηθήσετε στη μετάφραση του Sway.
Αν θέλετε να υποστηρίξετε την ανάπτυξη του Sway, μπορείτε να συμβάλετε στη [σελίδα Patreon του SirCmpwn](https://patreon.com/sircmpwn)
ή να επιδοτήσετε τις [αμοιβές](https://github.com/swaywm/sway/issues/986) για υλοποίηση συγκεκριμένων δυνατοτήτων.
Ο καθένας μπορεί να διεκδικήσει μια αμοιβή και μπορείτε να προσθέσετε μια αμοιβή για οποιαδήποτε δυνατότητα θέλετε.
Προτιμήστε το Patreon αν θέλετε να υποστήριξετε την συνολική ανάπτυξη και διατήρηση του Sway.
## Υπογραφές Έκδοσης
Οι εκδόσεις υπογράφονται ως [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) και δημοσιεύονται στο [GitHub](https://github.com/swaywm/sway/releases).
## Εγκατάσταση
### Από Πακέτα
Ο Sway είναι διαθέσιμος για εγκατάσταση μέσω του διαχειριστή πακέτων σε διάφορες διανομές.
Δοκιμάστε να εγκαταστήσετε το πακέτο ονομαζόμενο ως "sway" για τη δική σας.
Αν δεν είναι διαθέσιμο, μεταβείτε στη [σελίδα τεκμηρίωσης](https://github.com/swaywm/sway/wiki/Unsupported-packages) για πληροφορίες σχετικά με την εγκατάσταση για τη διανομή σας.
Αν ενδιαφέρεστε να δημιουργήσετε ένα πακέτο του Sway για τη διανομή σας, περάστε απο το κανάλι μας στο IRC ή στείλτε ένα email, στα **Αγγλικά**, στο sir@cmpwn.com για συμβουλές.
### Compile από Πηγαίο Κώδικα
Εγκατάσταση εξαρτήσεων:
* meson
* [wlc](https://github.com/Cloudef/wlc)
* wayland
* xwayland
* libinput >= 1.6.0
* libcap
* pcre
* json-c >= 0.13
* pango
* cairo
* gdk-pixbuf2 *
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (required for man pages)
* git
_\*Απαιτείται μόνο για swaybar, swaybg_
Εκτελέστε αυτές τις εντολές:
meson build
ninja -C build
sudo ninja -C build install
Σε συστήματα χωρίς logind, χρειάζεται να θέσετε το suid bit στο εκτελέσιμο αρχείο:
sudo chmod a+s /usr/local/bin/sway
## Παραμετροποίηση
Αν είστε ήδη χρήστης του i3, τότε απλά αντιγράψτε το αρχείο ρυθμίσεων σας στο `~/.config/sway/config` και θα είναι όλα έτοιμα για χρήση.
Διαφορετικά, αντιγράψτε το συνοδευόμενο δείγμα ρυθμίσεων, το οποίο θα βρείτε τυπικά στο `/etc/sway/config`, και μεταφέρετε το στην τοποθεσία `~/.config/sway/config`. Εκτελέστε `man 5 sway` για πληροφορίες σχετικά με την παραμετροποίηση των ρυθμίσεων σας.
## Εκτέλεση
Εκτελέστε `sway` απο ένα TTY. Μερικοί γραφικοί διαχειριστές σύνδεσης ενδέχεται να δουλεύουν, αλλά δεν υποστηρίζονται επίσημα (ο GDM "προτείνεται" ως λειτουργικός).

View file

@ -1,9 +1,6 @@
# sway # sway
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) - sway es un compositor de [Wayland](http://wayland.freedesktop.org/) compatible con [i3](https://i3wm.org/).
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--)
sway es un compositor de [Wayland](http://wayland.freedesktop.org/) compatible con i3.
Lea el [FAQ](https://github.com/swaywm/sway/wiki). Únase al [canal de IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on Lea el [FAQ](https://github.com/swaywm/sway/wiki). Únase al [canal de IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on
irc.freenode.net). irc.freenode.net).
@ -37,14 +34,12 @@ Instale las dependencias:
* json-c * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 \*\* * gdk-pixbuf2 (optional: system tray)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) >= 1.8.1 (optional: man pages) \* * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \*
* git \* * git \*
_\*Compile-time dep_ _\*Compile-time dep_
_\*\*opcional: necesario para swaybg_
Desde su consola, ejecute las órdenes: Desde su consola, ejecute las órdenes:
meson build meson build

View file

@ -1,19 +1,13 @@
# sway # sway
Sway est un compositeur [Wayland](http://wayland.freedesktop.org/) compatible Sway est un compositeur [Wayland](http://wayland.freedesktop.org/) compatible
avec i3, **en cours de développement**. Lisez la avec [i3](https://i3wm.org/), **en cours de développement**. Lisez la
[FAQ](https://github.com/swaywm/sway/wiki). Rejoignez le [canal [FAQ](https://github.com/swaywm/sway/wiki). Rejoignez le [canal
IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway sur IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway sur
irc.freenode.net). irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png) Si vous souhaitez soutenir le développement de Sway, vous pouvez contribuer à [la page
Patreon de SirCmpwn](https://patreon.com/sircmpwn).
Si vous souhaitez soutenir le développement de Sway, vous pouvez contribuer à [ma page
Patreon](https://patreon.com/sircmpwn) ou aux [primes](https://github.com/swaywm/sway/issues/986)
pour des fonctionnalités spécifiques.
Tout le monde est invité à réclamer une prime et vous pouvez donner une prime pour n'importe quelle
fonctionnalité souhaitée. Patreon est plus utile pour supporter l'état général et la
maintenance de Sway.
## Aide en français ## Aide en français
@ -39,21 +33,19 @@ IRC ou envoyez un e-mail à sir@cmpwn.com (en anglais seulement) pour des consei
Installez les dépendances : Installez les dépendances :
* meson * meson \*
* [wlc](https://github.com/Cloudef/wlc) * [wlroots](https://github.com/swaywm/wlroots)
* wayland * wayland
* xwayland * wayland-protocols \*
* libinput >= 1.6.0
* libcap
* pcre * pcre
* json-c >= 0.13 * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 * * gdk-pixbuf2 (optionnel: system tray)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (requis pour les pages man) * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optionnel: requis pour les pages man) \*
* git * git \*
_\*Uniquement requis pour swaybar, swaybg_ _\*Requis uniquement pour la compilation_
Exécutez ces commandes : Exécutez ces commandes :
@ -65,6 +57,8 @@ Sur les systèmes sans logind, vous devez suid le binaire de sway :
sudo chmod a+s /usr/local/bin/sway sudo chmod a+s /usr/local/bin/sway
Sway se débarassera des permissions *root* peu de temps après le démarrage.
## Configuration ## Configuration
Si vous utilisez déjà i3, copiez votre configuration i3 à `~/.config/sway/config` et Si vous utilisez déjà i3, copiez votre configuration i3 à `~/.config/sway/config` et
@ -72,10 +66,6 @@ cela va fonctionner. Sinon, copiez l'exemple de fichier de configuration à
`~/.config/sway/config`. Il se trouve généralement dans `/etc/sway/config`. `~/.config/sway/config`. Il se trouve généralement dans `/etc/sway/config`.
Exécutez `man 5 sway` pour l'information sur la configuration. Exécutez `man 5 sway` pour l'information sur la configuration.
Mes propres dotfiles sont disponibles [ici](https://git.sr.ht/~sircmpwn/dotfiles) si
vous voulez un peu d'inspiration. Je vous recommande aussi de consulter le
[wiki](https://github.com/swaywm/sway/wiki).
## Exécution ## Exécution
Exécutez `sway` à partir d'un TTY. Certains gestionnaires d'affichage peuvent fonctionner, Exécutez `sway` à partir d'un TTY. Certains gestionnaires d'affichage peuvent fonctionner,

View file

@ -1,79 +0,0 @@
# sway
Sway è un compositor [Wayland](http://wayland.freedesktop.org/) **in via di
sviluppo** compatibile con i3. Leggi le [FAQ (in
Inglese)](https://github.com/swaywm/sway/wiki). Unisciti al [canale IRC (in
Inglese)](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on
irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png)
Se vuoi supportare lo sviluppo di Sway, puoi contribuire dalla
[pagina Patreon di SirCmpwn's](https://patreon.com/sircmpwn) o con dei
[premi](https://github.com/swaywm/sway/issues/986) per finanziare lo sviluppo
di funzionalità specifiche.
Chiunque è libero di reclamare un premio o crearne uno per qualsiasi funzionalità.
Patreon è più utile al supporto e alla manutenzione generale di Sway.
## Supporto italiano
syknro offre supporto in Italiano su GitHub nel fuso orario UTC+2.
Questa traduzione non è ancora completa. [Clicca qui per maggiori informazioni](https://github.com/swaywm/sway/issues/1318)
## Firme digitali
Le release sono firmate con [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
e pubblicate [su GitHub](https://github.com/swaywm/sway/releases).
## Installazione
### Dai pacchetti
Sway è disponibile in molte distribuzioni. Prova a installare il pacchetto "sway" per la tua.
Se non funziona, controlla [questa pagina (in Inglese)](https://github.com/swaywm/sway/wiki/Unsupported-packages)
per informazioni sull'installazione per le tue distribuzioni.
Se vuoi creare un pacchetto per la tua distribuzione, passa dall'IRC o manda un email (in Inglese)
a sir@cmpwn.com.
### Compilando il codice sorgente
Installa queste dipendenze:
* meson
* [wlc](https://github.com/Cloudef/wlc)
* wayland
* xwayland
* libinput >= 1.6.0
* libcap
* pcre
* json-c >= 0.13
* pango
* cairo
* gdk-pixbuf2 *
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (rrichiesto per man pages)
* git
_\*Richiesto solo per swaybar, swaybg_
Esegui questi comandi:
meson build
ninja -C build
sudo ninja -C build install
Per i sistemi senza logind, devi cambiare i permessi (suid):
sudo chmod a+s /usr/local/bin/sway
## Configurazione
Se usi i3, copia la tua configurazione in `~/.config/sway/config` e
funzionerà direttamente.
Altrimenti copia in `~/.config/sway/config` la configurazione di esempio,
solitamente si trova in `/etc/sway/config`.
Esegui `man 5 sway` per informazioni sulla configurazione.
## Esecuzione
Esegui `sway` da un TTY. Qualche display manager potrebbe funzionare ma non sono
ufficialmente supportati da Sway (gdm è risaputo funzionare abbastanza bene).

View file

@ -1,6 +1,6 @@
# sway # sway
Swayはi3互換な[Wayland](http://wayland.freedesktop.org/)コンポジタです。 Swayは[i3](https://i3wm.org/)互換な[Wayland](http://wayland.freedesktop.org/)コンポジタです。
[FAQ](https://github.com/swaywm/sway/wiki)も合わせてご覧ください。 [FAQ](https://github.com/swaywm/sway/wiki)も合わせてご覧ください。
[IRC チャンネル](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on irc.freenode.net)もあります。 [IRC チャンネル](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on irc.freenode.net)もあります。
@ -36,14 +36,12 @@ Swayは沢山のディストリビューションで提供されています。"
* json-c * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 \*\* * gdk-pixbuf2 (システムイコンで必要です)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (manで必要です) \* * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (manで必要です) \*
* git \* * git \*
_\*コンパイルの時_ _\*コンパイルの時_
_\*\*オプション: swaybgでのみ必要です_
次のコマンドを実行してください: 次のコマンドを実行してください:
meson build meson build

View file

@ -1,11 +1,10 @@
# sway # sway
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Indonesian](https://github.com/swaywm/sway/blob/master/README.id.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) -
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--) -
[Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--)
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--) - [Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--) - [中文-简体](https://github.com/swaywm/sway/blob/master/README.zh-CN.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Indonesian](https://github.com/swaywm/sway/blob/master/README.id.md#sway--)
sway is an [i3](https://i3wm.org/)-compatible [Wayland](http://wayland.freedesktop.org/) compositor.
sway is an i3-compatible [Wayland](http://wayland.freedesktop.org/) compositor.
Read the [FAQ](https://github.com/swaywm/sway/wiki). Join the [IRC Read the [FAQ](https://github.com/swaywm/sway/wiki). Join the [IRC
channel](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on channel](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on
irc.freenode.net). irc.freenode.net).
@ -41,14 +40,12 @@ Install dependencies:
* json-c * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 \*\* * gdk-pixbuf2 (optional: system tray)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) >= 1.8.1 (optional: man pages) \* * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \*
* git \* * git \*
_\*Compile-time dep_ _\*Compile-time dep_
_\*\*optional: required for swaybg_
Run these commands: Run these commands:
meson build meson build

View file

@ -1,10 +1,6 @@
# sway # sway
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) - sway jest kompozytorem [Wayland](http://wayland.freedesktop.org/) kompatybilnym z [i3](https://i3wm.org/).
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--) -
[Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--)
sway jest kompozytorem [Wayland](http://wayland.freedesktop.org/) kompatybilnym z i3.
Przeczytaj [FAQ](https://github.com/swaywm/sway/wiki). Dołącz do [kanału IRC](http://webchat.freenode.net/?channels=sway&uio=d4) Przeczytaj [FAQ](https://github.com/swaywm/sway/wiki). Dołącz do [kanału IRC](http://webchat.freenode.net/?channels=sway&uio=d4)
(#sway na irc.freenode.net). (#sway na irc.freenode.net).
@ -38,14 +34,12 @@ Zainstaluj zależności:
* json-c * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 \*\* * gdk-pixbuf2 (opcjonalnie: system tray)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) >= 1.8.1 (opcjonalnie: strony pomocy man) \* * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (opcjonalnie: strony pomocy man) \*
* git \* * git \*
_\*zależności kompilacji_ _\*zależności kompilacji_
_\*\*opcjonalnie: wymagane dla swaybg_
Wykonaj następujące polecenia: Wykonaj następujące polecenia:
meson build meson build

View file

@ -1,91 +0,0 @@
# sway
Sway é um compositor [Wayland](http://wayland.freedesktop.org/) compatível com o
i3. Leia o [FAQ](https://github.com/swaywm/sway/wiki). Participe do [canal
IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway no
irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png)
Se você deseja apoiar o desenvolvimento do Sway, você pode contribuir com o
SirCmpwn em sua [página no Patreon](https://patreon.com/sircmpwn) ou você
pode colaborar com [premiações](https://github.com/swaywm/sway/issues/986)
para recursos específicos. Qualquer um pode requerer uma premiação ao implementar
o recurso especificado, e você pode criar uma premiação para qualquer recurso que desejar.
O Patreon é melhor direcionado para a manutenção a longo prazo do Sway.
## Ajuda em português
No momento, o suporte em português no canal do IRC **não está ativo**. Em caso de problemas,
use as [*issues*](https://github.com/swaywm/sway/issues/) do Github (*em inglês*).
A tradução para português é um *trabalho em progresso*, no momento. Caso encontre algum erro
ou queira colaborar com a tradução, visite
[essa *issue*](https://github.com/swaywm/sway/issues/1318) para mais informações e não
exite em enviar quaisquer correções necessárias.
## Assinaturas dos *Releases*
*Releases* são assinadas com a chave
[B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
e publicadas [no GitHub](https://github.com/swaywm/sway/releases).
## Instalação
### A partir de pacotes
Sway está disponível em várias distribuições. Verifique se o pacote "sway" está
disponível a partir do gerenciador de pacotes da sua distribuição. Caso não esteja,
procure por informações sobre como instalar o Sway na sua distribuição
[aqui](https://github.com/swaywm/sway/wiki/Unsupported-packages).
Se você está interessado em manter um pacote do Sway para a sua distribuição,
visite o canal no IRC ou mande um email para sir@cmpwn.com (*em inglês*).
### A partir do código-fonte
Antes de iniciar a compilação, instale as dependências:
* meson
* [wlc](https://github.com/Cloudef/wlc)
* wayland
* xwayland
* libinput >= 1.6.0
* libcap
* pcre
* json-c >= 0.13
* pango
* cairo
* gdk-pixbuf2 *
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (man pages)
* git
_\*Dependência apenas de swaybar, swaybg_
Para compilar, execute estes comandos:
meson build
ninja -C build
sudo ninja -C build install
Em sistemas com logind, configure as seguintes capacidades para o arquivo binário:
sudo setcap "cap_sys_ptrace,cap_sys_tty_config=eip" /usr/local/bin/sway
Em sistemas sem logind, ative a *flag* de *suid* do arquivo binário:
sudo chmod a+s /usr/local/bin/sway
## Configuração
Se você já usa o i3, copie o arquivo de configuração do i3 para `~/.config/sway/config`;
o Sway lerá o arquivo normalmente. Senão, copie o arquivo de configuração de exemplo
para `~/.config/sway/config`. É comum esse arquivo estar localizado em
`/etc/sway/config`. Veja `man 5 sway` para informações sobre configuração.
## Executando
Execute `sway` a partir de um terminal do Linux. Alguns gerenciadores de *display*
podem funcionar, porém o Sway não procura manter compatibilidade com esses (segundo
relatos, o gdm funciona bem com o Sway).

View file

@ -1,83 +0,0 @@
# sway
Sway на данный момент **(в разработке)** i3-совместимый
[Wayland](http://wayland.freedesktop.org/) композитор. Прочитайте
[FAQ](https://github.com/swaywm/sway/wiki). Присоединяйтесь к [IRC
каналу](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway на
irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png)
При желании поддержать разработку Sway вы можете пожертвовать [автору
на его Patreon странице](https://patreon.com/sircmpwn) или взяться
за разработку определённых целей в обмен на [награду](https://github.com/swaywm/sway/issues/986).
Вы также можете объявить свою награду за определённую цель и больше всего для этого подходит Patreon.
## Помощь
DarkReef оказывает поддержку на русском языке в IRC канале и на GitHub в часовом поясе UTC +05:00.
Если у вас есть желание помочь с переводом на русский язык, то, пожалуйста, ознакомьтесь с [подсказками для переводчиков](https://github.com/swaywm/sway/issues/1318). На этой же странице можно узнать [статус перевода](https://github.com/swaywm/sway/issues/1318#issuecomment-326913020).
## Подпись версий
Версии подписаны ключом [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
и опубликованы [на GitHub'е](https://github.com/swaywm/sway/releases).
## Установка
### Из пакета
Sway доступен во многих дистрибутивах и находится в официальных репозиториях. Попробуйте установить "sway" через ваш пакетный менеджер.
В случае, если это не представляется возможным, то обратитесь к [этой странице](https://github.com/swaywm/sway/wiki/Unsupported-packages)
для получения инструкций по установке для вашего дистрибутива.
Если вы заинтересованы в создании пакета "sway" в вашем дистрибутиве, то сообщите об этом в IRC
канале или отправьте письмо [sir@cmpwn.com](mailto:sir@cmpwn.com).
### Сборка из исходников
Установите следующие пакеты:
* meson
* [wlc](https://github.com/Cloudef/wlc)
* wayland
* xwayland
* libinput >= 1.6.0
* libcap
* pcre
* json-c >= 0.13
* pango
* cairo
* gdk-pixbuf2 *
* dbus >= 1.10 **
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (required for man pages)
* git
_\*Требуется только для swaybar, swaybg_
_\*\*Требуется только для tray_
Выполните следующие команды:
meson build
ninja -C build
sudo ninja -C build install
Если у вас logind:
sudo setcap "cap_sys_ptrace,cap_sys_tty_config=eip" /usr/local/bin/sway
Иначе:
sudo chmod a+s /usr/local/bin/sway
## Настройка
Если вы уже используете i3, тогда просто скопируйте ваш конфиг в `~/.config/sway/config`.
В любом другом случае, скопируйте `/etc/sway/config` в `~/.config/sway/config`.
Для более детальной информации о настройке: `man 5 sway`.
## Запуск
Выполните 'sway' в терминале. **Некоторые** менеджеры сессий могут работать, но не поддерживаются sway (к примеру, gdm работает со sway без проблем).

View file

@ -1,20 +1,12 @@
# sway # sway
**Sway** це сумісний з i3 композитор [Wayland](http://wayland.freedesktop.org/) Sway це сумісний з [i3](https://i3wm.org/) композитор [Wayland](http://wayland.freedesktop.org/).
(**у стані розробки**). Ознайомтесь з Ознайомтесь з [ЧаПами](https://github.com/swaywm/sway/wiki). Приєднуйтесь до [спільноти в
[ЧаПами](https://github.com/swaywm/sway/wiki). Приєднуйтесь до [спільноти в
IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway на IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway на
irc.freenode.net). irc.freenode.net).
[![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png) Якщо ви маєте бажання підтримати розробку sway, ви можете зробити свій внесок на сторінці
[SirCmpwn у Patreon](https://patreon.com/sircmpwn).
Якщо ви хочете підтримати розробку Sway, ви можете зробити свій внесок у
[SirCmpwn'ову сторінку Patreon](https://patreon.com/sircmpwn) або до
[фонду винагород](https://github.com/swaywm/sway/issues/986) за реалізацію
певного функціоналу.
Кожен може виставити винагороду за реалізацію довільної функції
(і, відповідно, забрати її собі, виконавши це завдання);
кошти від сторінки Patreon підтримують загальну розробку та підтримку Sway.
## Підтримка українською мовою ## Підтримка українською мовою
@ -39,28 +31,26 @@ Sway доступний у багатьох дистрибутивах Linux (а
для інформації щодо встановлення на вашому дистрибутиві. для інформації щодо встановлення на вашому дистрибутиві.
Якщо ви готові та зацікавлені запакувати і підтримувати Sway у вашому Якщо ви готові та зацікавлені запакувати і підтримувати Sway у вашому
дистрибутиві, будемо раді вас бачити у нашому каналі IRC. Ви також можете дистрибутиві, звертайтесь за порадами до нашого каналу в IRC або
спитати порад за адресою sir@cmpwn.com. пишіть на електронну пошту [sir@cmpwn.com](mailto:sir@cmpwn.com).
### З вихідного коду ### З вихідного коду
Встановіть залежності: Встановіть залежності:
* meson * meson \*
* [wlc](https://github.com/Cloudef/wlc) * [wlroots](https://github.com/swaywm/wlroots)
* wayland * wayland
* xwayland * wayland-protocols \*
* libinput >= 1.6.0
* libcap
* pcre * pcre
* json-c >= 0.13 * json-c
* pango * pango
* cairo * cairo
* gdk-pixbuf2 * * gdk-pixbuf2 (optional: system tray)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (required for man pages) * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (необов'язково, необхідно для сторінок man) \*
* git * git \*
_\*Лише для swaybar, swaybg_ _\*Лише для компіляції_
Виконайте ці команди: Виконайте ці команди:
@ -68,15 +58,12 @@ _\*Лише для swaybar, swaybg_
ninja -C build ninja -C build
sudo ninja -C build install sudo ninja -C build install
На системах **з** logind, варто встановити декілька можливостей (caps) На системах без logind, необхідно встановити біт SUID на виконуваний файл sway:
на виконуваний файл sway:
sudo setcap "cap_sys_ptrace,cap_sys_tty_config=eip" /usr/local/bin/sway
На системах **без** logind, необхідно встановити біт SUID на виконуваний файл sway:
sudo chmod a+s /usr/local/bin/sway sudo chmod a+s /usr/local/bin/sway
Sway втратить права доступу root незабаром після запуску.
## Налаштування ## Налаштування
Якщо ви вже використовуєте i3, скопіюйте свій файл налаштувань Якщо ви вже використовуєте i3, скопіюйте свій файл налаштувань

66
README.zh-CN.md Normal file
View file

@ -0,0 +1,66 @@
# sway
sway 是和 [i3](https://i3wm.org/) 兼容的 [Wayland](http://wayland.freedesktop.org/) compositor.
阅读 [FAQ](https://github.com/swaywm/sway/wiki). 加入 [IRC
频道](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on
irc.freenode.net).
如果你想要支持 sway 的发展, 请到 [SirCmpwn's
Patreon page](https://patreon.com/sircmpwn)贡献.
## 发布签名
发布是以 [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) 签名
并发布在 [GitHub](https://github.com/swaywm/sway/releases).
## 安装
### 从软件包中
Sway 在很多发行版中可用. 尝试在你的发行版中安装 "sway" 包.
如果这不可用, 请到 [此 wiki 页](https://github.com/swaywm/sway/wiki/Unsupported-packages)
检查针对你的发行版关于安装的信息.
如果你有兴趣给你的发行版打包 sway, 停下来到 IRC 频道或者发邮件至 sir@cmpwn.com 获取建议.
### 从源代码编译
安装依赖:
* meson \*
* [wlroots](https://github.com/swaywm/wlroots)
* wayland
* wayland-protocols \*
* pcre
* json-c
* pango
* cairo
* gdk-pixbuf2 (可选的: system tray)
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (可选的: man pages) \*
* git \*
_\*编译时依赖_
运行这些命令:
meson build
ninja -C build
sudo ninja -C build install
在没有 logind 的系统上, 你需要给 sway 二进制设置 suid:
sudo chmod a+s /usr/local/bin/sway
Sway 将会在启动后尽快丢掉 root 权限.
## 配置
如果你已经在使用 i3, 接下来复制你的 i3 配置到 `~/.config/sway/config`
它可以直接工作. 或者, 复制样本配置文件到
`~/.config/sway/config`. 它通常位于 `/etc/sway/config`.
运行 `man 5 sway` 获取关于配置的信息.
## 运行
从 TTY 中运行 `sway` . 某些显示管理器可能会工作但并不被 sway 支持
(已知的 gdm 工作得非常好).

View file

@ -5,7 +5,6 @@ lib_sway_client = static_library(
), ),
dependencies: [ dependencies: [
cairo, cairo,
gdk_pixbuf,
pango, pango,
pangocairo, pangocairo,
wayland_client wayland_client

View file

@ -2,6 +2,9 @@
#include "background-image.h" #include "background-image.h"
#include "cairo.h" #include "cairo.h"
#include "log.h" #include "log.h"
#if HAVE_GDK_PIXBUF
#include <gdk-pixbuf/gdk-pixbuf.h>
#endif
enum background_mode parse_background_mode(const char *mode) { enum background_mode parse_background_mode(const char *mode) {
if (strcmp(mode, "stretch") == 0) { if (strcmp(mode, "stretch") == 0) {
@ -21,6 +24,103 @@ enum background_mode parse_background_mode(const char *mode) {
return BACKGROUND_MODE_INVALID; return BACKGROUND_MODE_INVALID;
} }
#if HAVE_GDK_PIXBUF
static cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(
const GdkPixbuf *gdkbuf) {
int chan = gdk_pixbuf_get_n_channels(gdkbuf);
if (chan < 3) {
return NULL;
}
const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf);
if (!gdkpix) {
return NULL;
}
gint w = gdk_pixbuf_get_width(gdkbuf);
gint h = gdk_pixbuf_get_height(gdkbuf);
int stride = gdk_pixbuf_get_rowstride(gdkbuf);
cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h);
cairo_surface_flush (cs);
if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
return NULL;
}
int cstride = cairo_image_surface_get_stride(cs);
unsigned char * cpix = cairo_image_surface_get_data(cs);
if (chan == 3) {
int i;
for (i = h; i; --i) {
const guint8 *gp = gdkpix;
unsigned char *cp = cpix;
const guint8* end = gp + 3*w;
while (gp < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
cp[0] = gp[2];
cp[1] = gp[1];
cp[2] = gp[0];
#else
cp[1] = gp[0];
cp[2] = gp[1];
cp[3] = gp[2];
#endif
gp += 3;
cp += 4;
}
gdkpix += stride;
cpix += cstride;
}
} else {
/* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255
* (z/255) = z/256 * 256/255 = z/256 (1 + 1/255)
* = z/256 + (z/256)/255 = (z + z/255)/256
* # recurse once
* = (z + (z + z/255)/256)/256
* = (z + z/256 + z/256/255) / 256
* # only use 16bit uint operations, loose some precision,
* # result is floored.
* -> (z + z>>8)>>8
* # add 0x80/255 = 0.5 to convert floor to round
* => (z+0x80 + (z+0x80)>>8 ) >> 8
* ------
* tested as equal to lround(z/255.0) for uint z in [0..0xfe02]
*/
#define PREMUL_ALPHA(x,a,b,z) \
G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } \
G_STMT_END
int i;
for (i = h; i; --i) {
const guint8 *gp = gdkpix;
unsigned char *cp = cpix;
const guint8* end = gp + 4*w;
guint z1, z2, z3;
while (gp < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
PREMUL_ALPHA(cp[0], gp[2], gp[3], z1);
PREMUL_ALPHA(cp[1], gp[1], gp[3], z2);
PREMUL_ALPHA(cp[2], gp[0], gp[3], z3);
cp[3] = gp[3];
#else
PREMUL_ALPHA(cp[1], gp[0], gp[3], z1);
PREMUL_ALPHA(cp[2], gp[1], gp[3], z2);
PREMUL_ALPHA(cp[3], gp[2], gp[3], z3);
cp[0] = gp[3];
#endif
gp += 4;
cp += 4;
}
gdkpix += stride;
cpix += cstride;
}
#undef PREMUL_ALPHA
}
cairo_surface_mark_dirty(cs);
return cs;
}
#endif // HAVE_GDK_PIXBUF
cairo_surface_t *load_background_image(const char *path) { cairo_surface_t *load_background_image(const char *path) {
cairo_surface_t *image; cairo_surface_t *image;
#if HAVE_GDK_PIXBUF #if HAVE_GDK_PIXBUF

View file

@ -1,9 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include "cairo.h" #include "cairo.h"
#if HAVE_GDK_PIXBUF
#include <gdk-pixbuf/gdk-pixbuf.h>
#endif
void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
cairo_set_source_rgba(cairo, cairo_set_source_rgba(cairo,
@ -45,99 +42,3 @@ cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image,
cairo_destroy(cairo); cairo_destroy(cairo);
return new; return new;
} }
#if HAVE_GDK_PIXBUF
cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(const GdkPixbuf *gdkbuf) {
int chan = gdk_pixbuf_get_n_channels(gdkbuf);
if (chan < 3) {
return NULL;
}
const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf);
if (!gdkpix) {
return NULL;
}
gint w = gdk_pixbuf_get_width(gdkbuf);
gint h = gdk_pixbuf_get_height(gdkbuf);
int stride = gdk_pixbuf_get_rowstride(gdkbuf);
cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h);
cairo_surface_flush (cs);
if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
return NULL;
}
int cstride = cairo_image_surface_get_stride(cs);
unsigned char * cpix = cairo_image_surface_get_data(cs);
if (chan == 3) {
int i;
for (i = h; i; --i) {
const guint8 *gp = gdkpix;
unsigned char *cp = cpix;
const guint8* end = gp + 3*w;
while (gp < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
cp[0] = gp[2];
cp[1] = gp[1];
cp[2] = gp[0];
#else
cp[1] = gp[0];
cp[2] = gp[1];
cp[3] = gp[2];
#endif
gp += 3;
cp += 4;
}
gdkpix += stride;
cpix += cstride;
}
} else {
/* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255
* (z/255) = z/256 * 256/255 = z/256 (1 + 1/255)
* = z/256 + (z/256)/255 = (z + z/255)/256
* # recurse once
* = (z + (z + z/255)/256)/256
* = (z + z/256 + z/256/255) / 256
* # only use 16bit uint operations, loose some precision,
* # result is floored.
* -> (z + z>>8)>>8
* # add 0x80/255 = 0.5 to convert floor to round
* => (z+0x80 + (z+0x80)>>8 ) >> 8
* ------
* tested as equal to lround(z/255.0) for uint z in [0..0xfe02]
*/
#define PREMUL_ALPHA(x,a,b,z) \
G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } \
G_STMT_END
int i;
for (i = h; i; --i) {
const guint8 *gp = gdkpix;
unsigned char *cp = cpix;
const guint8* end = gp + 4*w;
guint z1, z2, z3;
while (gp < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
PREMUL_ALPHA(cp[0], gp[2], gp[3], z1);
PREMUL_ALPHA(cp[1], gp[1], gp[3], z2);
PREMUL_ALPHA(cp[2], gp[0], gp[3], z3);
cp[3] = gp[3];
#else
PREMUL_ALPHA(cp[1], gp[0], gp[3], z1);
PREMUL_ALPHA(cp[2], gp[1], gp[3], z2);
PREMUL_ALPHA(cp[3], gp[2], gp[3], z3);
cp[0] = gp[3];
#endif
gp += 4;
cp += 4;
}
gdkpix += stride;
cpix += cstride;
}
#undef PREMUL_ALPHA
}
cairo_surface_mark_dirty(cs);
return cs;
}
#endif // HAVE_GDK_PIXBUF

View file

@ -69,6 +69,14 @@ int ipc_open_socket(const char *socket_path) {
return socketfd; return socketfd;
} }
bool ipc_set_recv_timeout(int socketfd, struct timeval tv) {
if (setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
sway_log_errno(SWAY_ERROR, "Failed to set ipc recv timeout");
return false;
}
return true;
}
struct ipc_response *ipc_recv_response(int socketfd) { struct ipc_response *ipc_recv_response(int socketfd) {
char data[IPC_HEADER_SIZE]; char data[IPC_HEADER_SIZE];
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));

View file

@ -1,13 +1,13 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <stdlib.h> #include <ctype.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <ctype.h>
#include "stringop.h"
#include "log.h"
#include "string.h"
#include "list.h" #include "list.h"
#include "log.h"
#include "stringop.h"
static const char whitespace[] = " \f\n\r\t\v"; static const char whitespace[] = " \f\n\r\t\v";
@ -78,12 +78,10 @@ int lenient_strcmp(char *a, char *b) {
list_t *split_string(const char *str, const char *delims) { list_t *split_string(const char *str, const char *delims) {
list_t *res = create_list(); list_t *res = create_list();
char *copy = strdup(str); char *copy = strdup(str);
char *token;
token = strtok(copy, delims); char *token = strtok(copy, delims);
while(token) { while (token) {
token = strdup(token); list_add(res, strdup(token));
list_add(res, token);
token = strtok(NULL, delims); token = strtok(NULL, delims);
} }
free(copy); free(copy);
@ -150,29 +148,6 @@ void free_argv(int argc, char **argv) {
free(argv); free(argv);
} }
char *code_strstr(const char *haystack, const char *needle) {
/* TODO */
return strstr(haystack, needle);
}
char *code_strchr(const char *str, char delimiter) {
int in_string = 0, in_character = 0;
int i = 0;
while (str[i] != '\0') {
if (str[i] == '"' && !in_character) {
in_string = !in_string;
} else if (str[i] == '\'' && !in_string) {
in_character = !in_character;
} else if (!in_character && !in_string) {
if (str[i] == delimiter) {
return (char *)str + i;
}
}
++i;
}
return NULL;
}
int unescape_string(char *string) { int unescape_string(char *string) {
/* TODO: More C string escapes */ /* TODO: More C string escapes */
int len = strlen(string); int len = strlen(string);
@ -276,84 +251,6 @@ char *join_args(char **argv, int argc) {
return res; return res;
} }
static bool has_whitespace(const char *str) {
while (*str) {
if (isspace(*str)) {
return true;
}
++str;
}
return false;
}
/**
* Add quotes around any argv with whitespaces.
*/
void add_quotes(char **argv, int argc) {
int i;
for (i = 0; i < argc; ++i) {
if (has_whitespace(argv[i])) {
int len = strlen(argv[i]) + 3;
char *tmp = argv[i];
argv[i] = malloc(len * sizeof(char));
snprintf(argv[i], len, "\"%s\"", tmp);
free(tmp);
}
}
}
/*
* Join a list of strings, adding separator in between. Separator can be NULL.
*/
char *join_list(list_t *list, char *separator) {
if (!sway_assert(list != NULL, "list != NULL") || list->length == 0) {
return NULL;
}
size_t len = 1; // NULL terminator
size_t sep_len = 0;
if (separator != NULL) {
sep_len = strlen(separator);
len += (list->length - 1) * sep_len;
}
for (int i = 0; i < list->length; i++) {
len += strlen(list->items[i]);
}
char *res = malloc(len);
char *p = res + strlen(list->items[0]);
strcpy(res, list->items[0]);
for (int i = 1; i < list->length; i++) {
if (sep_len) {
memcpy(p, separator, sep_len);
p += sep_len;
}
strcpy(p, list->items[i]);
p += strlen(list->items[i]);
}
*p = '\0';
return res;
}
char *cmdsep(char **stringp, const char *delim) {
// skip over leading delims
char *head = *stringp + strspn(*stringp, delim);
// Find end token
char *tail = *stringp += strcspn(*stringp, delim);
// Set stringp to beginning of next token
*stringp += strspn(*stringp, delim);
// Set stringp to null if last token
if (!**stringp) *stringp = NULL;
// Nullify end of first token
*tail = 0;
return head;
}
char *argsep(char **stringp, const char *delim) { char *argsep(char **stringp, const char *delim) {
char *start = *stringp; char *start = *stringp;
char *end = start; char *end = start;
@ -369,13 +266,13 @@ char *argsep(char **stringp, const char *delim) {
escaped = !escaped; escaped = !escaped;
} else if (*end == '\0') { } else if (*end == '\0') {
*stringp = NULL; *stringp = NULL;
goto found; break;
} else if (!in_string && !in_char && !escaped && strchr(delim, *end)) { } else if (!in_string && !in_char && !escaped && strchr(delim, *end)) {
if (end - start) { if (end - start) {
*(end++) = 0; *(end++) = 0;
*stringp = end + strspn(end, delim);; *stringp = end + strspn(end, delim);;
if (!**stringp) *stringp = NULL; if (!**stringp) *stringp = NULL;
goto found; break;
} else { } else {
++start; ++start;
end = start; end = start;
@ -386,20 +283,5 @@ char *argsep(char **stringp, const char *delim) {
} }
++end; ++end;
} }
found:
return start; return start;
} }
const char *strcasestr(const char *haystack, const char *needle) {
size_t needle_len = strlen(needle);
const char *pos = haystack;
const char *end = pos + strlen(haystack) - needle_len;
while (pos <= end) {
if (strncasecmp(pos, needle, needle_len) == 0) {
return pos;
}
++pos;
}
return NULL;
}

View file

@ -1,9 +1,11 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <float.h> #include <float.h>
#include <fcntl.h>
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <wayland-server-protocol.h>
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
@ -54,3 +56,41 @@ float parse_float(const char *value) {
} }
return flt; return flt;
} }
const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel) {
switch (subpixel) {
case WL_OUTPUT_SUBPIXEL_UNKNOWN:
return "unknown";
case WL_OUTPUT_SUBPIXEL_NONE:
return "none";
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
return "rgb";
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
return "bgr";
case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
return "vrgb";
case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
return "vbgr";
}
sway_assert(false, "Unknown value for wl_output_subpixel.");
return NULL;
}
bool set_cloexec(int fd, bool cloexec) {
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
sway_log_errno(SWAY_ERROR, "fcntl failed");
return false;
}
if (cloexec) {
flags = flags | FD_CLOEXEC;
} else {
flags = flags & ~FD_CLOEXEC;
}
if (fcntl(fd, F_SETFD, flags) == -1) {
sway_log_errno(SWAY_ERROR, "fcntl failed");
return false;
}
return true;
}

View file

@ -17,10 +17,13 @@ _swaymsg()
'get_binding_modes' 'get_binding_modes'
'get_config' 'get_config'
'send_tick' 'send_tick'
'subscribe'
) )
short=( short=(
-h -h
-m
-p
-q -q
-r -r
-s -s
@ -30,6 +33,8 @@ _swaymsg()
long=( long=(
--help --help
--monitor
--pretty
--quiet --quiet
--raw --raw
--socket --socket

View file

@ -1,5 +1,6 @@
# sway(1) completion # sway(1) completion
complete -f -c sway
complete -c sway -s h -l help --description "Show help message and quit." complete -c sway -s h -l help --description "Show help message and quit."
complete -c sway -s c -l config --description "Specifies a config file." complete -c sway -s c -l config --description "Specifies a config file."
complete -c sway -s C -l validate --description "Check the validity of the config file, then exit." complete -c sway -s C -l validate --description "Check the validity of the config file, then exit."

View file

@ -1,10 +1,13 @@
# swaymsg(1) completion # swaymsg(1) completion
complete -f -c swaymsg
complete -c swaymsg -s h -l help --description "Show help message and quit." complete -c swaymsg -s h -l help --description "Show help message and quit."
complete -c swaymsg -s m -l monitor --description "Monitor subscribed events until killed."
complete -c swaymsg -s p -l pretty --description "Use pretty output even when not using a tty."
complete -c swaymsg -s q -l quiet --description "Sends the IPC message but does not print the response from sway." complete -c swaymsg -s q -l quiet --description "Sends the IPC message but does not print the response from sway."
complete -c swaymsg -s v -l version --description "Print the version (of swaymsg) and quit."
complete -c swaymsg -s r -l raw --description "Use raw output even if using tty." complete -c swaymsg -s r -l raw --description "Use raw output even if using tty."
complete -c swaymsg -s s -l socket -r --description "Use the specified socket path. Otherwise, swaymsg will ask where the socket is (which is the value of $SWAYSOCK, then of $I3SOCK)." complete -c swaymsg -s s -l socket -r --description "Use the specified socket path. Otherwise, swaymsg will ask where the socket is (which is the value of $SWAYSOCK, then of $I3SOCK)."
complete -c swaymsg -s v -l version --description "Print the version (of swaymsg) and quit."
complete -c swaymsg -s t -l type -fr --description "Specify the type of IPC message." complete -c swaymsg -s t -l type -fr --description "Specify the type of IPC message."
complete -c swaymsg -s t -l type -fra 'get_workspaces' --description "Gets a JSON-encoded list of workspaces and their status." complete -c swaymsg -s t -l type -fra 'get_workspaces' --description "Gets a JSON-encoded list of workspaces and their status."
@ -18,3 +21,4 @@ complete -c swaymsg -s t -l type -fra 'get_binding_modes' --description "Gets a
complete -c swaymsg -s t -l type -fra 'get_config' --description "Gets a JSON-encoded copy of the current configuration." complete -c swaymsg -s t -l type -fra 'get_config' --description "Gets a JSON-encoded copy of the current configuration."
complete -c swaymsg -s t -l type -fra 'get_seats' --description "Gets a JSON-encoded list of all seats, its properties and all assigned devices." complete -c swaymsg -s t -l type -fra 'get_seats' --description "Gets a JSON-encoded list of all seats, its properties and all assigned devices."
complete -c swaymsg -s t -l type -fra 'send_tick' --description "Sends a tick event to all subscribed clients." complete -c swaymsg -s t -l type -fra 'send_tick' --description "Sends a tick event to all subscribed clients."
complete -c swaymsg -s t -l type -fra 'subscribe' --description "Subscribe to a list of event types."

View file

@ -1,29 +1,30 @@
# swaynag # swaynag
complete -c swaynag -s C -l config --description 'The config file to use. Default: $HOME/.swaylock/config, $XDG_CONFIG_HOME/swaylock/config, and SYSCONFDIR/swaylock/config.' complete -f -c swaynag
complete -c swaynag -s C -l config -r --description 'The config file to use. Default: $HOME/.swaynag/config, $XDG_CONFIG_HOME/swaynag/config, and SYSCONFDIR/swaynag/config.'
complete -c swaynag -s d -l debug --description 'Enable debugging.' complete -c swaynag -s d -l debug --description 'Enable debugging.'
complete -c swaynag -s e -l edge --description 'Set the edge to use: top or bottom' complete -c swaynag -s e -l edge -fr --description 'Set the edge to use: top or bottom'
complete -c swaynag -s f -l font --description 'Set the font to use.' complete -c swaynag -s f -l font -r --description 'Set the font to use.'
complete -c swaynag -s h -l help --description 'Show help message and quit.' complete -c swaynag -s h -l help --description 'Show help message and quit.'
complete -c swaynag -s b -l button --description 'Create a button with a text and an action which is executed when pressed. Multiple buttons can be defined by providing the flag multiple times.' complete -c swaynag -s b -l button -fr --description 'Create a button with a text and an action which is executed when pressed. Multiple buttons can be defined by providing the flag multiple times.'
complete -c swaynag -s l -l detailed-message --description 'Read a detailed message from stdin. A button to toggle details will be added. Details are shown in a scrollable multi-line text area.' complete -c swaynag -s l -l detailed-message --description 'Read a detailed message from stdin. A button to toggle details will be added. Details are shown in a scrollable multi-line text area.'
complete -c swaynag -s L -l detailed-button --description 'Set the text for the button that toggles details. This has no effect if there is not a detailed message. The default is "Toggle details".' complete -c swaynag -s L -l detailed-button -fr --description 'Set the text for the button that toggles details. This has no effect if there is not a detailed message. The default is "Toggle details".'
complete -c swaynag -s m -l message --description 'Set the message text.' complete -c swaynag -s m -l message -fr --description 'Set the message text.'
complete -c swaynag -s o -l output --description 'Set the output to use.' complete -c swaynag -s o -l output -fr --description 'Set the output to use.'
complete -c swaynag -s s -l dismiss-button --description 'Sets the text for the dismiss nagbar button. The default is "X".' complete -c swaynag -s s -l dismiss-button -fr --description 'Sets the text for the dismiss nagbar button. The default is "X".'
complete -c swaynag -s t -l type --description 'Set the message type. Two types are created by default "error" and "warning". Custom types can be defined in the config file.' complete -c swaynag -s t -l type -fr --description 'Set the message type. Two types are created by default "error" and "warning". Custom types can be defined in the config file.'
complete -c swaynag -s v -l version --description 'Show the version number and quit.' complete -c swaynag -s v -l version --description 'Show the version number and quit.'
# Appearance # Appearance
complete -c swaynag -l background --description 'Set the color of the background.' complete -c swaynag -l background -fr --description 'Set the color of the background.'
complete -c swaynag -l border --description 'Set the color of the border.' complete -c swaynag -l border -fr --description 'Set the color of the border.'
complete -c swaynag -l border-bottom --description 'Set the color of the bottom border.' complete -c swaynag -l border-bottom -fr --description 'Set the color of the bottom border.'
complete -c swaynag -l button-background --description 'Set the color for the background for buttons.' complete -c swaynag -l button-background -fr --description 'Set the color for the background for buttons.'
complete -c swaynag -l text --description 'Set the text color.' complete -c swaynag -l text -fr --description 'Set the text color.'
complete -c swaynag -l border-bottom-size --description 'Set the thickness of the bottom border.' complete -c swaynag -l border-bottom-size -fr --description 'Set the thickness of the bottom border.'
complete -c swaynag -l message-padding --description 'Set the padding for the message.' complete -c swaynag -l message-padding -fr --description 'Set the padding for the message.'
complete -c swaynag -l details-border-size --description 'Set the thickness for the details border.' complete -c swaynag -l details-border-size -fr --description 'Set the thickness for the details border.'
complete -c swaynag -l button-border-size --description 'Set the thickness for the button border.' complete -c swaynag -l button-border-size -fr --description 'Set the thickness for the button border.'
complete -c swaynag -l button-gap --description 'Set the size of the gap between buttons.' complete -c swaynag -l button-gap -fr --description 'Set the size of the gap between buttons.'
complete -c swaynag -l button-dismiss-gap --description 'Set the size of the gap between the dismiss button and another button.' complete -c swaynag -l button-dismiss-gap -fr --description 'Set the size of the gap between the dismiss button and another button.'
complete -c swaynag -l button-margin-right --description 'Set the margin from the right of the dismiss button to edge.' complete -c swaynag -l button-margin-right -fr --description 'Set the margin from the right of the dismiss button to edge.'
complete -c swaynag -l button-padding --description 'Set the padding for the button text.' complete -c swaynag -l button-padding -fr --description 'Set the padding for the button text.'

View file

@ -25,13 +25,15 @@ types=(
'get_binding_modes' 'get_binding_modes'
'get_config' 'get_config'
'send_tick' 'send_tick'
'subscribe'
) )
_arguments -s \ _arguments -s \
'(-v --version)'{-v,--version}'[Show the version number and quit]' \
'(-m --monitor)'{-m,--monitor}'[Monitor until killed (-t SUBSCRIBE only)]' \
'(-h --help)'{-h,--help}'[Show help message and quit]' \ '(-h --help)'{-h,--help}'[Show help message and quit]' \
'(-m --monitor)'{-m,--monitor}'[Monitor until killed (-t SUBSCRIBE only)]' \
'(-p --pretty)'{-p,--pretty}'[Use pretty output even when not using a tty]' \
'(-q --quiet)'{-q,--quiet}'[Be quiet]' \ '(-q --quiet)'{-q,--quiet}'[Be quiet]' \
'(-r --raw)'{-r,--raw}'[Use raw output even if using a tty]' \ '(-r --raw)'{-r,--raw}'[Use raw output even if using a tty]' \
'(-s --socket)'{-s,--socket}'[Use the specified socket path]:files:_files' \ '(-s --socket)'{-s,--socket}'[Use the specified socket path]:files:_files' \
'(-t --type)'{-t,--type}'[Specify the message type]:type:{_describe "type" types}' '(-t --type)'{-t,--type}'[Specify the message type]:type:{_describe "type" types}' \
'(-v --version)'{-v,--version}'[Show the version number and quit]'

View file

@ -17,7 +17,7 @@ set $right l
set $term urxvt set $term urxvt
# Your preferred application launcher # Your preferred application launcher
# Note: it's recommended that you pass the final command to sway # Note: it's recommended that you pass the final command to sway
set $menu dmenu_path | dmenu | xargs swaymsg exec set $menu dmenu_path | dmenu | xargs swaymsg exec --
### Output configuration ### Output configuration
# #
@ -62,13 +62,13 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
# #
# Basics: # Basics:
# #
# start a terminal # Start a terminal
bindsym $mod+Return exec $term bindsym $mod+Return exec $term
# kill focused window # Kill focused window
bindsym $mod+Shift+q kill bindsym $mod+Shift+q kill
# start your launcher # Start your launcher
bindsym $mod+d exec $menu bindsym $mod+d exec $menu
# Drag floating windows by holding down $mod and left mouse button. # Drag floating windows by holding down $mod and left mouse button.
@ -78,10 +78,10 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
# mouse button for dragging. # mouse button for dragging.
floating_modifier $mod normal floating_modifier $mod normal
# reload the configuration file # Reload the configuration file
bindsym $mod+Shift+c reload bindsym $mod+Shift+c reload
# exit sway (logs you out of your Wayland session) # Exit sway (logs you out of your Wayland session)
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit' bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'
# #
# Moving around: # Moving around:
@ -91,18 +91,18 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
bindsym $mod+$down focus down bindsym $mod+$down focus down
bindsym $mod+$up focus up bindsym $mod+$up focus up
bindsym $mod+$right focus right bindsym $mod+$right focus right
# or use $mod+[up|down|left|right] # Or use $mod+[up|down|left|right]
bindsym $mod+Left focus left bindsym $mod+Left focus left
bindsym $mod+Down focus down bindsym $mod+Down focus down
bindsym $mod+Up focus up bindsym $mod+Up focus up
bindsym $mod+Right focus right bindsym $mod+Right focus right
# _move_ the focused window with the same, but add Shift # Move the focused window with the same, but add Shift
bindsym $mod+Shift+$left move left bindsym $mod+Shift+$left move left
bindsym $mod+Shift+$down move down bindsym $mod+Shift+$down move down
bindsym $mod+Shift+$up move up bindsym $mod+Shift+$up move up
bindsym $mod+Shift+$right move right bindsym $mod+Shift+$right move right
# ditto, with arrow keys # Ditto, with arrow keys
bindsym $mod+Shift+Left move left bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up bindsym $mod+Shift+Up move up
@ -110,7 +110,7 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
# #
# Workspaces: # Workspaces:
# #
# switch to workspace # Switch to workspace
bindsym $mod+1 workspace 1 bindsym $mod+1 workspace 1
bindsym $mod+2 workspace 2 bindsym $mod+2 workspace 2
bindsym $mod+3 workspace 3 bindsym $mod+3 workspace 3
@ -121,7 +121,7 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
bindsym $mod+8 workspace 8 bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9 bindsym $mod+9 workspace 9
bindsym $mod+0 workspace 10 bindsym $mod+0 workspace 10
# move focused container to workspace # Move focused container to workspace
bindsym $mod+Shift+1 move container to workspace 1 bindsym $mod+Shift+1 move container to workspace 1
bindsym $mod+Shift+2 move container to workspace 2 bindsym $mod+Shift+2 move container to workspace 2
bindsym $mod+Shift+3 move container to workspace 3 bindsym $mod+Shift+3 move container to workspace 3
@ -157,7 +157,7 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
# Swap focus between the tiling area and the floating area # Swap focus between the tiling area and the floating area
bindsym $mod+space focus mode_toggle bindsym $mod+space focus mode_toggle
# move focus to the parent container # Move focus to the parent container
bindsym $mod+a focus parent bindsym $mod+a focus parent
# #
# Scratchpad: # Scratchpad:
@ -184,13 +184,13 @@ mode "resize" {
bindsym $up resize shrink height 10px bindsym $up resize shrink height 10px
bindsym $right resize grow width 10px bindsym $right resize grow width 10px
# ditto, with arrow keys # Ditto, with arrow keys
bindsym Left resize shrink width 10px bindsym Left resize shrink width 10px
bindsym Down resize grow height 10px bindsym Down resize grow height 10px
bindsym Up resize shrink height 10px bindsym Up resize shrink height 10px
bindsym Right resize grow width 10px bindsym Right resize grow width 10px
# return to default mode # Return to default mode
bindsym Return mode "default" bindsym Return mode "default"
bindsym Escape mode "default" bindsym Escape mode "default"
} }

View file

@ -1,13 +1,9 @@
#ifndef _SWAY_CAIRO_H #ifndef _SWAY_CAIRO_H
#define _SWAY_CAIRO_H #define _SWAY_CAIRO_H
#include "config.h" #include "config.h"
#include <stdint.h> #include <stdint.h>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include <wayland-client-protocol.h> #include <wayland-client-protocol.h>
#if HAVE_GDK_PIXBUF
#include <gdk-pixbuf/gdk-pixbuf.h>
#endif
void cairo_set_source_u32(cairo_t *cairo, uint32_t color); void cairo_set_source_u32(cairo_t *cairo, uint32_t color);
cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel); cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel);
@ -15,11 +11,4 @@ cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel)
cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image,
int width, int height); int width, int height);
#if HAVE_GDK_PIXBUF
cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(
const GdkPixbuf *gdkbuf);
#endif // HAVE_GDK_PIXBUF
#endif #endif

View file

@ -1,7 +1,9 @@
#ifndef _SWAY_IPC_CLIENT_H #ifndef _SWAY_IPC_CLIENT_H
#define _SWAY_IPC_CLIENT_H #define _SWAY_IPC_CLIENT_H
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <sys/time.h>
#include "ipc.h" #include "ipc.h"
@ -36,5 +38,9 @@ struct ipc_response *ipc_recv_response(int socketfd);
* Free ipc_response struct * Free ipc_response struct
*/ */
void free_ipc_response(struct ipc_response *response); void free_ipc_response(struct ipc_response *response);
/**
* Sets the receive timeout for the IPC socket
*/
bool ipc_set_recv_timeout(int socketfd, struct timeval tv);
#endif #endif

View file

@ -4,7 +4,6 @@
#include "list.h" #include "list.h"
void strip_whitespace(char *str); void strip_whitespace(char *str);
char *strip_comments(char *str);
void strip_quotes(char *str); void strip_quotes(char *str);
// strcat that does nothing if dest or src is NULL // strcat that does nothing if dest or src is NULL
@ -21,22 +20,10 @@ list_t *split_string(const char *str, const char *delims);
char **split_args(const char *str, int *argc); char **split_args(const char *str, int *argc);
void free_argv(int argc, char **argv); void free_argv(int argc, char **argv);
char *code_strchr(const char *string, char delimiter);
char *code_strstr(const char *haystack, const char *needle);
int unescape_string(char *string); int unescape_string(char *string);
char *join_args(char **argv, int argc); char *join_args(char **argv, int argc);
char *join_list(list_t *list, char *separator);
/**
* Add quotes around any argv with whitespaces.
*/
void add_quotes(char **argv, int argc);
// split string into 2 by delim.
char *cmdsep(char **stringp, const char *delim);
// Split string into 2 by delim, handle quotes // Split string into 2 by delim, handle quotes
char *argsep(char **stringp, const char *delim); char *argsep(char **stringp, const char *delim);
const char *strcasestr(const char *haystack, const char *needle);
#endif #endif

View file

@ -101,6 +101,7 @@ struct sway_container *container_find_resize_parent(struct sway_container *con,
sway_cmd cmd_assign; sway_cmd cmd_assign;
sway_cmd cmd_bar; sway_cmd cmd_bar;
sway_cmd cmd_bindcode; sway_cmd cmd_bindcode;
sway_cmd cmd_bindswitch;
sway_cmd cmd_bindsym; sway_cmd cmd_bindsym;
sway_cmd cmd_border; sway_cmd cmd_border;
sway_cmd cmd_client_noop; sway_cmd cmd_client_noop;
@ -135,6 +136,7 @@ sway_cmd cmd_fullscreen;
sway_cmd cmd_gaps; sway_cmd cmd_gaps;
sway_cmd cmd_hide_edge_borders; sway_cmd cmd_hide_edge_borders;
sway_cmd cmd_include; sway_cmd cmd_include;
sway_cmd cmd_inhibit_idle;
sway_cmd cmd_input; sway_cmd cmd_input;
sway_cmd cmd_seat; sway_cmd cmd_seat;
sway_cmd cmd_ipc; sway_cmd cmd_ipc;
@ -145,6 +147,8 @@ sway_cmd cmd_mark;
sway_cmd cmd_mode; sway_cmd cmd_mode;
sway_cmd cmd_mouse_warping; sway_cmd cmd_mouse_warping;
sway_cmd cmd_move; sway_cmd cmd_move;
sway_cmd cmd_new_float;
sway_cmd cmd_new_window;
sway_cmd cmd_nop; sway_cmd cmd_nop;
sway_cmd cmd_opacity; sway_cmd cmd_opacity;
sway_cmd cmd_new_float; sway_cmd cmd_new_float;
@ -177,6 +181,9 @@ sway_cmd cmd_title_align;
sway_cmd cmd_title_format; sway_cmd cmd_title_format;
sway_cmd cmd_titlebar_border_thickness; sway_cmd cmd_titlebar_border_thickness;
sway_cmd cmd_titlebar_padding; sway_cmd cmd_titlebar_padding;
sway_cmd cmd_unbindcode;
sway_cmd cmd_unbindswitch;
sway_cmd cmd_unbindsym;
sway_cmd cmd_unmark; sway_cmd cmd_unmark;
sway_cmd cmd_urgent; sway_cmd cmd_urgent;
sway_cmd cmd_workspace; sway_cmd cmd_workspace;
@ -210,6 +217,8 @@ sway_cmd bar_cmd_tray_bindcode;
sway_cmd bar_cmd_tray_bindsym; sway_cmd bar_cmd_tray_bindsym;
sway_cmd bar_cmd_tray_output; sway_cmd bar_cmd_tray_output;
sway_cmd bar_cmd_tray_padding; sway_cmd bar_cmd_tray_padding;
sway_cmd bar_cmd_unbindcode;
sway_cmd bar_cmd_unbindsym;
sway_cmd bar_cmd_wrap_scroll; sway_cmd bar_cmd_wrap_scroll;
sway_cmd bar_cmd_workspace_buttons; sway_cmd bar_cmd_workspace_buttons;
@ -260,6 +269,8 @@ sway_cmd output_cmd_enable;
sway_cmd output_cmd_mode; sway_cmd output_cmd_mode;
sway_cmd output_cmd_position; sway_cmd output_cmd_position;
sway_cmd output_cmd_scale; sway_cmd output_cmd_scale;
sway_cmd output_cmd_subpixel;
sway_cmd output_cmd_toggle;
sway_cmd output_cmd_transform; sway_cmd output_cmd_transform;
sway_cmd seat_cmd_attach; sway_cmd seat_cmd_attach;

View file

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <wlr/interfaces/wlr_switch.h>
#include <wlr/types/wlr_box.h> #include <wlr/types/wlr_box.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include "../include/config.h" #include "../include/config.h"
@ -23,12 +24,12 @@ struct sway_variable {
char *value; char *value;
}; };
enum binding_input_type { enum binding_input_type {
BINDING_KEYCODE, BINDING_KEYCODE,
BINDING_KEYSYM, BINDING_KEYSYM,
BINDING_MOUSECODE, BINDING_MOUSECODE,
BINDING_MOUSESYM, BINDING_MOUSESYM,
BINDING_SWITCH
}; };
enum binding_flags { enum binding_flags {
@ -37,6 +38,7 @@ enum binding_flags {
BINDING_BORDER=4, // mouse only; trigger on container border BINDING_BORDER=4, // mouse only; trigger on container border
BINDING_CONTENTS=8, // mouse only; trigger on container contents BINDING_CONTENTS=8, // mouse only; trigger on container contents
BINDING_TITLEBAR=16, // mouse only; trigger on container titlebar BINDING_TITLEBAR=16, // mouse only; trigger on container titlebar
BINDING_CODE=32, // keyboard only; convert keysyms into keycodes
}; };
/** /**
@ -48,6 +50,7 @@ struct sway_binding {
char *input; char *input;
uint32_t flags; uint32_t flags;
list_t *keys; // sorted in ascending order list_t *keys; // sorted in ascending order
list_t *syms; // sorted in ascending order; NULL if BINDING_CODE is not set
uint32_t modifiers; uint32_t modifiers;
char *command; char *command;
}; };
@ -60,6 +63,16 @@ struct sway_mouse_binding {
char *command; char *command;
}; };
/**
* A laptop switch binding and an associated command.
*/
struct sway_switch_binding {
enum wlr_switch_type type;
enum wlr_switch_state state;
uint32_t flags;
char *command;
};
/** /**
* Focus on window activation. * Focus on window activation.
*/ */
@ -78,6 +91,7 @@ struct sway_mode {
list_t *keysym_bindings; list_t *keysym_bindings;
list_t *keycode_bindings; list_t *keycode_bindings;
list_t *mouse_bindings; list_t *mouse_bindings;
list_t *switch_bindings;
bool pango; bool pango;
}; };
@ -92,6 +106,7 @@ struct input_config_mapped_from_region {
*/ */
struct input_config { struct input_config {
char *identifier; char *identifier;
const char *input_type;
int accel_profile; int accel_profile;
int click_method; int click_method;
@ -171,6 +186,7 @@ struct output_config {
int x, y; int x, y;
float scale; float scale;
int32_t transform; int32_t transform;
enum wl_output_subpixel subpixel;
char *background; char *background;
char *background_option; char *background_option;
@ -200,6 +216,10 @@ struct workspace_config {
}; };
struct bar_config { struct bar_config {
char *swaybar_command;
struct wl_client *client;
struct wl_listener client_destroy;
/** /**
* One of "dock", "hide", "invisible" * One of "dock", "hide", "invisible"
* *
@ -227,7 +247,6 @@ struct bar_config {
list_t *bindings; list_t *bindings;
char *status_command; char *status_command;
bool pango_markup; bool pango_markup;
char *swaybar_command;
char *font; char *font;
int height; // -1 not defined int height; // -1 not defined
bool workspace_buttons; bool workspace_buttons;
@ -238,7 +257,6 @@ struct bar_config {
bool binding_mode_indicator; bool binding_mode_indicator;
bool verbose; bool verbose;
struct side_gaps gaps; struct side_gaps gaps;
pid_t pid;
int status_padding; int status_padding;
int status_edge_padding; int status_edge_padding;
struct { struct {
@ -404,13 +422,13 @@ struct sway_config {
list_t *workspace_configs; list_t *workspace_configs;
list_t *output_configs; list_t *output_configs;
list_t *input_configs; list_t *input_configs;
list_t *input_type_configs;
list_t *seat_configs; list_t *seat_configs;
list_t *criteria; list_t *criteria;
list_t *no_focus; list_t *no_focus;
list_t *active_bar_modifiers; list_t *active_bar_modifiers;
struct sway_mode *current_mode; struct sway_mode *current_mode;
struct bar_config *current_bar; struct bar_config *current_bar;
char *swaybg_command;
uint32_t floating_mod; uint32_t floating_mod;
bool floating_mod_inverse; bool floating_mod_inverse;
uint32_t dragging_key; uint32_t dragging_key;
@ -433,6 +451,11 @@ struct sway_config {
enum sway_popup_during_fullscreen popup_during_fullscreen; enum sway_popup_during_fullscreen popup_during_fullscreen;
bool xwayland; bool xwayland;
// swaybg
char *swaybg_command;
struct wl_client *swaybg_client;
struct wl_listener swaybg_client_destroy;
// Flags // Flags
enum focus_follows_mouse_mode focus_follows_mouse; enum focus_follows_mouse_mode focus_follows_mouse;
enum mouse_warping_mode mouse_warping; enum mouse_warping_mode mouse_warping;
@ -465,6 +488,7 @@ struct sway_config {
int floating_border_thickness; int floating_border_thickness;
enum edge_border_types hide_edge_borders; enum edge_border_types hide_edge_borders;
enum edge_border_types saved_edge_borders; enum edge_border_types saved_edge_borders;
bool hide_lone_tab;
// border colors // border colors
struct { struct {
@ -487,6 +511,9 @@ struct sway_config {
list_t *feature_policies; list_t *feature_policies;
list_t *ipc_policies; list_t *ipc_policies;
// The keysym to keycode translation
struct xkb_state *keysym_translation_state;
// Context for command handlers // Context for command handlers
struct { struct {
struct input_config *input_config; struct input_config *input_config;
@ -513,7 +540,7 @@ bool load_main_config(const char *path, bool is_active, bool validating);
/** /**
* Loads an included config. Can only be used after load_main_config. * Loads an included config. Can only be used after load_main_config.
*/ */
bool load_include_configs(const char *path, struct sway_config *config, void load_include_configs(const char *path, struct sway_config *config,
struct swaynag_instance *swaynag); struct swaynag_instance *swaynag);
/** /**
@ -552,6 +579,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src);
struct input_config *store_input_config(struct input_config *ic); struct input_config *store_input_config(struct input_config *ic);
void input_config_fill_rule_names(struct input_config *ic,
struct xkb_rule_names *rules);
void free_input_config(struct input_config *ic); void free_input_config(struct input_config *ic);
int seat_name_cmp(const void *item, const void *data); int seat_name_cmp(const void *item, const void *data);
@ -584,30 +614,28 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output);
struct output_config *store_output_config(struct output_config *oc); struct output_config *store_output_config(struct output_config *oc);
struct output_config *find_output_config(struct sway_output *output);
void apply_output_config_to_outputs(struct output_config *oc); void apply_output_config_to_outputs(struct output_config *oc);
void reset_outputs(void); void reset_outputs(void);
void free_output_config(struct output_config *oc); void free_output_config(struct output_config *oc);
bool spawn_swaybg(void);
int workspace_output_cmp_workspace(const void *a, const void *b); int workspace_output_cmp_workspace(const void *a, const void *b);
int sway_binding_cmp(const void *a, const void *b);
int sway_binding_cmp_qsort(const void *a, const void *b);
int sway_binding_cmp_keys(const void *a, const void *b);
void free_sway_binding(struct sway_binding *sb); void free_sway_binding(struct sway_binding *sb);
void free_switch_binding(struct sway_switch_binding *binding);
void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding); void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding);
void load_swaybar(struct bar_config *bar); void load_swaybar(struct bar_config *bar);
void load_swaybars(void); void load_swaybars(void);
void terminate_swaybg(pid_t pid);
struct bar_config *default_bar_config(void); struct bar_config *default_bar_config(void);
void free_bar_config(struct bar_config *bar); void free_bar_config(struct bar_config *bar);
@ -626,6 +654,16 @@ void free_workspace_config(struct workspace_config *wsc);
*/ */
void config_update_font_height(bool recalculate); void config_update_font_height(bool recalculate);
/**
* Convert bindsym into bindcode using the first configured layout.
* Return false in case the conversion is unsuccessful.
*/
bool translate_binding(struct sway_binding *binding);
void translate_keysyms(struct input_config *input_config);
void binding_add_translated(struct sway_binding *binding, list_t *bindings);
/* Global config singleton. */ /* Global config singleton. */
extern struct sway_config *config; extern struct sway_config *config;

View file

@ -20,6 +20,7 @@ struct criteria {
char *cmdlist; char *cmdlist;
char *target; // workspace or output name for `assign` criteria char *target; // workspace or output name for `assign` criteria
bool autofail; // __focused__ while no focus or n/a for focused view
pcre *title; pcre *title;
pcre *shell; pcre *shell;
pcre *app_id; pcre *app_id;
@ -35,7 +36,7 @@ struct criteria {
bool floating; bool floating;
bool tiling; bool tiling;
char urgent; // 'l' for latest or 'o' for oldest char urgent; // 'l' for latest or 'o' for oldest
char *workspace; pcre *workspace;
}; };
bool criteria_is_empty(struct criteria *criteria); bool criteria_is_empty(struct criteria *criteria);

View file

@ -1,22 +0,0 @@
#ifndef SWAY_DEBUG_H
#define SWAY_DEBUG_H
#include <stdbool.h>
struct sway_debug {
bool noatomic; // Ignore atomic layout updates
bool render_tree; // Render the tree overlay
bool txn_timings; // Log verbose messages about transactions
bool txn_wait; // Always wait for the timeout before applying
enum {
DAMAGE_DEFAULT, // Default behaviour
DAMAGE_HIGHLIGHT, // Highlight regions of the screen being damaged
DAMAGE_RERENDER, // Render the full output when any damage occurs
} damage;
};
extern struct sway_debug debug;
void update_debug_tree(void);
#endif

View file

@ -4,6 +4,14 @@
#include <wlr/types/wlr_idle.h> #include <wlr/types/wlr_idle.h>
#include "sway/server.h" #include "sway/server.h"
enum sway_idle_inhibit_mode {
INHIBIT_IDLE_APPLICATION, // Application set inhibitor (when visible)
INHIBIT_IDLE_FOCUS, // User set inhibitor when focused
INHIBIT_IDLE_FULLSCREEN, // User set inhibitor when fullscreen + visible
INHIBIT_IDLE_OPEN, // User set inhibitor while open
INHIBIT_IDLE_VISIBLE // User set inhibitor when visible
};
struct sway_idle_inhibit_manager_v1 { struct sway_idle_inhibit_manager_v1 {
struct wlr_idle_inhibit_manager_v1 *wlr_manager; struct wlr_idle_inhibit_manager_v1 *wlr_manager;
struct wl_listener new_idle_inhibitor_v1; struct wl_listener new_idle_inhibitor_v1;
@ -15,14 +23,24 @@ struct sway_idle_inhibit_manager_v1 {
struct sway_idle_inhibitor_v1 { struct sway_idle_inhibitor_v1 {
struct sway_idle_inhibit_manager_v1 *manager; struct sway_idle_inhibit_manager_v1 *manager;
struct sway_view *view; struct sway_view *view;
enum sway_idle_inhibit_mode mode;
struct wl_list link; struct wl_list link;
struct wl_listener destroy; struct wl_listener destroy;
}; };
void idle_inhibit_v1_check_active( void sway_idle_inhibit_v1_check_active(
struct sway_idle_inhibit_manager_v1 *manager); struct sway_idle_inhibit_manager_v1 *manager);
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
enum sway_idle_inhibit_mode mode);
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
struct sway_view *view);
void sway_idle_inhibit_v1_user_inhibitor_destroy(
struct sway_idle_inhibitor_v1 *inhibitor);
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create( struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
struct wl_display *wl_display, struct wlr_idle *idle); struct wl_display *wl_display, struct wlr_idle *idle);
#endif #endif

View file

@ -52,8 +52,6 @@ struct sway_cursor {
struct wl_event_source *hide_source; struct wl_event_source *hide_source;
bool hidden; bool hidden;
// Mouse binding state
uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP];
size_t pressed_button_count; size_t pressed_button_count;
}; };
@ -78,13 +76,6 @@ void cursor_handle_activity(struct sway_cursor *cursor);
void cursor_unhide(struct sway_cursor *cursor); void cursor_unhide(struct sway_cursor *cursor);
int cursor_get_timeout(struct sway_cursor *cursor); int cursor_get_timeout(struct sway_cursor *cursor);
/**
* Like cursor_rebase, but also allows focus to change when the cursor enters a
* new container.
*/
void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
struct sway_node *node, struct wlr_surface *surface, double sx, double sy);
void dispatch_cursor_button(struct sway_cursor *cursor, void dispatch_cursor_button(struct sway_cursor *cursor,
struct wlr_input_device *device, uint32_t time_msec, uint32_t button, struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
enum wlr_button_state state); enum wlr_button_state state);

View file

@ -62,4 +62,6 @@ struct input_config *input_device_get_config(struct sway_input_device *device);
char *input_device_get_identifier(struct wlr_input_device *device); char *input_device_get_identifier(struct wlr_input_device *device);
const char *input_device_get_type(struct sway_input_device *device);
#endif #endif

View file

@ -65,6 +65,8 @@ struct sway_keyboard {
struct sway_binding *repeat_binding; struct sway_binding *repeat_binding;
}; };
struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic);
struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
struct sway_seat_device *device); struct sway_seat_device *device);

View file

@ -9,18 +9,25 @@
struct sway_seat; struct sway_seat;
struct sway_seatop_impl { struct sway_seatop_impl {
void (*motion)(struct sway_seat *seat, uint32_t time_msec); void (*button)(struct sway_seat *seat, uint32_t time_msec,
void (*finish)(struct sway_seat *seat); struct wlr_input_device *device, uint32_t button,
void (*abort)(struct sway_seat *seat); enum wlr_button_state state);
void (*motion)(struct sway_seat *seat, uint32_t time_msec,
double dx, double dy);
void (*axis)(struct sway_seat *seat, struct wlr_event_pointer_axis *event);
void (*rebase)(struct sway_seat *seat, uint32_t time_msec);
void (*end)(struct sway_seat *seat);
void (*unref)(struct sway_seat *seat, struct sway_container *con); void (*unref)(struct sway_seat *seat, struct sway_container *con);
void (*render)(struct sway_seat *seat, struct sway_output *output, void (*render)(struct sway_seat *seat, struct sway_output *output,
pixman_region32_t *damage); pixman_region32_t *damage);
bool allow_set_cursor;
}; };
struct sway_seat_device { struct sway_seat_device {
struct sway_seat *sway_seat; struct sway_seat *sway_seat;
struct sway_input_device *input_device; struct sway_input_device *input_device;
struct sway_keyboard *keyboard; struct sway_keyboard *keyboard;
struct sway_switch *switch_device;
struct wl_list link; // sway_seat::devices struct wl_list link; // sway_seat::devices
}; };
@ -68,14 +75,13 @@ struct sway_seat {
// Seat operations (drag and resize) // Seat operations (drag and resize)
const struct sway_seatop_impl *seatop_impl; const struct sway_seatop_impl *seatop_impl;
void *seatop_data; void *seatop_data;
uint32_t seatop_button;
uint32_t last_button;
uint32_t last_button_serial; uint32_t last_button_serial;
struct wl_listener focus_destroy; struct wl_listener focus_destroy;
struct wl_listener new_node; struct wl_listener new_node;
struct wl_listener new_drag_icon; struct wl_listener request_start_drag;
struct wl_listener start_drag;
struct wl_listener request_set_selection; struct wl_listener request_set_selection;
struct wl_listener request_set_primary_selection; struct wl_listener request_set_primary_selection;
@ -137,6 +143,11 @@ struct sway_node *seat_get_focus(struct sway_seat *seat);
struct sway_workspace *seat_get_focused_workspace(struct sway_seat *seat); struct sway_workspace *seat_get_focused_workspace(struct sway_seat *seat);
// If a scratchpad container is fullscreen global, this can be used to try to
// determine the last focused workspace. Otherwise, this should yield the same
// results as seat_get_focused_workspace.
struct sway_workspace *seat_get_last_known_workspace(struct sway_seat *seat);
struct sway_container *seat_get_focused_container(struct sway_seat *seat); struct sway_container *seat_get_focused_container(struct sway_seat *seat);
/** /**
@ -184,23 +195,25 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface);
void drag_icon_update_position(struct sway_drag_icon *icon); void drag_icon_update_position(struct sway_drag_icon *icon);
void seatop_begin_down(struct sway_seat *seat, void seatop_begin_default(struct sway_seat *seat);
struct sway_container *con, uint32_t button, int sx, int sy);
void seatop_begin_down(struct sway_seat *seat, struct sway_container *con,
uint32_t time_msec, int sx, int sy);
void seatop_begin_move_floating(struct sway_seat *seat, void seatop_begin_move_floating(struct sway_seat *seat,
struct sway_container *con, uint32_t button); struct sway_container *con);
void seatop_begin_move_tiling_threshold(struct sway_seat *seat, void seatop_begin_move_tiling_threshold(struct sway_seat *seat,
struct sway_container *con, uint32_t button); struct sway_container *con);
void seatop_begin_move_tiling(struct sway_seat *seat, void seatop_begin_move_tiling(struct sway_seat *seat,
struct sway_container *con, uint32_t button); struct sway_container *con);
void seatop_begin_resize_floating(struct sway_seat *seat, void seatop_begin_resize_floating(struct sway_seat *seat,
struct sway_container *con, uint32_t button, enum wlr_edges edge); struct sway_container *con, enum wlr_edges edge);
void seatop_begin_resize_tiling(struct sway_seat *seat, void seatop_begin_resize_tiling(struct sway_seat *seat,
struct sway_container *con, uint32_t button, enum wlr_edges edge); struct sway_container *con, enum wlr_edges edge);
struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
struct sway_workspace *workspace); struct sway_workspace *workspace);
@ -210,19 +223,24 @@ void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
void seat_consider_warp_to_focus(struct sway_seat *seat); void seat_consider_warp_to_focus(struct sway_seat *seat);
bool seat_doing_seatop(struct sway_seat *seat); void seatop_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
void seatop_motion(struct sway_seat *seat, uint32_t time_msec); enum wlr_button_state state);
/** /**
* End a seatop and apply the affects. * dx and dy are distances relative to previous position.
*/ */
void seatop_finish(struct sway_seat *seat); void seatop_motion(struct sway_seat *seat, uint32_t time_msec,
double dx, double dy);
void seatop_axis(struct sway_seat *seat, struct wlr_event_pointer_axis *event);
void seatop_rebase(struct sway_seat *seat, uint32_t time_msec);
/** /**
* End a seatop without applying the affects. * End a seatop (ie. free any seatop specific resources).
*/ */
void seatop_abort(struct sway_seat *seat); void seatop_end(struct sway_seat *seat);
/** /**
* Instructs the seatop implementation to drop any references to the given * Instructs the seatop implementation to drop any references to the given
@ -238,5 +256,6 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con);
void seatop_render(struct sway_seat *seat, struct sway_output *output, void seatop_render(struct sway_seat *seat, struct sway_output *output,
pixman_region32_t *damage); pixman_region32_t *damage);
bool seatop_allows_set_cursor(struct sway_seat *seat);
#endif #endif

View file

@ -0,0 +1,19 @@
#ifndef _SWAY_INPUT_SWITCH_H
#define _SWAY_INPUT_SWITCH_H
#include "sway/input/seat.h"
struct sway_switch {
struct sway_seat_device *seat_device;
struct wl_listener switch_toggle;
};
struct sway_switch *sway_switch_create(struct sway_seat *seat,
struct sway_seat_device *device);
void sway_switch_configure(struct sway_switch *sway_switch);
void sway_switch_destroy(struct sway_switch *sway_switch);
#endif

View file

@ -29,16 +29,15 @@ struct sway_output {
struct timespec last_frame; struct timespec last_frame;
struct wlr_output_damage *damage; struct wlr_output_damage *damage;
int lx, ly; int lx, ly; // layout coords
int width, height; int width, height; // transformed buffer size
enum wl_output_subpixel detected_subpixel;
bool enabled, configured; bool enabled, configured;
list_t *workspaces; list_t *workspaces;
struct sway_output_state current; struct sway_output_state current;
struct wl_client *swaybg_client;
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener mode; struct wl_listener mode;
struct wl_listener transform; struct wl_listener transform;
@ -46,7 +45,6 @@ struct sway_output {
struct wl_listener present; struct wl_listener present;
struct wl_listener damage_destroy; struct wl_listener damage_destroy;
struct wl_listener damage_frame; struct wl_listener damage_frame;
struct wl_listener swaybg_client_destroy;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;
@ -84,11 +82,13 @@ void output_damage_box(struct sway_output *output, struct wlr_box *box);
void output_damage_whole_container(struct sway_output *output, void output_damage_whole_container(struct sway_output *output,
struct sway_container *con); struct sway_container *con);
// this ONLY includes the enabled outputs
struct sway_output *output_by_name_or_id(const char *name_or_id); struct sway_output *output_by_name_or_id(const char *name_or_id);
void output_sort_workspaces(struct sway_output *output); // this includes all the outputs, including disabled ones
struct sway_output *all_output_by_name_or_id(const char *name_or_id);
struct output_config *output_find_config(struct sway_output *output); void output_sort_workspaces(struct sway_output *output);
void output_enable(struct sway_output *output, struct output_config *oc); void output_enable(struct sway_output *output, struct output_config *oc);
@ -144,7 +144,7 @@ void output_get_box(struct sway_output *output, struct wlr_box *box);
enum sway_container_layout output_get_default_layout( enum sway_container_layout output_get_default_layout(
struct sway_output *output); struct sway_output *output);
void render_rect(struct wlr_output *wlr_output, void render_rect(struct sway_output *output,
pixman_region32_t *output_damage, const struct wlr_box *_box, pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]); float color[static 4]);
@ -154,4 +154,8 @@ void scale_box(struct wlr_box *box, float scale);
enum wlr_direction opposite_direction(enum wlr_direction d); enum wlr_direction opposite_direction(enum wlr_direction d);
void handle_output_manager_apply(struct wl_listener *listener, void *data);
void handle_output_manager_test(struct wl_listener *listener, void *data);
#endif #endif

View file

@ -8,6 +8,7 @@
#include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_presentation_time.h> #include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_relative_pointer_v1.h> #include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/types/wlr_server_decoration.h> #include <wlr/types/wlr_server_decoration.h>
@ -67,6 +68,10 @@ struct sway_server {
struct wlr_pointer_constraints_v1 *pointer_constraints; struct wlr_pointer_constraints_v1 *pointer_constraints;
struct wl_listener pointer_constraint; struct wl_listener pointer_constraint;
struct wlr_output_manager_v1 *output_manager_v1;
struct wl_listener output_manager_apply;
struct wl_listener output_manager_test;
size_t txn_timeout_ms; size_t txn_timeout_ms;
list_t *transactions; list_t *transactions;
list_t *dirty_nodes; list_t *dirty_nodes;
@ -74,6 +79,20 @@ struct sway_server {
struct sway_server server; struct sway_server server;
struct sway_debug {
bool noatomic; // Ignore atomic layout updates
bool txn_timings; // Log verbose messages about transactions
bool txn_wait; // Always wait for the timeout before applying
enum {
DAMAGE_DEFAULT, // Default behaviour
DAMAGE_HIGHLIGHT, // Highlight regions of the screen being damaged
DAMAGE_RERENDER, // Render the full output when any damage occurs
} damage;
};
struct sway_debug debug;
/* Prepares an unprivileged server_init by performing all privileged operations in advance */ /* Prepares an unprivileged server_init by performing all privileged operations in advance */
bool server_privileged_prepare(struct sway_server *server); bool server_privileged_prepare(struct sway_server *server);
bool server_init(struct sway_server *server); bool server_init(struct sway_server *server);

View file

@ -1,9 +1,12 @@
#ifndef _SWAY_SWAYNAG_H #ifndef _SWAY_SWAYNAG_H
#define _SWAY_SWAYNAG_H #define _SWAY_SWAYNAG_H
#include <wayland-server-core.h>
struct swaynag_instance { struct swaynag_instance {
struct wl_client *client;
struct wl_listener client_destroy;
const char *args; const char *args;
pid_t pid;
int fd[2]; int fd[2];
bool detailed; bool detailed;
}; };
@ -15,9 +18,6 @@ struct swaynag_instance {
bool swaynag_spawn(const char *swaynag_command, bool swaynag_spawn(const char *swaynag_command,
struct swaynag_instance *swaynag); struct swaynag_instance *swaynag);
// Kill the swaynag instance
void swaynag_kill(struct swaynag_instance *swaynag);
// Write a log message to swaynag->fd[1]. This will fail when swaynag->detailed // Write a log message to swaynag->fd[1]. This will fail when swaynag->detailed
// is false. // is false.
void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag, void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag,

View file

@ -212,10 +212,12 @@ void container_update_representation(struct sway_container *container);
*/ */
size_t container_titlebar_height(void); size_t container_titlebar_height(void);
/** void floating_calculate_constraints(int *min_width, int *max_width,
* Resize and center the container in its workspace. int *min_height, int *max_height);
*/
void container_init_floating(struct sway_container *container); void container_floating_resize_and_center(struct sway_container *con);
void container_floating_set_default_size(struct sway_container *con);
void container_set_floating(struct sway_container *container, bool enable); void container_set_floating(struct sway_container *container, bool enable);

View file

@ -21,8 +21,6 @@ struct sway_root {
#endif #endif
struct wl_list drag_icons; // sway_drag_icon::link struct wl_list drag_icons; // sway_drag_icon::link
struct wlr_texture *debug_tree;
// Includes disabled outputs // Includes disabled outputs
struct wl_list all_outputs; // sway_output::link struct wl_list all_outputs; // sway_output::link
@ -87,4 +85,6 @@ struct sway_container *root_find_container(
void root_get_box(struct sway_root *root, struct wlr_box *box); void root_get_box(struct sway_root *root, struct wlr_box *box);
void root_rename_pid_workspaces(const char *old_name, const char *new_name);
#endif #endif

View file

@ -192,8 +192,11 @@ struct sway_view_child_impl {
*/ */
struct sway_view_child { struct sway_view_child {
const struct sway_view_child_impl *impl; const struct sway_view_child_impl *impl;
struct wl_list link;
struct sway_view *view; struct sway_view *view;
struct sway_view_child *parent;
struct wl_list children; // sway_view_child::link
struct wlr_surface *surface; struct wlr_surface *surface;
bool mapped; bool mapped;
@ -202,6 +205,7 @@ struct sway_view_child {
struct wl_listener surface_map; struct wl_listener surface_map;
struct wl_listener surface_unmap; struct wl_listener surface_unmap;
struct wl_listener surface_destroy; struct wl_listener surface_destroy;
struct wl_listener view_unmap;
}; };
struct sway_subsurface { struct sway_subsurface {
@ -313,7 +317,7 @@ void view_destroy(struct sway_view *view);
void view_begin_destroy(struct sway_view *view); void view_begin_destroy(struct sway_view *view);
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, bool decoration); bool fullscreen, struct wlr_output *fullscreen_output, bool decoration);
void view_unmap(struct sway_view *view); void view_unmap(struct sway_view *view);

View file

@ -23,6 +23,7 @@ struct swaybar {
// only relevant when bar is in "hide" mode // only relevant when bar is in "hide" mode
bool visible_by_modifier; bool visible_by_modifier;
bool visible_by_urgency; bool visible_by_urgency;
bool visible_by_mode;
bool visible; bool visible;
struct wl_display *display; struct wl_display *display;
@ -30,10 +31,8 @@ struct swaybar {
struct zwlr_layer_shell_v1 *layer_shell; struct zwlr_layer_shell_v1 *layer_shell;
struct zxdg_output_manager_v1 *xdg_output_manager; struct zxdg_output_manager_v1 *xdg_output_manager;
struct wl_shm *shm; struct wl_shm *shm;
struct wl_seat *seat;
struct swaybar_config *config; struct swaybar_config *config;
struct swaybar_pointer pointer;
struct status_line *status; struct status_line *status;
struct loop *eventloop; struct loop *eventloop;
@ -42,6 +41,7 @@ struct swaybar {
int ipc_socketfd; int ipc_socketfd;
struct wl_list outputs; // swaybar_output::link struct wl_list outputs; // swaybar_output::link
struct wl_list seats; // swaybar_seat::link
#if HAVE_TRAY #if HAVE_TRAY
struct swaybar_tray *tray; struct swaybar_tray *tray;
@ -57,6 +57,7 @@ struct swaybar_output {
struct zxdg_output_v1 *xdg_output; struct zxdg_output_v1 *xdg_output;
struct wl_surface *surface; struct wl_surface *surface;
struct zwlr_layer_surface_v1 *layer_surface; struct zwlr_layer_surface_v1 *layer_surface;
struct wl_region *input_region;
uint32_t wl_name; uint32_t wl_name;
struct wl_list workspaces; // swaybar_workspace::link struct wl_list workspaces; // swaybar_workspace::link

View file

@ -22,6 +22,19 @@ struct swaybar_pointer {
uint32_t serial; uint32_t serial;
}; };
struct touch_slot {
int32_t id;
uint32_t time;
struct swaybar_output *output;
double start_x, start_y;
double x, y;
};
struct swaybar_touch {
struct wl_touch *touch;
struct touch_slot slots[16];
};
enum hotspot_event_handling { enum hotspot_event_handling {
HOTSPOT_IGNORE, HOTSPOT_IGNORE,
HOTSPOT_PROCESS, HOTSPOT_PROCESS,
@ -37,12 +50,23 @@ struct swaybar_hotspot {
void *data; void *data;
}; };
struct swaybar_seat {
struct swaybar *bar;
uint32_t wl_name;
struct wl_seat *wl_seat;
struct swaybar_pointer pointer;
struct swaybar_touch touch;
struct wl_list link; // swaybar_seat:link
};
extern const struct wl_seat_listener seat_listener; extern const struct wl_seat_listener seat_listener;
void update_cursor(struct swaybar *bar); void update_cursor(struct swaybar_seat *seat);
uint32_t event_to_x11_button(uint32_t event); uint32_t event_to_x11_button(uint32_t event);
void free_hotspots(struct wl_list *list); void free_hotspots(struct wl_list *list);
void swaybar_seat_free(struct swaybar_seat *seat);
#endif #endif

View file

@ -8,22 +8,26 @@ struct swaynag_type {
char *output; char *output;
uint32_t anchors; uint32_t anchors;
// Colors
uint32_t button_background; uint32_t button_background;
uint32_t background; uint32_t background;
uint32_t text; uint32_t text;
uint32_t border; uint32_t border;
uint32_t border_bottom; uint32_t border_bottom;
uint32_t bar_border_thickness; // Sizing
uint32_t message_padding; ssize_t bar_border_thickness;
uint32_t details_border_thickness; ssize_t message_padding;
uint32_t button_border_thickness; ssize_t details_border_thickness;
uint32_t button_gap; ssize_t button_border_thickness;
uint32_t button_gap_close; ssize_t button_gap;
uint32_t button_margin_right; ssize_t button_gap_close;
uint32_t button_padding; ssize_t button_margin_right;
ssize_t button_padding;
}; };
struct swaynag_type *swaynag_type_new(const char *name);
void swaynag_types_add_default(list_t *types); void swaynag_types_add_default(list_t *types);
struct swaynag_type *swaynag_type_get(list_t *types, char *name); struct swaynag_type *swaynag_type_get(list_t *types, char *name);

View file

@ -3,6 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <wayland-server-protocol.h>
/** /**
* Wrap i into the range [0, max[ * Wrap i into the range [0, max[
@ -29,4 +30,8 @@ bool parse_boolean(const char *boolean, bool current);
*/ */
float parse_float(const char *value); float parse_float(const char *value);
const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel);
bool set_cloexec(int fd, bool cloexec);
#endif #endif

View file

@ -1,7 +1,7 @@
project( project(
'sway', 'sway',
'c', 'c',
version: '1.0', version: '1.1',
license: 'MIT', license: 'MIT',
meson_version: '>=0.48.0', meson_version: '>=0.48.0',
default_options: [ default_options: [
@ -57,20 +57,22 @@ elogind = dependency('libelogind', version: '>=239', required: false)
xcb = dependency('xcb', required: get_option('xwayland')) xcb = dependency('xcb', required: get_option('xwayland'))
math = cc.find_library('m') math = cc.find_library('m')
rt = cc.find_library('rt') rt = cc.find_library('rt')
git = find_program('git', required: false) git = find_program('git', native: true, required: false)
# Try first to find wlroots as a subproject, then as a system dependency # Try first to find wlroots as a subproject, then as a system dependency
wlroots_version = '>=0.6'
wlroots_proj = subproject( wlroots_proj = subproject(
'wlroots', 'wlroots',
default_options: ['rootston=false', 'examples=false'], default_options: ['rootston=false', 'examples=false'],
required: false, required: false,
version: wlroots_version,
) )
if wlroots_proj.found() if wlroots_proj.found()
wlroots = wlroots_proj.get_variable('wlroots') wlroots = wlroots_proj.get_variable('wlroots')
wlroots_conf = wlroots_proj.get_variable('conf_data') wlroots_conf = wlroots_proj.get_variable('conf_data')
wlroots_has_xwayland = wlroots_conf.get('WLR_HAS_XWAYLAND') == 1 wlroots_has_xwayland = wlroots_conf.get('WLR_HAS_XWAYLAND') == 1
else else
wlroots = dependency('wlroots') wlroots = dependency('wlroots', version: wlroots_version)
wlroots_has_xwayland = cc.get_define('WLR_HAS_XWAYLAND', prefix: '#include <wlr/config.h>', dependencies: wlroots) == '1' wlroots_has_xwayland = cc.get_define('WLR_HAS_XWAYLAND', prefix: '#include <wlr/config.h>', dependencies: wlroots) == '1'
endif endif
@ -93,21 +95,19 @@ conf_data.set10('HAVE_SYSTEMD', systemd.found())
conf_data.set10('HAVE_ELOGIND', elogind.found()) conf_data.set10('HAVE_ELOGIND', elogind.found())
conf_data.set10('HAVE_TRAY', have_tray) conf_data.set10('HAVE_TRAY', have_tray)
if not systemd.found() and not elogind.found() scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-pages'))
warning('The sway binary must be setuid when compiled without (e)logind')
warning('You must do this manually post-install: chmod a+s /path/to/sway')
endif
scdoc = find_program('scdoc', required: get_option('man-pages'))
if scdoc.found() if scdoc.found()
sh = find_program('sh') scdoc_prog = find_program(scdoc.get_pkgconfig_variable('scdoc'), native: true)
sh = find_program('sh', native: true)
mandir = get_option('mandir') mandir = get_option('mandir')
man_files = [ man_files = [
'sway/sway.1.scd', 'sway/sway.1.scd',
'sway/sway.5.scd', 'sway/sway.5.scd',
'sway/sway-bar.5.scd', 'sway/sway-bar.5.scd',
'sway/sway-input.5.scd', 'sway/sway-input.5.scd',
'sway/sway-ipc.7.scd',
'sway/sway-output.5.scd', 'sway/sway-output.5.scd',
'swaybar/swaybar-protocol.7.scd',
'swaymsg/swaymsg.1.scd', 'swaymsg/swaymsg.1.scd',
'swaynag/swaynag.1.scd', 'swaynag/swaynag.1.scd',
'swaynag/swaynag.5.scd', 'swaynag/swaynag.5.scd',
@ -122,7 +122,7 @@ if scdoc.found()
input: filename, input: filename,
output: output, output: output,
command: [ command: [
sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc.path(), output) sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc_prog.path(), output)
], ],
install: true, install: true,
install_dir: '@0@/man@1@'.format(mandir, section) install_dir: '@0@/man@1@'.format(mandir, section)
@ -151,7 +151,6 @@ subdir('sway')
subdir('swaymsg') subdir('swaymsg')
subdir('client') subdir('client')
subdir('swaybg')
subdir('swaybar') subdir('swaybar')
subdir('swaynag') subdir('swaynag')
@ -235,3 +234,21 @@ if get_option('fish-completions')
install_data(fish_files, install_dir: fish_install_dir) install_data(fish_files, install_dir: fish_install_dir)
endif endif
status = [
'',
'Features:',
'xwayland: @0@'.format(have_xwayland),
'gdk-pixbuf: @0@'.format(gdk_pixbuf.found()),
'systemd: @0@'.format(systemd.found()),
'elogind: @0@'.format(elogind.found()),
'tray: @0@'.format(have_tray),
'man-pages: @0@'.format(scdoc.found()),
'',
]
message('\n'.join(status))
if not systemd.found() and not elogind.found()
warning('The sway binary must be setuid when compiled without (e)logind')
warning('You must do this manually post-install: chmod a+s /path/to/sway')
endif

View file

@ -1,5 +1,5 @@
[Desktop Entry] [Desktop Entry]
Name=Sway Name=Sway
Comment=SirCmpwn's Wayland window manager Comment=An i3-compatible Wayland compositor
Exec=sway Exec=sway
Type=Application Type=Application

View file

@ -47,6 +47,7 @@ static struct cmd_handler handlers[] = {
{ "assign", cmd_assign }, { "assign", cmd_assign },
{ "bar", cmd_bar }, { "bar", cmd_bar },
{ "bindcode", cmd_bindcode }, { "bindcode", cmd_bindcode },
{ "bindswitch", cmd_bindswitch },
{ "bindsym", cmd_bindsym }, { "bindsym", cmd_bindsym },
{ "client.background", cmd_client_noop }, { "client.background", cmd_client_noop },
{ "client.focused", cmd_client_focused }, { "client.focused", cmd_client_focused },
@ -76,8 +77,8 @@ static struct cmd_handler handlers[] = {
{ "input", cmd_input }, { "input", cmd_input },
{ "mode", cmd_mode }, { "mode", cmd_mode },
{ "mouse_warping", cmd_mouse_warping }, { "mouse_warping", cmd_mouse_warping },
{ "new_float", cmd_default_floating_border }, { "new_float", cmd_new_float },
{ "new_window", cmd_default_border }, { "new_window", cmd_new_window },
{ "no_focus", cmd_no_focus }, { "no_focus", cmd_no_focus },
{ "output", cmd_output }, { "output", cmd_output },
{ "popup_during_fullscreen", cmd_popup_during_fullscreen }, { "popup_during_fullscreen", cmd_popup_during_fullscreen },
@ -91,6 +92,9 @@ static struct cmd_handler handlers[] = {
{ "title_align", cmd_title_align }, { "title_align", cmd_title_align },
{ "titlebar_border_thickness", cmd_titlebar_border_thickness }, { "titlebar_border_thickness", cmd_titlebar_border_thickness },
{ "titlebar_padding", cmd_titlebar_padding }, { "titlebar_padding", cmd_titlebar_padding },
{ "unbindcode", cmd_unbindcode },
{ "unbindswitch", cmd_unbindswitch },
{ "unbindsym", cmd_unbindsym },
{ "workspace", cmd_workspace }, { "workspace", cmd_workspace },
{ "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
}; };
@ -111,6 +115,7 @@ static struct cmd_handler command_handlers[] = {
{ "exit", cmd_exit }, { "exit", cmd_exit },
{ "floating", cmd_floating }, { "floating", cmd_floating },
{ "fullscreen", cmd_fullscreen }, { "fullscreen", cmd_fullscreen },
{ "inhibit_idle", cmd_inhibit_idle },
{ "kill", cmd_kill }, { "kill", cmd_kill },
{ "layout", cmd_layout }, { "layout", cmd_layout },
{ "mark", cmd_mark }, { "mark", cmd_mark },
@ -255,7 +260,8 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
int argc; int argc;
char **argv = split_args(cmd, &argc); char **argv = split_args(cmd, &argc);
if (strcmp(argv[0], "exec") != 0 && if (strcmp(argv[0], "exec") != 0 &&
strcmp(argv[0], "exec_always") != 0) { strcmp(argv[0], "exec_always") != 0 &&
strcmp(argv[0], "mode") != 0) {
int i; int i;
for (i = 1; i < argc; ++i) { for (i = 1; i < argc; ++i) {
if (*argv[i] == '\"' || *argv[i] == '\'') { if (*argv[i] == '\"' || *argv[i] == '\'') {
@ -274,7 +280,6 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
// Var replacement, for all but first argument of set // Var replacement, for all but first argument of set
for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) {
argv[i] = do_var_replacement(argv[i]); argv[i] = do_var_replacement(argv[i]);
unescape_string(argv[i]);
} }
if (!config->handler_context.using_criteria) { if (!config->handler_context.using_criteria) {
@ -385,7 +390,9 @@ struct cmd_results *config_command(char *exec, char **new_block) {
&& handler->handle != cmd_mode && handler->handle != cmd_mode
&& handler->handle != cmd_bindsym && handler->handle != cmd_bindsym
&& handler->handle != cmd_bindcode && handler->handle != cmd_bindcode
&& handler->handle != cmd_bindswitch
&& handler->handle != cmd_set && handler->handle != cmd_set
&& handler->handle != cmd_for_window
&& (*argv[i] == '\"' || *argv[i] == '\'')) { && (*argv[i] == '\"' || *argv[i] == '\'')) {
strip_quotes(argv[i]); strip_quotes(argv[i]);
} }

View file

@ -32,6 +32,8 @@ static struct cmd_handler bar_handlers[] = {
{ "tray_bindsym", bar_cmd_tray_bindsym }, { "tray_bindsym", bar_cmd_tray_bindsym },
{ "tray_output", bar_cmd_tray_output }, { "tray_output", bar_cmd_tray_output },
{ "tray_padding", bar_cmd_tray_padding }, { "tray_padding", bar_cmd_tray_padding },
{ "unbindcode", bar_cmd_unbindcode },
{ "unbindsym", bar_cmd_unbindsym },
{ "workspace_buttons", bar_cmd_workspace_buttons }, { "workspace_buttons", bar_cmd_workspace_buttons },
{ "wrap_scroll", bar_cmd_wrap_scroll }, { "wrap_scroll", bar_cmd_wrap_scroll },
}; };
@ -78,9 +80,18 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
} }
config->current_bar = bar; config->current_bar = bar;
++argv; --argc; ++argv; --argc;
} else if (!config->reading && strcmp(argv[0], "mode") != 0 &&
strcmp(argv[0], "hidden_state") != 0) {
if (is_subcommand(argv[0])) {
return cmd_results_new(CMD_INVALID, "No bar defined.");
} else {
return cmd_results_new(CMD_INVALID,
"Unknown/invalid command '%s'", argv[1]);
}
} }
if (!config->current_bar && config->reading) { if (!config->current_bar) {
if (config->reading) {
// Create new bar with default values // Create new bar with default values
struct bar_config *bar = default_bar_config(); struct bar_config *bar = default_bar_config();
if (!bar) { if (!bar) {
@ -89,7 +100,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
} }
// set bar id // set bar id
const int len = snprintf(NULL, 0, "bar-%d", config->bars->length - 1) + 1; int len = snprintf(NULL, 0, "bar-%d", config->bars->length - 1) + 1;
bar->id = malloc(len * sizeof(char)); bar->id = malloc(len * sizeof(char));
if (bar->id) { if (bar->id) {
snprintf(bar->id, len, "bar-%d", config->bars->length - 1); snprintf(bar->id, len, "bar-%d", config->bars->length - 1);
@ -101,6 +112,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
config->current_bar = bar; config->current_bar = bar;
sway_log(SWAY_DEBUG, "Creating bar %s", bar->id); sway_log(SWAY_DEBUG, "Creating bar %s", bar->id);
} }
}
if (find_handler(argv[0], bar_config_handlers, if (find_handler(argv[0], bar_config_handlers,
sizeof(bar_config_handlers))) { sizeof(bar_config_handlers))) {

View file

@ -9,14 +9,71 @@
#include "log.h" #include "log.h"
#include "stringop.h" #include "stringop.h"
static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code) { static struct cmd_results *binding_add(struct bar_binding *binding,
const char *command = code ? "bar bindcode" : "bar bindsym"; list_t *mode_bindings) {
struct cmd_results *error = NULL; const char *name = get_mouse_button_name(binding->button);
if ((error = checkarg(argc, command, EXPECTED_AT_LEAST, 2))) { bool overwritten = false;
return error; for (int i = 0; i < mode_bindings->length; i++) {
struct bar_binding *other = mode_bindings->items[i];
if (other->button == binding->button &&
other->release == binding->release) {
overwritten = true;
mode_bindings->items[i] = binding;
free_bar_binding(other);
sway_log(SWAY_DEBUG, "[bar %s] Updated binding for %u (%s)%s",
config->current_bar->id, binding->button, name,
binding->release ? " - release" : "");
break;
} }
if (!config->current_bar) { }
return cmd_results_new(CMD_FAILURE, "No bar defined."); if (!overwritten) {
list_add(mode_bindings, binding);
sway_log(SWAY_DEBUG, "[bar %s] Added binding for %u (%s)%s",
config->current_bar->id, binding->button, name,
binding->release ? " - release" : "");
}
return cmd_results_new(CMD_SUCCESS, NULL);
}
static struct cmd_results *binding_remove(struct bar_binding *binding,
list_t *mode_bindings) {
const char *name = get_mouse_button_name(binding->button);
for (int i = 0; i < mode_bindings->length; i++) {
struct bar_binding *other = mode_bindings->items[i];
if (other->button == binding->button &&
other->release == binding->release) {
sway_log(SWAY_DEBUG, "[bar %s] Unbound binding for %u (%s)%s",
config->current_bar->id, binding->button, name,
binding->release ? " - release" : "");
free_bar_binding(other);
free_bar_binding(binding);
list_del(mode_bindings, i);
return cmd_results_new(CMD_SUCCESS, NULL);
}
}
struct cmd_results *error = cmd_results_new(CMD_FAILURE, "Could not "
"find binding for [bar %s]" " Button %u (%s)%s",
config->current_bar->id, binding->button, name,
binding->release ? " - release" : "");
free_bar_binding(binding);
return error;
}
static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code,
bool unbind) {
int minargs = 2;
const char *command;
if (unbind) {
minargs--;
command = code ? "bar unbindcode" : "bar unbindsym";
} else {
command = code ? "bar bindcode" : "bar bindsym";
}
struct cmd_results *error = NULL;
if ((error = checkarg(argc, command, EXPECTED_AT_LEAST, minargs))) {
return error;
} }
struct bar_binding *binding = calloc(1, sizeof(struct bar_binding)); struct bar_binding *binding = calloc(1, sizeof(struct bar_binding));
@ -46,39 +103,27 @@ static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code) {
free_bar_binding(binding); free_bar_binding(binding);
return cmd_results_new(CMD_INVALID, "Unknown button %s", argv[0]); return cmd_results_new(CMD_INVALID, "Unknown button %s", argv[0]);
} }
const char *name = get_mouse_button_name(binding->button); list_t *bindings = config->current_bar->bindings;
if (unbind) {
return binding_remove(binding, bindings);
}
binding->command = join_args(argv + 1, argc - 1); binding->command = join_args(argv + 1, argc - 1);
return binding_add(binding, bindings);
list_t *bindings = config->current_bar->bindings;
bool overwritten = false;
for (int i = 0; i < bindings->length; i++) {
struct bar_binding *other = bindings->items[i];
if (other->button == binding->button &&
other->release == binding->release) {
overwritten = true;
bindings->items[i] = binding;
free_bar_binding(other);
sway_log(SWAY_DEBUG, "[bar %s] Updated binding for %u (%s)%s",
config->current_bar->id, binding->button, name,
binding->release ? " - release" : "");
break;
}
}
if (!overwritten) {
list_add(bindings, binding);
sway_log(SWAY_DEBUG, "[bar %s] Added binding for %u (%s)%s",
config->current_bar->id, binding->button, name,
binding->release ? " - release" : "");
}
return cmd_results_new(CMD_SUCCESS, NULL);
} }
struct cmd_results *bar_cmd_bindcode(int argc, char **argv) { struct cmd_results *bar_cmd_bindcode(int argc, char **argv) {
return bar_cmd_bind(argc, argv, true); return bar_cmd_bind(argc, argv, true, false);
} }
struct cmd_results *bar_cmd_bindsym(int argc, char **argv) { struct cmd_results *bar_cmd_bindsym(int argc, char **argv) {
return bar_cmd_bind(argc, argv, false); return bar_cmd_bind(argc, argv, false, false);
}
struct cmd_results *bar_cmd_unbindcode(int argc, char **argv) {
return bar_cmd_bind(argc, argv, true, true);
}
struct cmd_results *bar_cmd_unbindsym(int argc, char **argv) {
return bar_cmd_bind(argc, argv, false, true);
} }

View file

@ -10,9 +10,6 @@ struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) {
"binding_mode_indicator", EXPECTED_EQUAL_TO, 1))) { "binding_mode_indicator", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
config->current_bar->binding_mode_indicator = config->current_bar->binding_mode_indicator =
parse_boolean(argv[0], config->current_bar->binding_mode_indicator); parse_boolean(argv[0], config->current_bar->binding_mode_indicator);
if (config->current_bar->binding_mode_indicator) { if (config->current_bar->binding_mode_indicator) {

View file

@ -9,9 +9,6 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) {
if ((error = checkarg(argc, "font", EXPECTED_AT_LEAST, 1))) { if ((error = checkarg(argc, "font", EXPECTED_AT_LEAST, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
char *font = join_args(argv, argc); char *font = join_args(argv, argc);
free(config->current_bar->font); free(config->current_bar->font);
config->current_bar->font = font; config->current_bar->font = font;

View file

@ -13,9 +13,6 @@ struct cmd_results *bar_cmd_gaps(int argc, char **argv) {
if ((error = checkarg(argc, "gaps", EXPECTED_AT_MOST, 4))) { if ((error = checkarg(argc, "gaps", EXPECTED_AT_MOST, 4))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
int top = 0, right = 0, bottom = 0, left = 0; int top = 0, right = 0, bottom = 0, left = 0;

View file

@ -12,10 +12,6 @@ struct cmd_results *bar_cmd_icon_theme(int argc, char **argv) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
sway_log(SWAY_DEBUG, "[Bar %s] Setting icon theme to %s", sway_log(SWAY_DEBUG, "[Bar %s] Setting icon theme to %s",
config->current_bar->id, argv[0]); config->current_bar->id, argv[0]);
free(config->current_bar->icon_theme); free(config->current_bar->icon_theme);

View file

@ -20,6 +20,8 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
bar->mode = strdup("hide"); bar->mode = strdup("hide");
} else if (strcasecmp("invisible", mode) == 0) { } else if (strcasecmp("invisible", mode) == 0) {
bar->mode = strdup("invisible"); bar->mode = strdup("invisible");
} else if (strcasecmp("overlay", mode) == 0) {
bar->mode = strdup("overlay");
} else { } else {
return cmd_results_new(CMD_INVALID, "Invalid value %s", mode); return cmd_results_new(CMD_INVALID, "Invalid value %s", mode);
} }

View file

@ -10,10 +10,6 @@ struct cmd_results *bar_cmd_modifier(int argc, char **argv) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
uint32_t mod = 0; uint32_t mod = 0;
if (strcmp(argv[0], "none") != 0) { if (strcmp(argv[0], "none") != 0) {
list_t *split = split_string(argv[0], "+"); list_t *split = split_string(argv[0], "+");

View file

@ -10,9 +10,6 @@ struct cmd_results *bar_cmd_output(int argc, char **argv) {
if ((error = checkarg(argc, "output", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "output", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
const char *output = argv[0]; const char *output = argv[0];
list_t *outputs = config->current_bar->outputs; list_t *outputs = config->current_bar->outputs;

View file

@ -9,11 +9,8 @@ struct cmd_results *bar_cmd_pango_markup(int argc, char **argv) {
if ((error = checkarg(argc, "pango_markup", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "pango_markup", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) { config->current_bar->pango_markup =
return cmd_results_new(CMD_FAILURE, "No bar defined."); parse_boolean(argv[0], config->current_bar->pango_markup);
}
config->current_bar->pango_markup
= parse_boolean(argv[0], config->current_bar->pango_markup);
if (config->current_bar->pango_markup) { if (config->current_bar->pango_markup) {
sway_log(SWAY_DEBUG, "Enabling pango markup for bar: %s", sway_log(SWAY_DEBUG, "Enabling pango markup for bar: %s",
config->current_bar->id); config->current_bar->id);

View file

@ -9,9 +9,6 @@ struct cmd_results *bar_cmd_position(int argc, char **argv) {
if ((error = checkarg(argc, "position", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "position", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
char *valid[] = { "top", "bottom" }; char *valid[] = { "top", "bottom" };
for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) { for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) {
if (strcasecmp(valid[i], argv[0]) == 0) { if (strcasecmp(valid[i], argv[0]) == 0) {

View file

@ -8,9 +8,6 @@ struct cmd_results *bar_cmd_separator_symbol(int argc, char **argv) {
if ((error = checkarg(argc, "separator_symbol", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "separator_symbol", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
free(config->current_bar->separator_symbol); free(config->current_bar->separator_symbol);
config->current_bar->separator_symbol = strdup(argv[0]); config->current_bar->separator_symbol = strdup(argv[0]);
sway_log(SWAY_DEBUG, "Settings separator_symbol '%s' for bar: %s", sway_log(SWAY_DEBUG, "Settings separator_symbol '%s' for bar: %s",

View file

@ -8,9 +8,6 @@ struct cmd_results *bar_cmd_status_command(int argc, char **argv) {
if ((error = checkarg(argc, "status_command", EXPECTED_AT_LEAST, 1))) { if ((error = checkarg(argc, "status_command", EXPECTED_AT_LEAST, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
free(config->current_bar->status_command); free(config->current_bar->status_command);
config->current_bar->status_command = NULL; config->current_bar->status_command = NULL;

View file

@ -10,9 +10,6 @@ struct cmd_results *bar_cmd_strip_workspace_name(int argc, char **argv) {
"strip_workspace_name", EXPECTED_EQUAL_TO, 1))) { "strip_workspace_name", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
config->current_bar->strip_workspace_name = config->current_bar->strip_workspace_name =
parse_boolean(argv[0], config->current_bar->strip_workspace_name); parse_boolean(argv[0], config->current_bar->strip_workspace_name);

View file

@ -10,9 +10,6 @@ struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) {
"strip_workspace_numbers", EXPECTED_EQUAL_TO, 1))) { "strip_workspace_numbers", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
config->current_bar->strip_workspace_numbers = config->current_bar->strip_workspace_numbers =
parse_boolean(argv[0], config->current_bar->strip_workspace_numbers); parse_boolean(argv[0], config->current_bar->strip_workspace_numbers);

View file

@ -8,9 +8,6 @@ struct cmd_results *bar_cmd_swaybar_command(int argc, char **argv) {
if ((error = checkarg(argc, "swaybar_command", EXPECTED_AT_LEAST, 1))) { if ((error = checkarg(argc, "swaybar_command", EXPECTED_AT_LEAST, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
free(config->current_bar->swaybar_command); free(config->current_bar->swaybar_command);
config->current_bar->swaybar_command = join_args(argv, argc); config->current_bar->swaybar_command = join_args(argv, argc);
sway_log(SWAY_DEBUG, "Using custom swaybar command: %s", sway_log(SWAY_DEBUG, "Using custom swaybar command: %s",

View file

@ -12,9 +12,6 @@ static struct cmd_results *tray_bind(int argc, char **argv, bool code) {
if ((error = checkarg(argc, command, EXPECTED_EQUAL_TO, 2))) { if ((error = checkarg(argc, command, EXPECTED_EQUAL_TO, 2))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
struct tray_binding *binding = calloc(1, sizeof(struct tray_binding)); struct tray_binding *binding = calloc(1, sizeof(struct tray_binding));
if (!binding) { if (!binding) {

View file

@ -13,10 +13,6 @@ struct cmd_results *bar_cmd_tray_output(int argc, char **argv) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
list_t *outputs = config->current_bar->tray_outputs; list_t *outputs = config->current_bar->tray_outputs;
if (!outputs) { if (!outputs) {
config->current_bar->tray_outputs = outputs = create_list(); config->current_bar->tray_outputs = outputs = create_list();

View file

@ -15,9 +15,6 @@ struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
struct bar_config *bar = config->current_bar; struct bar_config *bar = config->current_bar;
char *end; char *end;

View file

@ -9,9 +9,6 @@ struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) {
if ((error = checkarg(argc, "workspace_buttons", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "workspace_buttons", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
config->current_bar->workspace_buttons = config->current_bar->workspace_buttons =
parse_boolean(argv[0], config->current_bar->workspace_buttons); parse_boolean(argv[0], config->current_bar->workspace_buttons);
if (config->current_bar->workspace_buttons) { if (config->current_bar->workspace_buttons) {

View file

@ -9,9 +9,6 @@ struct cmd_results *bar_cmd_wrap_scroll(int argc, char **argv) {
if ((error = checkarg(argc, "wrap_scroll", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "wrap_scroll", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "No bar defined.");
}
config->current_bar->wrap_scroll = config->current_bar->wrap_scroll =
parse_boolean(argv[0], config->current_bar->wrap_scroll); parse_boolean(argv[0], config->current_bar->wrap_scroll);
if (config->current_bar->wrap_scroll) { if (config->current_bar->wrap_scroll) {

View file

@ -24,11 +24,38 @@ void free_sway_binding(struct sway_binding *binding) {
} }
list_free_items_and_destroy(binding->keys); list_free_items_and_destroy(binding->keys);
list_free_items_and_destroy(binding->syms);
free(binding->input); free(binding->input);
free(binding->command); free(binding->command);
free(binding); free(binding);
} }
void free_switch_binding(struct sway_switch_binding *binding) {
if (!binding) {
return;
}
free(binding->command);
free(binding);
}
/**
* Returns true if the bindings have the same switch type and state combinations.
*/
static bool binding_switch_compare(struct sway_switch_binding *binding_a,
struct sway_switch_binding *binding_b) {
if (binding_a->type != binding_b->type) {
return false;
}
if (binding_a->state != binding_b->state) {
return false;
}
if ((binding_a->flags & BINDING_LOCKED) !=
(binding_b->flags & BINDING_LOCKED)) {
return false;
}
return true;
}
/** /**
* Returns true if the bindings have the same key and modifier combinations. * Returns true if the bindings have the same key and modifier combinations.
* Note that keyboard layout is not considered, so the bindings might actually * Note that keyboard layout is not considered, so the bindings might actually
@ -45,7 +72,7 @@ static bool binding_key_compare(struct sway_binding *binding_a,
} }
uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER
| BINDING_CONTENTS | BINDING_TITLEBAR; | BINDING_CONTENTS | BINDING_TITLEBAR | BINDING_LOCKED;
if ((binding_a->flags & conflict_generating_flags) != if ((binding_a->flags & conflict_generating_flags) !=
(binding_b->flags & conflict_generating_flags)) { (binding_b->flags & conflict_generating_flags)) {
return false; return false;
@ -174,12 +201,133 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
return NULL; return NULL;
} }
static struct cmd_results *switch_binding_add(
struct sway_switch_binding *binding, const char *bindtype,
const char *switchcombo, bool warn) {
list_t *mode_bindings = config->current_mode->switch_bindings;
// overwrite the binding if it already exists
bool overwritten = false;
for (int i = 0; i < mode_bindings->length; ++i) {
struct sway_switch_binding *config_binding = mode_bindings->items[i];
if (binding_switch_compare(binding, config_binding)) {
sway_log(SWAY_INFO, "Overwriting binding '%s' to `%s` from `%s`",
switchcombo, binding->command, config_binding->command);
if (warn) {
config_add_swaynag_warning("Overwriting binding"
"'%s' to `%s` from `%s`",
switchcombo, binding->command,
config_binding->command);
}
free_switch_binding(config_binding);
mode_bindings->items[i] = binding;
overwritten = true;
}
}
if (!overwritten) {
list_add(mode_bindings, binding);
sway_log(SWAY_DEBUG, "%s - Bound %s to command `%s`",
bindtype, switchcombo, binding->command);
}
return cmd_results_new(CMD_SUCCESS, NULL);
}
static struct cmd_results *switch_binding_remove(
struct sway_switch_binding *binding, const char *bindtype,
const char *switchcombo) {
list_t *mode_bindings = config->current_mode->switch_bindings;
for (int i = 0; i < mode_bindings->length; ++i) {
struct sway_switch_binding *config_binding = mode_bindings->items[i];
if (binding_switch_compare(binding, config_binding)) {
free_switch_binding(config_binding);
free_switch_binding(binding);
list_del(mode_bindings, i);
sway_log(SWAY_DEBUG, "%s - Unbound %s switch",
bindtype, switchcombo);
return cmd_results_new(CMD_SUCCESS, NULL);
}
}
free_switch_binding(binding);
return cmd_results_new(CMD_FAILURE, "Could not find switch binding `%s`",
switchcombo);
}
/**
* Insert or update the binding.
* Return the binding which has been replaced or NULL.
*/
static struct sway_binding *binding_upsert(struct sway_binding *binding,
list_t *mode_bindings) {
for (int i = 0; i < mode_bindings->length; ++i) {
struct sway_binding *config_binding = mode_bindings->items[i];
if (binding_key_compare(binding, config_binding)) {
mode_bindings->items[i] = binding;
return config_binding;
}
}
list_add(mode_bindings, binding);
return NULL;
}
static struct cmd_results *binding_add(struct sway_binding *binding,
list_t *mode_bindings, const char *bindtype,
const char *keycombo, bool warn) {
struct sway_binding *config_binding = binding_upsert(binding, mode_bindings);
if (config_binding) {
sway_log(SWAY_INFO, "Overwriting binding '%s' for device '%s' "
"to `%s` from `%s`", keycombo, binding->input,
binding->command, config_binding->command);
if (warn) {
config_add_swaynag_warning("Overwriting binding"
"'%s' for device '%s' to `%s` from `%s`",
keycombo, binding->input, binding->command,
config_binding->command);
}
free_sway_binding(config_binding);
} else {
sway_log(SWAY_DEBUG, "%s - Bound %s to command `%s` for device '%s'",
bindtype, keycombo, binding->command, binding->input);
}
return cmd_results_new(CMD_SUCCESS, NULL);
}
static struct cmd_results *binding_remove(struct sway_binding *binding,
list_t *mode_bindings, const char *bindtype,
const char *keycombo) {
for (int i = 0; i < mode_bindings->length; ++i) {
struct sway_binding *config_binding = mode_bindings->items[i];
if (binding_key_compare(binding, config_binding)) {
sway_log(SWAY_DEBUG, "%s - Unbound `%s` from device '%s'",
bindtype, keycombo, binding->input);
free_sway_binding(config_binding);
free_sway_binding(binding);
list_del(mode_bindings, i);
return cmd_results_new(CMD_SUCCESS, NULL);
}
}
free_sway_binding(binding);
return cmd_results_new(CMD_FAILURE, "Could not find binding `%s` "
"for the given flags", keycombo);
}
static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
bool bindcode) { bool bindcode, bool unbind) {
const char *bindtype = bindcode ? "bindcode" : "bindsym"; const char *bindtype;
int minargs = 2;
if (unbind) {
bindtype = bindcode ? "unbindcode" : "unbindsym";
minargs--;
} else {
bindtype = bindcode ? "bindcode": "bindsym";
}
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, 2))) { if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) {
return error; return error;
} }
@ -196,7 +344,6 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
bool exclude_titlebar = false; bool exclude_titlebar = false;
bool warn = true; bool warn = true;
// Handle --release and --locked
while (argc > 0) { while (argc > 0) {
if (strcmp("--release", argv[0]) == 0) { if (strcmp("--release", argv[0]) == 0) {
binding->flags |= BINDING_RELEASE; binding->flags |= BINDING_RELEASE;
@ -206,6 +353,10 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
binding->flags |= BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR; binding->flags |= BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR;
} else if (strcmp("--border", argv[0]) == 0) { } else if (strcmp("--border", argv[0]) == 0) {
binding->flags |= BINDING_BORDER; binding->flags |= BINDING_BORDER;
} else if (strcmp("--to-code", argv[0]) == 0) {
if (!bindcode) {
binding->flags |= BINDING_CODE;
}
} else if (strcmp("--exclude-titlebar", argv[0]) == 0) { } else if (strcmp("--exclude-titlebar", argv[0]) == 0) {
exclude_titlebar = true; exclude_titlebar = true;
} else if (strncmp("--input-device=", argv[0], } else if (strncmp("--input-device=", argv[0],
@ -226,15 +377,14 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
BINDING_MOUSECODE : BINDING_MOUSESYM; BINDING_MOUSECODE : BINDING_MOUSESYM;
} }
if (argc < 2) { if (argc < minargs) {
free_sway_binding(binding); free_sway_binding(binding);
return cmd_results_new(CMD_FAILURE, return cmd_results_new(CMD_FAILURE,
"Invalid %s command " "Invalid %s command "
"(expected at least 2 non-option arguments, got %d)", bindtype, argc); "(expected at least %d non-option arguments, got %d)",
bindtype, minargs, argc);
} }
binding->command = join_args(argv + 1, argc - 1);
list_t *split = split_string(argv[0], "+"); list_t *split = split_string(argv[0], "+");
for (int i = 0; i < split->length; ++i) { for (int i = 0; i < split->length; ++i) {
// Check for a modifier key // Check for a modifier key
@ -265,7 +415,6 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
list_add(binding->keys, key); list_add(binding->keys, key);
} }
list_free_items_and_destroy(split); list_free_items_and_destroy(split);
binding->order = binding_order++;
// refine region of interest for mouse binding once we are certain // refine region of interest for mouse binding once we are certain
// that this is one // that this is one
@ -279,6 +428,12 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
// sort ascending // sort ascending
list_qsort(binding->keys, key_qsort_cmp); list_qsort(binding->keys, key_qsort_cmp);
// translate keysyms into keycodes
if (!translate_binding(binding)) {
sway_log(SWAY_INFO,
"Unable to translate bindsym into bindcode: %s", argv[0]);
}
list_t *mode_bindings; list_t *mode_bindings;
if (binding->type == BINDING_KEYCODE) { if (binding->type == BINDING_KEYCODE) {
mode_bindings = config->current_mode->keycode_bindings; mode_bindings = config->current_mode->keycode_bindings;
@ -288,41 +443,116 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
mode_bindings = config->current_mode->mouse_bindings; mode_bindings = config->current_mode->mouse_bindings;
} }
// overwrite the binding if it already exists if (unbind) {
bool overwritten = false; return binding_remove(binding, mode_bindings, bindtype, argv[0]);
for (int i = 0; i < mode_bindings->length; ++i) {
struct sway_binding *config_binding = mode_bindings->items[i];
if (binding_key_compare(binding, config_binding)) {
sway_log(SWAY_INFO, "Overwriting binding '%s' for device '%s' "
"from `%s` to `%s`", argv[0], binding->input,
binding->command, config_binding->command);
if (warn) {
config_add_swaynag_warning("Overwriting binding"
"'%s' for device '%s' to `%s` from `%s`",
argv[0], binding->input, binding->command,
config_binding->command);
}
free_sway_binding(config_binding);
mode_bindings->items[i] = binding;
overwritten = true;
}
} }
if (!overwritten) { binding->command = join_args(argv + 1, argc - 1);
list_add(mode_bindings, binding); binding->order = binding_order++;
return binding_add(binding, mode_bindings, bindtype, argv[0], warn);
}
struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
bool unbind) {
int minargs = 2;
char *bindtype = "bindswitch";
if (unbind) {
minargs--;
bindtype = "unbindswitch";
} }
sway_log(SWAY_DEBUG, "%s - Bound %s to command `%s` for device '%s'", struct cmd_results *error = NULL;
bindtype, argv[0], binding->command, binding->input); if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) {
return cmd_results_new(CMD_SUCCESS, NULL); return error;
}
struct sway_switch_binding *binding = calloc(1, sizeof(struct sway_switch_binding));
if (!binding) {
return cmd_results_new(CMD_FAILURE, "Unable to allocate binding");
}
bool warn = true;
// Handle flags
while (argc > 0) {
if (strcmp("--locked", argv[0]) == 0) {
binding->flags |= BINDING_LOCKED;
} else if (strcmp("--no-warn", argv[0]) == 0) {
warn = false;
} else {
break;
}
argv++;
argc--;
}
if (argc < minargs) {
free(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (expected at least %d "
"non-option arguments, got %d)", bindtype, minargs, argc);
}
list_t *split = split_string(argv[0], ":");
if (split->length != 2) {
free_switch_binding(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (expected binding with the form "
"<switch>:<state>)", bindtype, argc);
}
if (strcmp(split->items[0], "tablet") == 0) {
binding->type = WLR_SWITCH_TYPE_TABLET_MODE;
} else if (strcmp(split->items[0], "lid") == 0) {
binding->type = WLR_SWITCH_TYPE_LID;
} else {
free_switch_binding(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (expected switch binding: "
"unknown switch %s)", bindtype, split->items[0]);
}
if (strcmp(split->items[1], "on") == 0) {
binding->state = WLR_SWITCH_STATE_ON;
} else if (strcmp(split->items[1], "off") == 0) {
binding->state = WLR_SWITCH_STATE_OFF;
} else if (strcmp(split->items[1], "toggle") == 0) {
binding->state = WLR_SWITCH_STATE_TOGGLE;
} else {
free_switch_binding(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command "
"(expected switch state: unknown state %d)",
bindtype, split->items[0]);
}
list_free_items_and_destroy(split);
if (unbind) {
return switch_binding_remove(binding, bindtype, argv[0]);
}
binding->command = join_args(argv + 1, argc - 1);
return switch_binding_add(binding, bindtype, argv[0], warn);
} }
struct cmd_results *cmd_bindsym(int argc, char **argv) { struct cmd_results *cmd_bindsym(int argc, char **argv) {
return cmd_bindsym_or_bindcode(argc, argv, false); return cmd_bindsym_or_bindcode(argc, argv, false, false);
} }
struct cmd_results *cmd_bindcode(int argc, char **argv) { struct cmd_results *cmd_bindcode(int argc, char **argv) {
return cmd_bindsym_or_bindcode(argc, argv, true); return cmd_bindsym_or_bindcode(argc, argv, true, false);
}
struct cmd_results *cmd_unbindsym(int argc, char **argv) {
return cmd_bindsym_or_bindcode(argc, argv, false, true);
}
struct cmd_results *cmd_unbindcode(int argc, char **argv) {
return cmd_bindsym_or_bindcode(argc, argv, true, true);
}
struct cmd_results *cmd_bindswitch(int argc, char **argv) {
return cmd_bind_or_unbind_switch(argc, argv, false);
}
struct cmd_results *cmd_unbindswitch(int argc, char **argv) {
return cmd_bind_or_unbind_switch(argc, argv, true);
} }
/** /**
@ -360,3 +590,115 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding)
ipc_event_binding(binding); ipc_event_binding(binding);
} }
} }
/**
* The last found keycode associated with the keysym
* and the total count of matches.
*/
struct keycode_matches {
xkb_keysym_t keysym;
xkb_keycode_t keycode;
int count;
};
/**
* Iterate through keycodes in the keymap to find ones matching
* the specified keysym.
*/
static void find_keycode(struct xkb_keymap *keymap,
xkb_keycode_t keycode, void *data) {
xkb_keysym_t keysym = xkb_state_key_get_one_sym(
config->keysym_translation_state, keycode);
if (keysym == XKB_KEY_NoSymbol) {
return;
}
struct keycode_matches *matches = data;
if (matches->keysym == keysym) {
matches->keycode = keycode;
matches->count++;
}
}
/**
* Return the keycode for the specified keysym.
*/
static struct keycode_matches get_keycode_for_keysym(xkb_keysym_t keysym) {
struct keycode_matches matches = {
.keysym = keysym,
.keycode = XKB_KEYCODE_INVALID,
.count = 0,
};
xkb_keymap_key_for_each(
xkb_state_get_keymap(config->keysym_translation_state),
find_keycode, &matches);
return matches;
}
bool translate_binding(struct sway_binding *binding) {
if ((binding->flags & BINDING_CODE) == 0) {
return true;
}
switch (binding->type) {
// a bindsym to translate
case BINDING_KEYSYM:
binding->syms = binding->keys;
binding->keys = create_list();
break;
// a bindsym to re-translate
case BINDING_KEYCODE:
list_free_items_and_destroy(binding->keys);
binding->keys = create_list();
break;
default:
return true;
}
for (int i = 0; i < binding->syms->length; ++i) {
xkb_keysym_t *keysym = binding->syms->items[i];
struct keycode_matches matches = get_keycode_for_keysym(*keysym);
if (matches.count != 1) {
sway_log(SWAY_INFO, "Unable to convert keysym %d into"
" a single keycode (found %d matches)",
*keysym, matches.count);
goto error;
}
xkb_keycode_t *keycode = malloc(sizeof(xkb_keycode_t));
if (!keycode) {
sway_log(SWAY_ERROR, "Unable to allocate memory for a keycode");
goto error;
}
*keycode = matches.keycode;
list_add(binding->keys, keycode);
}
list_qsort(binding->keys, key_qsort_cmp);
binding->type = BINDING_KEYCODE;
return true;
error:
list_free_items_and_destroy(binding->keys);
binding->type = BINDING_KEYSYM;
binding->keys = binding->syms;
binding->syms = NULL;
return false;
}
void binding_add_translated(struct sway_binding *binding,
list_t *mode_bindings) {
struct sway_binding *config_binding =
binding_upsert(binding, mode_bindings);
if (config_binding) {
sway_log(SWAY_INFO, "Overwriting binding for device '%s' "
"to `%s` from `%s`", binding->input,
binding->command, config_binding->command);
free_sway_binding(config_binding);
}
}

View file

@ -32,6 +32,11 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
seat_set_focus_container(config->handler_context.seat, container); seat_set_focus_container(config->handler_context.seat, container);
} }
if (container_is_scratchpad_hidden(container)) {
return cmd_results_new(CMD_INVALID,
"Can't change floating on hidden scratchpad container");
}
// If the container is in a floating split container, // If the container is in a floating split container,
// operate on the split container instead of the child. // operate on the split container instead of the child.
if (container_is_floating_or_child(container)) { if (container_is_floating_or_child(container)) {
@ -45,7 +50,10 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
container_set_floating(container, wants_floating); container_set_floating(container, wants_floating);
// Floating containers in the scratchpad should be ignored
if (container->workspace) {
arrange_workspace(container->workspace); arrange_workspace(container->workspace);
}
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

View file

@ -1,3 +1,4 @@
#include <float.h>
#include <strings.h> #include <strings.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include "log.h" #include "log.h"
@ -90,8 +91,9 @@ static struct sway_node *get_node_in_output_direction(
return &ws->node; return &ws->node;
} }
static struct sway_node *node_get_in_direction(struct sway_container *container, static struct sway_node *node_get_in_direction_tiling(
struct sway_seat *seat, enum wlr_direction dir) { struct sway_container *container, struct sway_seat *seat,
enum wlr_direction dir) {
struct sway_container *wrap_candidate = NULL; struct sway_container *wrap_candidate = NULL;
struct sway_container *current = container; struct sway_container *current = container;
while (current) { while (current) {
@ -172,6 +174,41 @@ static struct sway_node *node_get_in_direction(struct sway_container *container,
return NULL; return NULL;
} }
static struct sway_node *node_get_in_direction_floating(
struct sway_container *con, struct sway_seat *seat,
enum wlr_direction dir) {
double ref_lx = con->x + con->width / 2;
double ref_ly = con->y + con->height / 2;
double closest_distance = DBL_MAX;
struct sway_container *closest_con = NULL;
if (!con->workspace) {
return NULL;
}
for (int i = 0; i < con->workspace->floating->length; i++) {
struct sway_container *floater = con->workspace->floating->items[i];
if (floater == con) {
continue;
}
float distance = dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_RIGHT
? (floater->x + floater->width / 2) - ref_lx
: (floater->y + floater->height / 2) - ref_ly;
if (dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_UP) {
distance = -distance;
}
if (distance < 0) {
continue;
}
if (distance < closest_distance) {
closest_distance = distance;
closest_con = floater;
}
}
return closest_con ? &closest_con->node : NULL;
}
static struct cmd_results *focus_mode(struct sway_workspace *ws, static struct cmd_results *focus_mode(struct sway_workspace *ws,
struct sway_seat *seat, bool floating) { struct sway_seat *seat, bool floating) {
struct sway_container *new_focus = NULL; struct sway_container *new_focus = NULL;
@ -208,6 +245,11 @@ static struct cmd_results *focus_output(struct sway_seat *seat,
"There is no output with that name"); "There is no output with that name");
} }
struct sway_workspace *ws = seat_get_focused_workspace(seat); struct sway_workspace *ws = seat_get_focused_workspace(seat);
if (!ws) {
free(identifier);
return cmd_results_new(CMD_FAILURE,
"No focused workspace to base directions off of");
}
output = output_get_in_direction(ws->output, direction); output = output_get_in_direction(ws->output, direction);
if (!output) { if (!output) {
@ -279,6 +321,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
} }
seat_set_focus_container(seat, container); seat_set_focus_container(seat, container);
seat_consider_warp_to_focus(seat); seat_consider_warp_to_focus(seat);
container_raise_floating(container);
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }
@ -325,11 +368,19 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }
struct sway_node *next_focus = struct sway_node *next_focus = NULL;
node_get_in_direction(container, seat, direction); if (container_is_floating(container)) {
next_focus = node_get_in_direction_floating(container, seat, direction);
} else {
next_focus = node_get_in_direction_tiling(container, seat, direction);
}
if (next_focus) { if (next_focus) {
seat_set_focus(seat, next_focus); seat_set_focus(seat, next_focus);
seat_consider_warp_to_focus(seat); seat_consider_warp_to_focus(seat);
if (next_focus->type == N_CONTAINER) {
container_raise_floating(next_focus->sway_container);
}
} }
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);

View file

@ -1,9 +1,16 @@
#include <strings.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "log.h"
#include "util.h" #include "util.h"
struct cmd_results *cmd_force_focus_wrapping(int argc, char **argv) { struct cmd_results *cmd_force_focus_wrapping(int argc, char **argv) {
sway_log(SWAY_INFO, "Warning: force_focus_wrapping is deprecated. "
"Use focus_wrapping instead.");
if (config->reading) {
config_add_swaynag_warning("force_focus_wrapping is deprecated. "
"Use focus_wrapping instead.");
}
struct cmd_results *error = struct cmd_results *error =
checkarg(argc, "force_focus_wrapping", EXPECTED_EQUAL_TO, 1); checkarg(argc, "force_focus_wrapping", EXPECTED_EQUAL_TO, 1);
if (error) { if (error) {

View file

@ -26,6 +26,13 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
"Can't fullscreen an empty workspace"); "Can't fullscreen an empty workspace");
} }
// If in the scratchpad, operate on the highest container
if (container && !container->workspace) {
while (container->parent) {
container = container->parent;
}
}
bool is_fullscreen = container && bool is_fullscreen = container &&
container->fullscreen_mode != FULLSCREEN_NONE; container->fullscreen_mode != FULLSCREEN_NONE;
bool global = false; bool global = false;

View file

@ -4,11 +4,25 @@
#include "sway/tree/view.h" #include "sway/tree/view.h"
struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) { struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
const char *expected_syntax = "Expected 'hide_edge_borders [--i3] "
"none|vertical|horizontal|both|smart|smart_no_gaps";
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, "hide_edge_borders", EXPECTED_EQUAL_TO, 1))) { if ((error = checkarg(argc, "hide_edge_borders", EXPECTED_AT_LEAST, 1))) {
return error; return error;
} }
bool hide_lone_tab = false;
if (strcmp(*argv, "--i3") == 0) {
hide_lone_tab = true;
++argv;
--argc;
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_syntax);
}
if (strcmp(argv[0], "none") == 0) { if (strcmp(argv[0], "none") == 0) {
config->hide_edge_borders = E_NONE; config->hide_edge_borders = E_NONE;
} else if (strcmp(argv[0], "vertical") == 0) { } else if (strcmp(argv[0], "vertical") == 0) {
@ -22,9 +36,9 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
} else if (strcmp(argv[0], "smart_no_gaps") == 0) { } else if (strcmp(argv[0], "smart_no_gaps") == 0) {
config->hide_edge_borders = E_SMART_NO_GAPS; config->hide_edge_borders = E_SMART_NO_GAPS;
} else { } else {
return cmd_results_new(CMD_INVALID, "Expected 'hide_edge_borders " return cmd_results_new(CMD_INVALID, expected_syntax);
"<none|vertical|horizontal|both|smart|smart_no_gaps>'");
} }
config->hide_lone_tab = hide_lone_tab;
config->saved_edge_borders = config->hide_edge_borders; config->saved_edge_borders = config->hide_edge_borders;
arrange_root(); arrange_root();

View file

@ -7,11 +7,8 @@ struct cmd_results *cmd_include(int argc, char **argv) {
return error; return error;
} }
if (!load_include_configs(argv[0], config, // We don't care if the included config(s) fails to load.
&config->swaynag_config_errors)) { load_include_configs(argv[0], config, &config->swaynag_config_errors);
return cmd_results_new(CMD_INVALID,
"Failed to include sub configuration file: %s", argv[0]);
}
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

View file

@ -0,0 +1,51 @@
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/desktop/idle_inhibit_v1.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
struct cmd_results *cmd_inhibit_idle(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "inhibit_idle", EXPECTED_EQUAL_TO, 1))) {
return error;
}
struct sway_container *con = config->handler_context.container;
if (!con || !con->view) {
return cmd_results_new(CMD_INVALID,
"Only views can have idle inhibitors");
}
bool clear = false;
enum sway_idle_inhibit_mode mode;
if (strcmp(argv[0], "focus") == 0) {
mode = INHIBIT_IDLE_FOCUS;
} else if (strcmp(argv[0], "fullscreen") == 0) {
mode = INHIBIT_IDLE_FULLSCREEN;
} else if (strcmp(argv[0], "open") == 0) {
mode = INHIBIT_IDLE_OPEN;
} else if (strcmp(argv[0], "none") == 0) {
clear = true;
} else if (strcmp(argv[0], "visible") == 0) {
mode = INHIBIT_IDLE_VISIBLE;
} else {
return cmd_results_new(CMD_INVALID,
"Expected `inhibit_idle focus|fullscreen|open|none|visible`");
}
struct sway_idle_inhibitor_v1 *inhibitor =
sway_idle_inhibit_v1_user_inhibitor_for_view(con->view);
if (inhibitor) {
if (clear) {
sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor);
} else {
inhibitor->mode = mode;
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
}
} else if (!clear) {
sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode);
}
return cmd_results_new(CMD_SUCCESS, NULL);
}

View file

@ -39,6 +39,23 @@ static struct cmd_handler input_config_handlers[] = {
{ "xkb_numlock", input_cmd_xkb_numlock }, { "xkb_numlock", input_cmd_xkb_numlock },
}; };
/**
* Re-translate keysyms if a change in the input config could affect them.
*/
static void retranslate_keysyms(struct input_config *input_config) {
for (int i = 0; i < config->input_configs->length; ++i) {
struct input_config *ic = config->input_configs->items[i];
if (ic->xkb_layout) {
// this is the first config with xkb_layout
if (ic->identifier == input_config->identifier) {
translate_keysyms(ic);
}
return;
}
}
}
struct cmd_results *cmd_input(int argc, char **argv) { struct cmd_results *cmd_input(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, "input", EXPECTED_AT_LEAST, 2))) { if ((error = checkarg(argc, "input", EXPECTED_AT_LEAST, 2))) {
@ -73,6 +90,7 @@ struct cmd_results *cmd_input(int argc, char **argv) {
store_input_config(config->handler_context.input_config); store_input_config(config->handler_context.input_config);
input_manager_apply_input_config(ic); input_manager_apply_input_config(ic);
retranslate_keysyms(ic);
} else { } else {
free_input_config(config->handler_context.input_config); free_input_config(config->handler_context.input_config);
} }

View file

@ -147,8 +147,12 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
workspace->layout = new_layout; workspace->layout = new_layout;
workspace_update_representation(workspace); workspace_update_representation(workspace);
} }
if (root->fullscreen_global) {
arrange_root();
} else {
arrange_workspace(workspace); arrange_workspace(workspace);
} }
}
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }

View file

@ -12,7 +12,9 @@
// Must be in order for the bsearch // Must be in order for the bsearch
static struct cmd_handler mode_handlers[] = { static struct cmd_handler mode_handlers[] = {
{ "bindcode", cmd_bindcode }, { "bindcode", cmd_bindcode },
{ "bindsym", cmd_bindsym } { "bindswitch", cmd_bindswitch },
{ "bindsym", cmd_bindsym },
{ "set", cmd_set },
}; };
struct cmd_results *cmd_mode(int argc, char **argv) { struct cmd_results *cmd_mode(int argc, char **argv) {
@ -54,6 +56,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
mode->keysym_bindings = create_list(); mode->keysym_bindings = create_list();
mode->keycode_bindings = create_list(); mode->keycode_bindings = create_list();
mode->mouse_bindings = create_list(); mode->mouse_bindings = create_list();
mode->switch_bindings = create_list();
mode->pango = pango; mode->pango = pango;
list_add(config->modes, mode); list_add(config->modes, mode);
} }

View file

@ -28,6 +28,15 @@ static const char expected_syntax[] =
static struct sway_output *output_in_direction(const char *direction_string, static struct sway_output *output_in_direction(const char *direction_string,
struct sway_output *reference, int ref_lx, int ref_ly) { struct sway_output *reference, int ref_lx, int ref_ly) {
if (strcasecmp(direction_string, "current") == 0) {
struct sway_workspace *active_ws =
seat_get_focused_workspace(config->handler_context.seat);
if (!active_ws) {
return NULL;
}
return active_ws->output;
}
struct { struct {
char *name; char *name;
enum wlr_direction direction; enum wlr_direction direction;
@ -311,6 +320,7 @@ static bool container_move_in_direction(struct sway_container *container,
while (current) { while (current) {
list_t *siblings = container_get_siblings(current); list_t *siblings = container_get_siblings(current);
if (siblings) {
enum sway_container_layout layout = container_parent_layout(current); enum sway_container_layout layout = container_parent_layout(current);
int index = list_find(siblings, current); int index = list_find(siblings, current);
int desired = index + offs; int desired = index + offs;
@ -344,12 +354,14 @@ static bool container_move_in_direction(struct sway_container *container,
return true; return true;
} }
} }
}
current = current->parent; current = current->parent;
} }
// Maybe rejigger the workspace // Maybe rejigger the workspace
struct sway_workspace *ws = container->workspace; struct sway_workspace *ws = container->workspace;
if (ws) {
if (!is_parallel(ws->layout, move_dir)) { if (!is_parallel(ws->layout, move_dir)) {
workspace_rejigger(ws, container, move_dir); workspace_rejigger(ws, container, move_dir);
return true; return true;
@ -370,13 +382,15 @@ static bool container_move_in_direction(struct sway_container *container,
return true; return true;
} }
sway_log(SWAY_DEBUG, "Hit edge of output, nowhere else to go"); sway_log(SWAY_DEBUG, "Hit edge of output, nowhere else to go");
}
return false; return false;
} }
static struct cmd_results *cmd_move_container(int argc, char **argv) { static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, "move container/window", if ((error = checkarg(argc, "move container/window",
EXPECTED_AT_LEAST, 3))) { EXPECTED_AT_LEAST, 2))) {
return error; return error;
} }
@ -391,27 +405,9 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
container = workspace_wrap_children(workspace); container = workspace_wrap_children(workspace);
} }
bool no_auto_back_and_forth = false; if (container->fullscreen_mode == FULLSCREEN_GLOBAL) {
while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) { return cmd_results_new(CMD_FAILURE,
no_auto_back_and_forth = true; "Can't move fullscreen global container");
if (--argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax);
}
++argv;
}
while (strcasecmp(argv[1], "--no-auto-back-and-forth") == 0) {
no_auto_back_and_forth = true;
if (--argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax);
}
argv++;
}
while (strcasecmp(argv[1], "to") == 0) {
if (--argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax);
}
argv++;
} }
struct sway_seat *seat = config->handler_context.seat; struct sway_seat *seat = config->handler_context.seat;
@ -421,18 +417,18 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
struct sway_node *destination = NULL; struct sway_node *destination = NULL;
// determine destination // determine destination
if (strcasecmp(argv[1], "workspace") == 0) { if (strcasecmp(argv[0], "workspace") == 0) {
// move container to workspace x // move container to workspace x
struct sway_workspace *ws = NULL; struct sway_workspace *ws = NULL;
char *ws_name = NULL; char *ws_name = NULL;
if (strcasecmp(argv[2], "next") == 0 || if (strcasecmp(argv[1], "next") == 0 ||
strcasecmp(argv[2], "prev") == 0 || strcasecmp(argv[1], "prev") == 0 ||
strcasecmp(argv[2], "next_on_output") == 0 || strcasecmp(argv[1], "next_on_output") == 0 ||
strcasecmp(argv[2], "prev_on_output") == 0 || strcasecmp(argv[1], "prev_on_output") == 0 ||
strcasecmp(argv[2], "current") == 0) { strcasecmp(argv[1], "current") == 0) {
ws = workspace_by_name(argv[2]); ws = workspace_by_name(argv[1]);
} else if (strcasecmp(argv[2], "back_and_forth") == 0) { } else if (strcasecmp(argv[1], "back_and_forth") == 0) {
if (!(ws = workspace_by_name(argv[2]))) { if (!(ws = workspace_by_name(argv[1]))) {
if (seat->prev_workspace_name) { if (seat->prev_workspace_name) {
ws_name = strdup(seat->prev_workspace_name); ws_name = strdup(seat->prev_workspace_name);
} else { } else {
@ -441,19 +437,19 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
} }
} }
} else { } else {
if (strcasecmp(argv[2], "number") == 0) { if (strcasecmp(argv[1], "number") == 0) {
// move "container to workspace number x" // move [window|container] [to] "workspace number x"
if (argc < 4) { if (argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax); return cmd_results_new(CMD_INVALID, expected_syntax);
} }
if (!isdigit(argv[3][0])) { if (!isdigit(argv[2][0])) {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,
"Invalid workspace number '%s'", argv[3]); "Invalid workspace number '%s'", argv[2]);
} }
ws_name = join_args(argv + 3, argc - 3); ws_name = join_args(argv + 2, argc - 2);
ws = workspace_by_number(ws_name); ws = workspace_by_number(ws_name);
} else { } else {
ws_name = join_args(argv + 2, argc - 2); ws_name = join_args(argv + 1, argc - 1);
ws = workspace_by_name(ws_name); ws = workspace_by_name(ws_name);
} }
@ -473,7 +469,7 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
// We have to create the workspace, but if the container is // We have to create the workspace, but if the container is
// sticky and the workspace is going to be created on the same // sticky and the workspace is going to be created on the same
// output, we'll bail out first. // output, we'll bail out first.
if (container->is_sticky) { if (container->is_sticky && container_is_floating_or_child(container)) {
struct sway_output *new_output = struct sway_output *new_output =
workspace_get_initial_output(ws_name); workspace_get_initial_output(ws_name);
if (old_output == new_output) { if (old_output == new_output) {
@ -488,27 +484,27 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
free(ws_name); free(ws_name);
struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws); struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws);
destination = dst ? &dst->node : &ws->node; destination = dst ? &dst->node : &ws->node;
} else if (strcasecmp(argv[1], "output") == 0) { } else if (strcasecmp(argv[0], "output") == 0) {
struct sway_output *new_output = output_in_direction(argv[2], struct sway_output *new_output = output_in_direction(argv[1],
old_output, container->x, container->y); old_output, container->x, container->y);
if (!new_output) { if (!new_output) {
return cmd_results_new(CMD_FAILURE, return cmd_results_new(CMD_FAILURE,
"Can't find output with name/direction '%s'", argv[2]); "Can't find output with name/direction '%s'", argv[1]);
} }
destination = seat_get_focus_inactive(seat, &new_output->node); destination = seat_get_focus_inactive(seat, &new_output->node);
} else if (strcasecmp(argv[1], "mark") == 0) { } else if (strcasecmp(argv[0], "mark") == 0) {
struct sway_container *dest_con = container_find_mark(argv[2]); struct sway_container *dest_con = container_find_mark(argv[1]);
if (dest_con == NULL) { if (dest_con == NULL) {
return cmd_results_new(CMD_FAILURE, return cmd_results_new(CMD_FAILURE,
"Mark '%s' not found", argv[2]); "Mark '%s' not found", argv[1]);
} }
destination = &dest_con->node; destination = &dest_con->node;
} else { } else {
return cmd_results_new(CMD_INVALID, expected_syntax); return cmd_results_new(CMD_INVALID, expected_syntax);
} }
if (container->is_sticky && old_output && if (container->is_sticky && container_is_floating_or_child(container) &&
node_has_ancestor(destination, &old_output->node)) { old_output && node_has_ancestor(destination, &old_output->node)) {
return cmd_results_new(CMD_FAILURE, "Can't move sticky " return cmd_results_new(CMD_FAILURE, "Can't move sticky "
"container to another workspace on the same output"); "container to another workspace on the same output");
} }
@ -626,30 +622,32 @@ static void workspace_move_to_output(struct sway_workspace *workspace,
static struct cmd_results *cmd_move_workspace(int argc, char **argv) { static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, "move workspace", EXPECTED_AT_LEAST, 2))) { if ((error = checkarg(argc, "move workspace", EXPECTED_AT_LEAST, 1))) {
return error; return error;
} }
while (strcasecmp(argv[1], "to") == 0) { if (strcasecmp(argv[0], "output") == 0) {
if (--argc < 3) { --argc; ++argv;
return cmd_results_new(CMD_INVALID, expected_syntax);
}
++argv;
} }
if (strcasecmp(argv[1], "output") != 0) { if (!argc) {
return cmd_results_new(CMD_INVALID, expected_syntax); return cmd_results_new(CMD_INVALID,
"Expected 'move workspace to [output] <output>'");
} }
struct sway_workspace *workspace = config->handler_context.workspace; struct sway_workspace *workspace = config->handler_context.workspace;
if (!workspace) {
return cmd_results_new(CMD_FAILURE, "No workspace to move");
}
struct sway_output *old_output = workspace->output; struct sway_output *old_output = workspace->output;
int center_x = workspace->width / 2 + workspace->x, int center_x = workspace->width / 2 + workspace->x,
center_y = workspace->height / 2 + workspace->y; center_y = workspace->height / 2 + workspace->y;
struct sway_output *new_output = output_in_direction(argv[2], struct sway_output *new_output = output_in_direction(argv[0],
old_output, center_x, center_y); old_output, center_x, center_y);
if (!new_output) { if (!new_output) {
return cmd_results_new(CMD_FAILURE, return cmd_results_new(CMD_FAILURE,
"Can't find output with name/direction '%s'", argv[2]); "Can't find output with name/direction '%s'", argv[0]);
} }
workspace_move_to_output(workspace, new_output); workspace_move_to_output(workspace, new_output);
@ -662,9 +660,9 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
static struct cmd_results *cmd_move_in_direction( static struct cmd_results *cmd_move_in_direction(
enum wlr_direction direction, int argc, char **argv) { enum wlr_direction direction, int argc, char **argv) {
int move_amt = 10; int move_amt = 10;
if (argc > 1) { if (argc) {
char *inv; char *inv;
move_amt = (int)strtol(argv[1], &inv, 10); move_amt = (int)strtol(argv[0], &inv, 10);
if (*inv != '\0' && strcasecmp(inv, "px") != 0) { if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
return cmd_results_new(CMD_FAILURE, "Invalid distance specified"); return cmd_results_new(CMD_FAILURE, "Invalid distance specified");
} }
@ -756,7 +754,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
} }
if (!argc) { if (!argc) {
return cmd_results_new(CMD_FAILURE, expected_position_syntax); return cmd_results_new(CMD_INVALID, expected_position_syntax);
} }
bool absolute = false; bool absolute = false;
@ -766,17 +764,20 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
++argv; ++argv;
} }
if (!argc) { if (!argc) {
return cmd_results_new(CMD_FAILURE, expected_position_syntax); return cmd_results_new(CMD_INVALID, expected_position_syntax);
} }
if (strcmp(argv[0], "position") == 0) { if (strcmp(argv[0], "position") == 0) {
--argc; --argc;
++argv; ++argv;
} }
if (!argc) { if (!argc) {
return cmd_results_new(CMD_FAILURE, expected_position_syntax); return cmd_results_new(CMD_INVALID, expected_position_syntax);
} }
if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 || if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 ||
strcmp(argv[0], "pointer") == 0) { strcmp(argv[0], "pointer") == 0) {
if (absolute) {
return cmd_results_new(CMD_INVALID, expected_position_syntax);
}
struct sway_seat *seat = config->handler_context.seat; struct sway_seat *seat = config->handler_context.seat;
if (!seat->cursor) { if (!seat->cursor) {
return cmd_results_new(CMD_FAILURE, "No cursor device"); return cmd_results_new(CMD_FAILURE, "No cursor device");
@ -862,6 +863,18 @@ static struct cmd_results *cmd_move_to_scratchpad(void) {
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);
} }
static const char expected_full_syntax[] = "Expected "
"'move left|right|up|down [<amount> [px]]'"
" or 'move [--no-auto-back-and-forth] [window|container] [to] workspace"
" <name>|next|prev|next_on_output|prev_on_output|current|(number <num>)'"
" or 'move [window|container] [to] output <name/id>|left|right|up|down'"
" or 'move [window|container] [to] mark <mark>'"
" or 'move [window|container] [to] scratchpad'"
" or 'move workspace to [output] <name/id>|left|right|up|down'"
" or 'move [window|container] [to] [absolute] position <x> [px] <y> [px]'"
" or 'move [window|container] [to] [absolute] position center'"
" or 'move [window|container] [to] position mouse|cursor|pointer'";
struct cmd_results *cmd_move(int argc, char **argv) { struct cmd_results *cmd_move(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
@ -873,31 +886,55 @@ struct cmd_results *cmd_move(int argc, char **argv) {
} }
if (strcasecmp(argv[0], "left") == 0) { if (strcasecmp(argv[0], "left") == 0) {
return cmd_move_in_direction(WLR_DIRECTION_LEFT, argc, argv); return cmd_move_in_direction(WLR_DIRECTION_LEFT, --argc, ++argv);
} else if (strcasecmp(argv[0], "right") == 0) { } else if (strcasecmp(argv[0], "right") == 0) {
return cmd_move_in_direction(WLR_DIRECTION_RIGHT, argc, argv); return cmd_move_in_direction(WLR_DIRECTION_RIGHT, --argc, ++argv);
} else if (strcasecmp(argv[0], "up") == 0) { } else if (strcasecmp(argv[0], "up") == 0) {
return cmd_move_in_direction(WLR_DIRECTION_UP, argc, argv); return cmd_move_in_direction(WLR_DIRECTION_UP, --argc, ++argv);
} else if (strcasecmp(argv[0], "down") == 0) { } else if (strcasecmp(argv[0], "down") == 0) {
return cmd_move_in_direction(WLR_DIRECTION_DOWN, argc, argv); return cmd_move_in_direction(WLR_DIRECTION_DOWN, --argc, ++argv);
} else if ((strcasecmp(argv[0], "container") == 0 } else if (strcasecmp(argv[0], "workspace") == 0 && argc >= 2
|| strcasecmp(argv[0], "window") == 0) || && (strcasecmp(argv[1], "to") == 0 ||
(strcasecmp(argv[0], "--no-auto-back-and-forth") && argc >= 2 strcasecmp(argv[1], "output") == 0)) {
&& (strcasecmp(argv[1], "container") == 0 argc -= 2; argv += 2;
|| strcasecmp(argv[1], "window") == 0))) {
return cmd_move_container(argc, argv);
} else if (strcasecmp(argv[0], "workspace") == 0) {
return cmd_move_workspace(argc, argv); return cmd_move_workspace(argc, argv);
} else if (strcasecmp(argv[0], "scratchpad") == 0
|| (strcasecmp(argv[0], "to") == 0 && argc == 2
&& strcasecmp(argv[1], "scratchpad") == 0)) {
return cmd_move_to_scratchpad();
} else if (strcasecmp(argv[0], "position") == 0) {
return cmd_move_to_position(argc, argv);
} else if (strcasecmp(argv[0], "absolute") == 0) {
return cmd_move_to_position(argc, argv);
} else {
return cmd_results_new(CMD_INVALID, expected_syntax);
} }
return cmd_results_new(CMD_SUCCESS, NULL);
bool no_auto_back_and_forth = false;
if (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) {
no_auto_back_and_forth = true;
--argc; ++argv;
}
if (strcasecmp(argv[0], "window") == 0 ||
strcasecmp(argv[0], "container") == 0) {
--argc; ++argv;
}
if (strcasecmp(argv[0], "to") == 0) {
--argc; ++argv;
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_full_syntax);
}
// Only `move [window|container] [to] workspace` supports
// `--no-auto-back-and-forth` so treat others as invalid syntax
if (no_auto_back_and_forth && strcasecmp(argv[0], "workspace") != 0) {
return cmd_results_new(CMD_INVALID, expected_full_syntax);
}
if (strcasecmp(argv[0], "workspace") == 0 ||
strcasecmp(argv[0], "output") == 0 ||
strcasecmp(argv[0], "mark") == 0) {
return cmd_move_container(no_auto_back_and_forth, argc, argv);
} else if (strcasecmp(argv[0], "scratchpad") == 0) {
return cmd_move_to_scratchpad();
} else if (strcasecmp(argv[0], "position") == 0 ||
(argc > 1 && strcasecmp(argv[0], "absolute") == 0 &&
strcasecmp(argv[1], "position") == 0)) {
return cmd_move_to_position(argc, argv);
}
return cmd_results_new(CMD_INVALID, expected_full_syntax);
} }

13
sway/commands/new_float.c Normal file
View file

@ -0,0 +1,13 @@
#include "log.h"
#include "sway/commands.h"
#include "sway/config.h"
struct cmd_results *cmd_new_float(int argc, char **argv) {
sway_log(SWAY_INFO, "Warning: new_float is deprecated. "
"Use default_floating_border instead.");
if (config->reading) {
config_add_swaynag_warning("new_float is deprecated. "
"Use default_floating_border instead.");
}
return cmd_default_floating_border(argc, argv);
}

View file

@ -0,0 +1,13 @@
#include "log.h"
#include "sway/commands.h"
#include "sway/config.h"
struct cmd_results *cmd_new_window(int argc, char **argv) {
sway_log(SWAY_INFO, "Warning: new_window is deprecated. "
"Use default_border instead.");
if (config->reading) {
config_add_swaynag_warning("new_window is deprecated. "
"Use default_border instead.");
}
return cmd_default_border(argc, argv);
}

View file

@ -18,6 +18,8 @@ static struct cmd_handler output_handlers[] = {
{ "res", output_cmd_mode }, { "res", output_cmd_mode },
{ "resolution", output_cmd_mode }, { "resolution", output_cmd_mode },
{ "scale", output_cmd_scale }, { "scale", output_cmd_scale },
{ "subpixel", output_cmd_subpixel },
{ "toggle", output_cmd_toggle },
{ "transform", output_cmd_transform }, { "transform", output_cmd_transform },
}; };
@ -67,6 +69,8 @@ struct cmd_results *cmd_output(int argc, char **argv) {
config->handler_context.leftovers.argc = 0; config->handler_context.leftovers.argc = 0;
config->handler_context.leftovers.argv = NULL; config->handler_context.leftovers.argv = NULL;
bool background = output->background;
output = store_output_config(output); output = store_output_config(output);
// If reloading, the output configs will be applied after reading the // If reloading, the output configs will be applied after reading the
@ -74,6 +78,9 @@ struct cmd_results *cmd_output(int argc, char **argv) {
// workspace name is not given to re-enabled outputs. // workspace name is not given to re-enabled outputs.
if (!config->reloading) { if (!config->reloading) {
apply_output_config_to_outputs(output); apply_output_config_to_outputs(output);
if (background) {
spawn_swaybg();
}
} }
return cmd_results_new(CMD_SUCCESS, NULL); return cmd_results_new(CMD_SUCCESS, NULL);

View file

@ -20,6 +20,16 @@ static const char *bg_options[] = {
"tile", "tile",
}; };
static bool validate_color(const char *color) {
if (strlen(color) != 7 || color[0] != '#') {
return false;
}
char *ptr = NULL;
strtol(&color[1], &ptr, 16);
return *ptr == '\0';
}
struct cmd_results *output_cmd_background(int argc, char **argv) { struct cmd_results *output_cmd_background(int argc, char **argv) {
if (!config->handler_context.output_config) { if (!config->handler_context.output_config) {
return cmd_results_new(CMD_FAILURE, "Missing output config"); return cmd_results_new(CMD_FAILURE, "Missing output config");
@ -36,6 +46,10 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
struct output_config *output = config->handler_context.output_config; struct output_config *output = config->handler_context.output_config;
if (strcasecmp(argv[1], "solid_color") == 0) { if (strcasecmp(argv[1], "solid_color") == 0) {
if (!validate_color(argv[0])) {
return cmd_results_new(CMD_INVALID,
"Colors should be of the form #RRGGBB");
}
output->background = strdup(argv[0]); output->background = strdup(argv[0]);
output->background_option = strdup("solid_color"); output->background_option = strdup("solid_color");
output->background_fallback = NULL; output->background_fallback = NULL;
@ -130,6 +144,11 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
output->background_fallback = NULL; output->background_fallback = NULL;
if (argc && *argv[0] == '#') { if (argc && *argv[0] == '#') {
if (!validate_color(argv[0])) {
return cmd_results_new(CMD_INVALID,
"fallback color should be of the form #RRGGBB");
}
output->background_fallback = strdup(argv[0]); output->background_fallback = strdup(argv[0]);
argc--; argv++; argc--; argv++;

View file

@ -0,0 +1,36 @@
#include <string.h>
#include "log.h"
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/output.h"
struct cmd_results *output_cmd_subpixel(int argc, char **argv) {
if (!config->handler_context.output_config) {
return cmd_results_new(CMD_FAILURE, "Missing output config");
}
if (!argc) {
return cmd_results_new(CMD_INVALID, "Missing subpixel argument.");
}
enum wl_output_subpixel subpixel;
if (strcmp(*argv, "rgb") == 0) {
subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
} else if (strcmp(*argv, "bgr") == 0) {
subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
} else if (strcmp(*argv, "vrgb") == 0) {
subpixel = WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
} else if (strcmp(*argv, "vbgr") == 0) {
subpixel = WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
} else if (strcmp(*argv, "none") == 0) {
subpixel = WL_OUTPUT_SUBPIXEL_NONE;
} else {
return cmd_results_new(CMD_INVALID, "Invalid output subpixel.");
}
struct output_config *oc = config->handler_context.output_config;
config->handler_context.leftovers.argc = argc - 1;
config->handler_context.leftovers.argv = argv + 1;
oc->subpixel = subpixel;
return NULL;
}

View file

@ -0,0 +1,37 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/output.h"
struct cmd_results *output_cmd_toggle(int argc, char **argv) {
if (!config->handler_context.output_config) {
return cmd_results_new(CMD_FAILURE, "Missing output config");
}
struct output_config *oc = config->handler_context.output_config;
if (strcmp(oc->name, "*") == 0) {
return cmd_results_new(CMD_INVALID,
"Cannot apply toggle to all outputs.");
}
struct sway_output *sway_output = all_output_by_name_or_id(oc->name);
if (sway_output == NULL) {
return cmd_results_new(CMD_FAILURE,
"Cannot apply toggle to unknown output %s", oc->name);
}
oc = find_output_config(sway_output);
if (!oc || oc->enabled != 0) {
config->handler_context.output_config->enabled = 0;
} else {
config->handler_context.output_config->enabled = 1;
}
free(oc);
config->handler_context.leftovers.argc = argc;
config->handler_context.leftovers.argv = argv;
return NULL;
}

View file

@ -12,7 +12,8 @@ struct cmd_results *output_cmd_transform(int argc, char **argv) {
return cmd_results_new(CMD_INVALID, "Missing transform argument."); return cmd_results_new(CMD_INVALID, "Missing transform argument.");
} }
enum wl_output_transform transform; enum wl_output_transform transform;
if (strcmp(*argv, "normal") == 0) { if (strcmp(*argv, "normal") == 0 ||
strcmp(*argv, "0") == 0) {
transform = WL_OUTPUT_TRANSFORM_NORMAL; transform = WL_OUTPUT_TRANSFORM_NORMAL;
} else if (strcmp(*argv, "90") == 0) { } else if (strcmp(*argv, "90") == 0) {
transform = WL_OUTPUT_TRANSFORM_90; transform = WL_OUTPUT_TRANSFORM_90;

View file

@ -9,6 +9,7 @@
#include "sway/output.h" #include "sway/output.h"
#include "sway/tree/container.h" #include "sway/tree/container.h"
#include "sway/tree/workspace.h" #include "sway/tree/workspace.h"
#include "sway/tree/root.h"
static const char expected_syntax[] = static const char expected_syntax[] =
"Expected 'rename workspace <old_name> to <new_name>' or " "Expected 'rename workspace <old_name> to <new_name>' or "
@ -89,6 +90,9 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
} }
sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
root_rename_pid_workspaces(workspace->name, new_name);
free(workspace->name); free(workspace->name);
workspace->name = new_name; workspace->name = new_name;

View file

@ -66,45 +66,6 @@ static int parse_resize_amount(int argc, char **argv,
return 2; return 2;
} }
static void calculate_constraints(int *min_width, int *max_width,
int *min_height, int *max_height) {
struct sway_container *con = config->handler_context.container;
if (config->floating_minimum_width == -1) { // no minimum
*min_width = 0;
} else if (config->floating_minimum_width == 0) { // automatic
*min_width = 75;
} else {
*min_width = config->floating_minimum_width;
}
if (config->floating_minimum_height == -1) { // no minimum
*min_height = 0;
} else if (config->floating_minimum_height == 0) { // automatic
*min_height = 50;
} else {
*min_height = config->floating_minimum_height;
}
if (config->floating_maximum_width == -1 ||
container_is_scratchpad_hidden(con)) { // no max
*max_width = INT_MAX;
} else if (config->floating_maximum_width == 0) { // automatic
*max_width = con->workspace->width;
} else {
*max_width = config->floating_maximum_width;
}
if (config->floating_maximum_height == -1 ||
container_is_scratchpad_hidden(con)) { // no max
*max_height = INT_MAX;
} else if (config->floating_maximum_height == 0) { // automatic
*max_height = con->workspace->height;
} else {
*max_height = config->floating_maximum_height;
}
}
static uint32_t parse_resize_axis(const char *axis) { static uint32_t parse_resize_axis(const char *axis) {
if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) { if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) {
return AXIS_HORIZONTAL; return AXIS_HORIZONTAL;
@ -258,7 +219,8 @@ static struct cmd_results *resize_adjust_floating(uint32_t axis,
// Make sure we're not adjusting beyond floating min/max size // Make sure we're not adjusting beyond floating min/max size
int min_width, max_width, min_height, max_height; int min_width, max_width, min_height, max_height;
calculate_constraints(&min_width, &max_width, &min_height, &max_height); floating_calculate_constraints(&min_width, &max_width,
&min_height, &max_height);
if (con->width + grow_width < min_width) { if (con->width + grow_width < min_width) {
grow_width = min_width - con->width; grow_width = min_width - con->width;
} else if (con->width + grow_width > max_width) { } else if (con->width + grow_width > max_width) {
@ -383,7 +345,8 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
static struct cmd_results *resize_set_floating(struct sway_container *con, static struct cmd_results *resize_set_floating(struct sway_container *con,
struct resize_amount *width, struct resize_amount *height) { struct resize_amount *width, struct resize_amount *height) {
int min_width, max_width, min_height, max_height, grow_width = 0, grow_height = 0; int min_width, max_width, min_height, max_height, grow_width = 0, grow_height = 0;
calculate_constraints(&min_width, &max_width, &min_height, &max_height); floating_calculate_constraints(&min_width, &max_width,
&min_height, &max_height);
if (width->amount) { if (width->amount) {
switch (width->unit) { switch (width->unit) {

View file

@ -12,6 +12,11 @@ static void scratchpad_toggle_auto(void) {
struct sway_seat *seat = input_manager_current_seat(); struct sway_seat *seat = input_manager_current_seat();
struct sway_container *focus = seat_get_focused_container(seat); struct sway_container *focus = seat_get_focused_container(seat);
struct sway_workspace *ws = seat_get_focused_workspace(seat); struct sway_workspace *ws = seat_get_focused_workspace(seat);
if (!ws) {
sway_log(SWAY_DEBUG,
"No focused workspace to toggle scratchpad windows on");
return;
}
// If the focus is in a floating split container, // If the focus is in a floating split container,
// operate on the split container instead of the child. // operate on the split container instead of the child.

View file

@ -13,7 +13,8 @@ static struct cmd_results *do_split(int layout) {
struct sway_container *con = config->handler_context.container; struct sway_container *con = config->handler_context.container;
struct sway_workspace *ws = config->handler_context.workspace; struct sway_workspace *ws = config->handler_context.workspace;
if (con) { if (con) {
if (container_is_scratchpad_hidden(con)) { if (container_is_scratchpad_hidden(con) &&
con->fullscreen_mode != FULLSCREEN_GLOBAL) {
return cmd_results_new(CMD_FAILURE, return cmd_results_new(CMD_FAILURE,
"Cannot split a hidden scratchpad container"); "Cannot split a hidden scratchpad container");
} }

Some files were not shown because too many files have changed in this diff Show more