mirror of
https://github.com/swaywm/sway.git
synced 2025-02-17 14:54:27 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
c6066ac7e4
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,6 +6,7 @@ bin/
|
||||||
test/
|
test/
|
||||||
build/
|
build/
|
||||||
build-*/
|
build-*/
|
||||||
|
.cache/
|
||||||
.lvimrc
|
.lvimrc
|
||||||
config-debug
|
config-debug
|
||||||
wayland-*-protocol.*
|
wayland-*-protocol.*
|
||||||
|
|
91
README.ar.md
Normal file
91
README.ar.md
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
# sway
|
||||||
|
|
||||||
|
sway
|
||||||
|
|
||||||
|
هو مدير للمجموعات المركبة لـ[Wayland] متوافق مع [i3] -
|
||||||
|
|
||||||
|
إقرأ [الأسئلة الشائعة](https://github.com/swaywm/sway/wiki)
|
||||||
|
|
||||||
|
انضم الى [قناة IRC](https://web.libera.chat/gamja/?channels=#sway)
|
||||||
|
|
||||||
|
|
||||||
|
## تواقيع الإصدار
|
||||||
|
تٌوقع الإصدارات بـواسطة [E88F5E48] و تُنشر على [GitHub](https://github.com/swaywm/sway/releases)
|
||||||
|
|
||||||
|
## التثبيت
|
||||||
|
|
||||||
|
### بإستخدام الحزم
|
||||||
|
|
||||||
|
يتوفر Sway للعديد من التوزيعات، حاول تثبيت حزمة "sway" لتوزيعتك
|
||||||
|
### التجميع من المصدر
|
||||||
|
إطلع على [صفحة الويكي هذه](https://github.com/swaywm/sway/wiki/Development-Setup) إذا أردت بناء الـHEAD من sway و wlroots لأغراض الفحص والتطوير
|
||||||
|
|
||||||
|
تثبيت اللوازم:
|
||||||
|
* meson \*
|
||||||
|
* [wlroots]
|
||||||
|
* wayland
|
||||||
|
* wayland-protocols \*
|
||||||
|
* pcre2
|
||||||
|
* json-c
|
||||||
|
* pango
|
||||||
|
* cairo
|
||||||
|
* gdk-pixbuf2 (optional: system tray)
|
||||||
|
* [scdoc] (optional: man pages) \*
|
||||||
|
* git (optional: version info) \*
|
||||||
|
|
||||||
|
_\* Compile-time dep_
|
||||||
|
|
||||||
|
نفذ هذه الأوامر:
|
||||||
|
|
||||||
|
meson build/
|
||||||
|
ninja -C build/
|
||||||
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
|
## الإعدادات
|
||||||
|
|
||||||
|
إذا كنت بالفعل تستخدم i3، فعليك نسخ إعدادات i3 لديك إلى `~/.config/sway/config` وسوف تعمل تلقائياً.
|
||||||
|
|
||||||
|
و إلا عليك نسخ ملف الإعدادات النموذج إلى `config/sway/config` الموجود عادةً في `/etc/sway/config.`
|
||||||
|
|
||||||
|
|
||||||
|
## التشغيل
|
||||||
|
|
||||||
|
شغل `sway` بإستخدام أمر TTY.
|
||||||
|
قد يعمل بعض مدراء العرض مع أنهم غير مدعومون من sway
|
||||||
|
(gdm مثلاً يعمل بشكل جيد إلى حد ما)
|
||||||
|
|
||||||
|
[en]: https://github.com/swaywm/sway#readme
|
||||||
|
[ar]: README.ar.md
|
||||||
|
[cs]: README.cs.md
|
||||||
|
[de]: README.de.md
|
||||||
|
[dk]: README.dk.md
|
||||||
|
[es]: README.es.md
|
||||||
|
[fr]: README.fr.md
|
||||||
|
[ge]: README.ge.md
|
||||||
|
[gr]: README.gr.md
|
||||||
|
[hi]: README.hi.md
|
||||||
|
[hu]: README.hu.md
|
||||||
|
[ir]: README.ir.md
|
||||||
|
[it]: README.it.md
|
||||||
|
[ja]: README.ja.md
|
||||||
|
[ko]: README.ko.md
|
||||||
|
[nl]: README.nl.md
|
||||||
|
[no]: README.no.md
|
||||||
|
[pl]: README.pl.md
|
||||||
|
[pt]: README.pt.md
|
||||||
|
[ro]: README.ro.md
|
||||||
|
[ru]: README.ru.md
|
||||||
|
[sv]: README.sv.md
|
||||||
|
[tr]: README.tr.md
|
||||||
|
[uk]: README.uk.md
|
||||||
|
[zh-CN]: README.zh-CN.md
|
||||||
|
[zh-TW]: README.zh-TW.md
|
||||||
|
[i3]: https://i3wm.org/
|
||||||
|
[Wayland]: http://wayland.freedesktop.org/
|
||||||
|
[FAQ]: https://github.com/swaywm/sway/wiki
|
||||||
|
[IRC channel]: https://web.libera.chat/gamja/?channels=#sway
|
||||||
|
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||||
|
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||||
|
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||||
|
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||||
|
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
|
@ -43,12 +43,6 @@ Spusťte tyto příkazy:
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
Na systémech bez logind či seatd musíte binární soubor sway nastavit jako suid:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway svá root oprávnění zruší krátce po spuštění.
|
|
||||||
|
|
||||||
## Konfigurace
|
## Konfigurace
|
||||||
|
|
||||||
Pokud již používáte i3, zkopírujte svou konfiguraci i3 do `~/.config/sway/config`
|
Pokud již používáte i3, zkopírujte svou konfiguraci i3 do `~/.config/sway/config`
|
||||||
|
|
18
README.de.md
18
README.de.md
|
@ -5,13 +5,13 @@
|
||||||
Sway ist ein [i3](https://i3wm.org/)-kompatibler [Wayland]-Compositor. Lies die [FAQ]. Tritt dem [IRC Channel] bei (#sway on irc.libera.chat; Englisch).
|
Sway ist ein [i3](https://i3wm.org/)-kompatibler [Wayland]-Compositor. Lies die [FAQ]. Tritt dem [IRC Channel] bei (#sway on irc.libera.chat; Englisch).
|
||||||
|
|
||||||
## Signaturen
|
## Signaturen
|
||||||
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48] signiert und auf GitHub veröffentlicht.
|
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48] signiert und auf GitHub veröffentlicht signiert und [auf GitHub][GitHub 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.
|
|
||||||
|
|
||||||
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.
|
### Über die Paketverwaltung
|
||||||
|
|
||||||
|
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Versuche einfach das Packet "sway" zu installieren.
|
||||||
|
|
||||||
### Quellcode selbst kompilieren
|
### Quellcode selbst kompilieren
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ sway benötigt die folgenden Pakete:
|
||||||
* pango
|
* pango
|
||||||
* cairo
|
* cairo
|
||||||
* gdk-pixbuf2 (Optional, wird für das Benachrichtigungsfeld (System Tray) benötigt)
|
* gdk-pixbuf2 (Optional, wird für das Benachrichtigungsfeld (System Tray) benötigt)
|
||||||
* [scdoc]\* (Optional, wird für die Dokumentation (Man Pages) benötigt)
|
* [scdoc] (Optional, wird für die Dokumentation (Man Pages) benötigt)\*
|
||||||
* git\*
|
* git (Optional: Versionsinfo)\*
|
||||||
|
|
||||||
_\*Werden nur während des Kompilierens benötigt_
|
_\*Werden nur während des Kompilierens benötigt_
|
||||||
|
|
||||||
|
@ -37,12 +37,6 @@ Führe die folgenden Befehle aus:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
Falls dein System nicht logind benutzt, musst du sway noch die passenden Berechtigungen geben:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway läuft nur in der Startphase mit Root-Rechten.
|
|
||||||
|
|
||||||
## Konfiguration
|
## Konfiguration
|
||||||
|
|
||||||
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`.
|
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`.
|
||||||
|
|
|
@ -47,12 +47,6 @@ Kør følgende kommandoer:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
På systemer uden logind eller seatd skal du sætte SUID bit på sway filen:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway dropper 'root' tilladelser kort efter opstart.
|
|
||||||
|
|
||||||
## Konfiguration
|
## Konfiguration
|
||||||
|
|
||||||
Hvis du allerede bruger i3 kan du bare kopiere din i3 konfiguration til
|
Hvis du allerede bruger i3 kan du bare kopiere din i3 konfiguration til
|
||||||
|
|
|
@ -46,12 +46,6 @@ Desde su consola, ejecute las órdenes:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
En sistemas sin `logind`, necesitará cambiar los permisos del archivo compilado de sway:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway abandonará los permisos de super-usuario al poco de arrancar.
|
|
||||||
|
|
||||||
## Configuración
|
## Configuración
|
||||||
|
|
||||||
Si ya utiliza i3, copie su archivo de configuración de i3 a `~/.config/sway/config` y
|
Si ya utiliza i3, copie su archivo de configuración de i3 a `~/.config/sway/config` y
|
||||||
|
|
|
@ -53,12 +53,6 @@ Exécutez ces commandes :
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
Sur les systèmes sans logind, vous devez suid le binaire de 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 vers
|
Si vous utilisez déjà i3, copiez votre configuration i3 vers
|
||||||
|
|
61
README.ge.md
Normal file
61
README.ge.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# sway
|
||||||
|
|
||||||
|
sway არის [i3]-თავსებადი [Wayland]-ის კომპოზიტორი. მეტი ინფორმაციისთვის იხილეთ
|
||||||
|
[FAQ]. დაუკავშირდით [IRC არხს][IRC channel] \(#sway irc.libera.chat-ზე).
|
||||||
|
|
||||||
|
## გამოშვების ხელმოწერები
|
||||||
|
|
||||||
|
გამოშვებები ხელმოწერილია [E88F5E48]-ით და გამოქვეყნებულია [GitHub-ზე][GitHub releases].
|
||||||
|
|
||||||
|
## ინსტალაცია
|
||||||
|
|
||||||
|
### რეპოზიტორიიდან
|
||||||
|
|
||||||
|
Sway არის ხელმისაწვდომი ბევრი დისტრიბუტაციისთვის. ცადეთ "sway" პაკეტის ინსტალაცია თქვენთვის.
|
||||||
|
|
||||||
|
### კოდის კომპილაცია
|
||||||
|
|
||||||
|
იხილეთ [ეს ვიკი გვერდი][Development setup] თუ გინდათ რომ ააწყოთ sway და wlroots სატესტოდ ან დეველოპმენტისთვის.
|
||||||
|
|
||||||
|
დააინსტალირეთ დამოკიდებულებები:
|
||||||
|
|
||||||
|
* meson \*
|
||||||
|
* [wlroots]
|
||||||
|
* wayland
|
||||||
|
* wayland-protocols \*
|
||||||
|
* pcre2
|
||||||
|
* json-c
|
||||||
|
* pango
|
||||||
|
* cairo
|
||||||
|
* gdk-pixbuf2 (ასევე არჩევითია: system tray)
|
||||||
|
* [scdoc] (ასევე არჩევითია: man pages) \*
|
||||||
|
* git (ასევე არჩევითია: version info) \*
|
||||||
|
|
||||||
|
_\* Compile-time dep_
|
||||||
|
|
||||||
|
გაუშვით ეს ბრძანებები:
|
||||||
|
|
||||||
|
meson build/
|
||||||
|
ninja -C build/
|
||||||
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
|
## კონფიგურაცია
|
||||||
|
|
||||||
|
თუ უკვე იყენებთ i3-ს, მაშინ დააკოპირე i3 კონფიგურაცია და ჩასვი `~/.config/sway/config`
|
||||||
|
და უპრობლემოდ იმუშავებს პირდაპირ. წინააღმდეგ შემთხვევაში კონფიგურაციის ნიმუში ჩააკოპირეთ აქ: `~/.config/sway/config`. კომპიგურაციის ნიმუში ხშირ შემთხვევაში არის `/etc/sway/config`.
|
||||||
|
გაუშვი `man 5 sway` კონპიგურაციაზე ინფორმაციის მისაღებად.
|
||||||
|
|
||||||
|
## გაშვება
|
||||||
|
|
||||||
|
გაუშვი `sway` TTY-ისთვის. ზოგიერთმა ლოგინ მენეჯერმა შეიძლება იმუშავოს, მაგრამ არ
|
||||||
|
არის მხარდაჭერილი sway-სგან (როგორც წესი კარგად მუშაობს gdm).
|
||||||
|
|
||||||
|
[i3]: https://i3wm.org/
|
||||||
|
[Wayland]: http://wayland.freedesktop.org/
|
||||||
|
[FAQ]: https://github.com/swaywm/sway/wiki
|
||||||
|
[IRC channel]: https://web.libera.chat/gamja/?channels=#sway
|
||||||
|
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||||
|
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||||
|
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||||
|
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||||
|
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
|
@ -46,12 +46,6 @@ _\*Compile-time dep_
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
Σε συστήματα χωρίς logind ή seatd, πρέπει να κάνετε suid το sway binary:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Το Sway θα κάνει drop root δικαιώματα λίγο μετά την εκκίνηση.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Εάν ήδη χρησιμοποιήτε το i3, αντιγράψτε το i3 config σας στο `~/.config/sway/config` και
|
Εάν ήδη χρησιμοποιήτε το i3, αντιγράψτε το i3 config σας στο `~/.config/sway/config` και
|
||||||
|
|
|
@ -50,13 +50,6 @@ _\* Compilation के समय आवश्यक_
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
उन systems पर जिनमें ना तो logind है, ना ही seatd है, आपको sway की binary
|
|
||||||
को suid करना पडेगा:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway अपनी root अनुमतियां प्रारंभ होने के कुछ ही देर बाद छोड़ देगी।
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
अगर आप पहले से ही i3 का उपयोग करते हैं तो अपने i3 config को
|
अगर आप पहले से ही i3 का उपयोग करते हैं तो अपने i3 config को
|
||||||
|
|
|
@ -46,13 +46,6 @@ Futtasd ezeket a parancsokat:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
Ha `logind` nélküli rendszert használsz, akkor be kell állítanod a `suid` bitet
|
|
||||||
a futtaható állományon:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
A Sway indulás után nem sokkal el fogja engedni a root jogosultságait.
|
|
||||||
|
|
||||||
## Konfiguráció
|
## Konfiguráció
|
||||||
|
|
||||||
Ha előzőleg i3-mat használtál, akkor átmásolhatod az i3 beállításaidat a
|
Ha előzőleg i3-mat használtál, akkor átmásolhatod az i3 beállításaidat a
|
||||||
|
|
|
@ -47,12 +47,6 @@ _\*نیازمندیهای زمان کامپایل برنامه_
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
روی سیستمهای بدون logind، باید فرمان زیر را برای suid کردن باینری sway اجرا کنید:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
‏sway پس از startup مجوزهای دسترسی root را رها میکند.
|
|
||||||
|
|
||||||
### شخصی سازی و تنظیمات
|
### شخصی سازی و تنظیمات
|
||||||
|
|
||||||
اگر در حال حاضر از i3 استفاده میکنید، تنظیمات i3 خودتان را در فایل `~/.config/sway/config` کپی کنید و بدون نیاز به تغییر کار خواهد کرد. در غیر اینصورت، فایل نمونه تنظیمات را استفاده کنید. این فایل عموما در `/etc/sway/config` قرار دارد. برای آگاهی بیشتر `man 5 sway` را اجرا کنید.
|
اگر در حال حاضر از i3 استفاده میکنید، تنظیمات i3 خودتان را در فایل `~/.config/sway/config` کپی کنید و بدون نیاز به تغییر کار خواهد کرد. در غیر اینصورت، فایل نمونه تنظیمات را استفاده کنید. این فایل عموما در `/etc/sway/config` قرار دارد. برای آگاهی بیشتر `man 5 sway` را اجرا کنید.
|
||||||
|
|
|
@ -44,13 +44,6 @@ Esegui questi comandi:
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
Nei sistemi in cui non sono disponibili né logind né seatd, è necessario
|
|
||||||
impostare il permesso suid al binario di sway:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway rinuncerà ai permessi di root poco dopo l'avvio.
|
|
||||||
|
|
||||||
## Configurazione
|
## Configurazione
|
||||||
|
|
||||||
Se hai già usato i3, copia il tuo file di configurazione in
|
Se hai già usato i3, copia il tuo file di configurazione in
|
||||||
|
|
|
@ -45,12 +45,6 @@ _\*컴파일 떄 필요_
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
logind를 사용하고 있지 않는 시스템에서는, 바이너리에 suid를 설정할 필요가 있습니다:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway는 시작 후에 root 권한을 drop할 것 입니다.
|
|
||||||
|
|
||||||
## 설정
|
## 설정
|
||||||
|
|
||||||
i3를 이미 사용 중이라면, i3 config을 `~/.config/sway/config`로 복사하세요.
|
i3를 이미 사용 중이라면, i3 config을 `~/.config/sway/config`로 복사하세요.
|
||||||
|
|
10
README.md
10
README.md
|
@ -1,6 +1,6 @@
|
||||||
# sway
|
# sway
|
||||||
|
|
||||||
**[English][en]** - [Česky][cs] - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
**[English][en]** - [عربي][ar] - [Česky][cs] - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [ქართული][ge] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||||
|
|
||||||
sway is an [i3]-compatible [Wayland] compositor. Read the [FAQ]. Join the
|
sway is an [i3]-compatible [Wayland] compositor. Read the [FAQ]. Join the
|
||||||
[IRC channel] \(#sway on irc.libera.chat).
|
[IRC channel] \(#sway on irc.libera.chat).
|
||||||
|
@ -43,12 +43,6 @@ Run these commands:
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
On systems without logind nor seatd, you need to suid the sway binary:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway will drop root permissions shortly after startup.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
If you already use i3, then copy your i3 config to `~/.config/sway/config` and
|
If you already use i3, then copy your i3 config to `~/.config/sway/config` and
|
||||||
|
@ -62,11 +56,13 @@ Run `sway` from a TTY. Some display managers may work but are not supported by
|
||||||
sway (gdm is known to work fairly well).
|
sway (gdm is known to work fairly well).
|
||||||
|
|
||||||
[en]: https://github.com/swaywm/sway#readme
|
[en]: https://github.com/swaywm/sway#readme
|
||||||
|
[ar]: README.ar.md
|
||||||
[cs]: README.cs.md
|
[cs]: README.cs.md
|
||||||
[de]: README.de.md
|
[de]: README.de.md
|
||||||
[dk]: README.dk.md
|
[dk]: README.dk.md
|
||||||
[es]: README.es.md
|
[es]: README.es.md
|
||||||
[fr]: README.fr.md
|
[fr]: README.fr.md
|
||||||
|
[ge]: README.ge.md
|
||||||
[gr]: README.gr.md
|
[gr]: README.gr.md
|
||||||
[hi]: README.hi.md
|
[hi]: README.hi.md
|
||||||
[hu]: README.hu.md
|
[hu]: README.hu.md
|
||||||
|
|
|
@ -46,12 +46,6 @@ Voer deze opdrachten uit:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
Op systemen zonder logind, moet je bij het binaire bestand het suid bit instellen:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway zal root-rechten kort na het opstarten loslaten.
|
|
||||||
|
|
||||||
## Configuratie
|
## Configuratie
|
||||||
|
|
||||||
Als je al i3 gebruikt, kopieer dan je i3-configuratie naar `~/.config/sway/config` en
|
Als je al i3 gebruikt, kopieer dan je i3-configuratie naar `~/.config/sway/config` en
|
||||||
|
|
|
@ -46,12 +46,6 @@ Wykonaj następujące polecenia:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
Na systemach bez logind należy wykonać polecenie suid na pliku wykonywalnym sway:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway pozbędzie się uprawnień roota tuż po wystartowaniu.
|
|
||||||
|
|
||||||
## Konfiguracja
|
## Konfiguracja
|
||||||
|
|
||||||
Jeśli już korzystasz z i3, skopiuj swoją konfigurację i3 do katalogu `~/.config/sway/config` i
|
Jeśli już korzystasz z i3, skopiuj swoją konfigurację i3 do katalogu `~/.config/sway/config` i
|
||||||
|
|
|
@ -48,12 +48,6 @@ Execute esses comandos:
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
Em sistemas sem logind, você precisa preparar o binário do sway:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
O sway perderá as privilégios de de root logo após o início do sistema.
|
|
||||||
|
|
||||||
## Configuração
|
## Configuração
|
||||||
|
|
||||||
Se você já utiliza o i3, então copie os seus arquivos de configuração para `~/.config/sway/config` e
|
Se você já utiliza o i3, então copie os seus arquivos de configuração para `~/.config/sway/config` e
|
||||||
|
|
|
@ -45,14 +45,6 @@ Rulați aceste comenzi:
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
```
|
```
|
||||||
|
|
||||||
Pe sisteme fără logind, trebuie să folosiți următoarea comandă pentru a marca binarul de Sway ca suid:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
```
|
|
||||||
|
|
||||||
Imediat după pornire, Sway va renunța la permisiunile de root.
|
|
||||||
|
|
||||||
## Configurare
|
## Configurare
|
||||||
|
|
||||||
Dacă folosiți deja i3, copiați fișierul de configurare din i3 în `~/.config/sway/config`, și va funcționa fără a necesita nici o modificare. In caz contrar, copiați exemplul de configurare (disponibil de obicei în `/etc/sway/config`) în `~/.config/sway/config`.
|
Dacă folosiți deja i3, copiați fișierul de configurare din i3 în `~/.config/sway/config`, și va funcționa fără a necesita nici o modificare. In caz contrar, copiați exemplul de configurare (disponibil de obicei în `/etc/sway/config`) în `~/.config/sway/config`.
|
||||||
|
|
|
@ -47,12 +47,6 @@ _\*Зависимости для сборки_
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
На системах без logind вам понадобится добавить suid к файлу программы sway:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
sway сбросит root-права при запуске.
|
|
||||||
|
|
||||||
## Настройка
|
## Настройка
|
||||||
|
|
||||||
Если вы уже используете i3, скопируйте ваш конфигурационный файл i3 в `~/.config/sway/config`, и
|
Если вы уже используете i3, скопируйте ваш конфигурационный файл i3 в `~/.config/sway/config`, и
|
||||||
|
|
|
@ -41,12 +41,6 @@ Kör dessa kommandon:
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
På system utan logind eller seatd måste du ge sways exekverbara fil root-privilegier:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway kommer att överge sina root-privilegier kort efter uppstart.
|
|
||||||
|
|
||||||
## Konfiguration
|
## Konfiguration
|
||||||
|
|
||||||
Ifall du redan använder i3 så kan du kopiera din konfigurationsfil till `~/.config/sway/config` och det kommer då att fungera som det ska.
|
Ifall du redan använder i3 så kan du kopiera din konfigurationsfil till `~/.config/sway/config` och det kommer då att fungera som det ska.
|
||||||
|
|
|
@ -43,12 +43,6 @@ _\*Derleme-anı bağımlılıkları_
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
logind olmayan sistemlerde, sway ikilisine (binary) izin vermeniz (suid) gerekir:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway, başlangıçtan kısa bir süre sonra kök(root) izinlerini bırakacaktır.
|
|
||||||
|
|
||||||
## Yapılandırma
|
## Yapılandırma
|
||||||
|
|
||||||
Zaten i3 kullanıyorsanız, i3 yapılandırmanızı `~/.config/sway/config` konumuna kopyalayın ve kutudan çıktığı gibi çalışacaktır. Aksi takdirde, örnek yapılandırma dosyasını `~/.config/sway/config` konumuna kopyalayın. Genellikle `/etc/sway/config` konumunda bulunur.
|
Zaten i3 kullanıyorsanız, i3 yapılandırmanızı `~/.config/sway/config` konumuna kopyalayın ve kutudan çıktığı gibi çalışacaktır. Aksi takdirde, örnek yapılandırma dosyasını `~/.config/sway/config` konumuna kopyalayın. Genellikle `/etc/sway/config` konumunda bulunur.
|
||||||
|
|
|
@ -57,12 +57,6 @@ _\*Лише для компіляції_
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
На системах без logind, необхідно встановити біт SUID на виконуваний файл sway:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway втратить права доступу root незабаром після запуску.
|
|
||||||
|
|
||||||
## Налаштування
|
## Налаштування
|
||||||
|
|
||||||
Якщо ви вже використовуєте i3, скопіюйте свій файл налаштувань
|
Якщо ви вже використовуєте i3, скопіюйте свій файл налаштувань
|
||||||
|
|
|
@ -41,12 +41,6 @@ _\*编译时依赖_
|
||||||
ninja -C build/
|
ninja -C build/
|
||||||
sudo ninja -C build/ install
|
sudo ninja -C build/ install
|
||||||
|
|
||||||
在没有logind或seatd的系统上, 你需要给sway二进制文件设置suid:
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
启动后,Sway会尽快放弃root权限。
|
|
||||||
|
|
||||||
## 配置
|
## 配置
|
||||||
|
|
||||||
如果你已经在使用i3,直接复制i3配置文件到 `~/.config/sway/config`,这是开箱即用的。或者,你可以复制配置样例到`~/.config/sway/config`。它通常位于 `/etc/sway/config`。
|
如果你已经在使用i3,直接复制i3配置文件到 `~/.config/sway/config`,这是开箱即用的。或者,你可以复制配置样例到`~/.config/sway/config`。它通常位于 `/etc/sway/config`。
|
||||||
|
|
|
@ -46,12 +46,6 @@ _\*編譯時相依_
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
|
|
||||||
在沒有 logind 的系統上,你需要為 sway 的執行檔加上 suid。
|
|
||||||
|
|
||||||
sudo chmod a+s /usr/local/bin/sway
|
|
||||||
|
|
||||||
Sway 在啟動不久後就會放棄 root 權限。
|
|
||||||
|
|
||||||
## 設定檔
|
## 設定檔
|
||||||
|
|
||||||
如果你已經在使用 i3,你可以直接將你的 i3 設定檔複製到 `~/.config/sway/config` 然後就能直接使用。
|
如果你已經在使用 i3,你可以直接將你的 i3 設定檔複製到 `~/.config/sway/config` 然後就能直接使用。
|
||||||
|
|
|
@ -12,23 +12,6 @@
|
||||||
|
|
||||||
const uint8_t GESTURE_FINGERS_ANY = 0;
|
const uint8_t GESTURE_FINGERS_ANY = 0;
|
||||||
|
|
||||||
// Helper to easily allocate and format string
|
|
||||||
static char *strformat(const char *format, ...) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
int length = vsnprintf(NULL, 0, format, args) + 1;
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
char *result = malloc(length);
|
|
||||||
if (result) {
|
|
||||||
va_start(args, format);
|
|
||||||
vsnprintf(result, length, format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *gesture_parse(const char *input, struct gesture *output) {
|
char *gesture_parse(const char *input, struct gesture *output) {
|
||||||
// Clear output in case of failure
|
// Clear output in case of failure
|
||||||
output->type = GESTURE_TYPE_NONE;
|
output->type = GESTURE_TYPE_NONE;
|
||||||
|
@ -38,7 +21,7 @@ char *gesture_parse(const char *input, struct gesture *output) {
|
||||||
// Split input type, fingers and directions
|
// Split input type, fingers and directions
|
||||||
list_t *split = split_string(input, ":");
|
list_t *split = split_string(input, ":");
|
||||||
if (split->length < 1 || split->length > 3) {
|
if (split->length < 1 || split->length > 3) {
|
||||||
return strformat(
|
return format_str(
|
||||||
"expected <gesture>[:<fingers>][:direction], got %s",
|
"expected <gesture>[:<fingers>][:direction], got %s",
|
||||||
input);
|
input);
|
||||||
}
|
}
|
||||||
|
@ -51,8 +34,8 @@ char *gesture_parse(const char *input, struct gesture *output) {
|
||||||
} else if (strcmp(split->items[0], "swipe") == 0) {
|
} else if (strcmp(split->items[0], "swipe") == 0) {
|
||||||
output->type = GESTURE_TYPE_SWIPE;
|
output->type = GESTURE_TYPE_SWIPE;
|
||||||
} else {
|
} else {
|
||||||
return strformat("expected hold|pinch|swipe, got %s",
|
return format_str("expected hold|pinch|swipe, got %s",
|
||||||
split->items[0]);
|
(const char *)split->items[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse optional arguments
|
// Parse optional arguments
|
||||||
|
@ -67,7 +50,7 @@ char *gesture_parse(const char *input, struct gesture *output) {
|
||||||
next = split->length == 3 ? split->items[2] : NULL;
|
next = split->length == 3 ? split->items[2] : NULL;
|
||||||
} else if (split->length == 3) {
|
} else if (split->length == 3) {
|
||||||
// Fail here if argument can only be finger count
|
// Fail here if argument can only be finger count
|
||||||
return strformat("expected 1-9, got %s", next);
|
return format_str("expected 1-9, got %s", next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is an argument left, try to parse as direction
|
// If there is an argument left, try to parse as direction
|
||||||
|
@ -95,7 +78,7 @@ char *gesture_parse(const char *input, struct gesture *output) {
|
||||||
} else if (strcmp(item, "counterclockwise") == 0) {
|
} else if (strcmp(item, "counterclockwise") == 0) {
|
||||||
output->directions |= GESTURE_DIRECTION_COUNTERCLOCKWISE;
|
output->directions |= GESTURE_DIRECTION_COUNTERCLOCKWISE;
|
||||||
} else {
|
} else {
|
||||||
return strformat("expected direction, got %s", item);
|
return format_str("expected direction, got %s", item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_free_items_and_destroy(directions);
|
list_free_items_and_destroy(directions);
|
||||||
|
@ -163,7 +146,7 @@ static char *gesture_directions_to_string(uint32_t directions) {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = strdup(name);
|
result = strdup(name);
|
||||||
} else {
|
} else {
|
||||||
char *new = strformat("%s+%s", result, name);
|
char *new = format_str("%s+%s", result, name);
|
||||||
free(result);
|
free(result);
|
||||||
result = new;
|
result = new;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +162,7 @@ static char *gesture_directions_to_string(uint32_t directions) {
|
||||||
|
|
||||||
char *gesture_to_string(struct gesture *gesture) {
|
char *gesture_to_string(struct gesture *gesture) {
|
||||||
char *directions = gesture_directions_to_string(gesture->directions);
|
char *directions = gesture_directions_to_string(gesture->directions);
|
||||||
char *result = strformat("%s:%u:%s",
|
char *result = format_str("%s:%u:%s",
|
||||||
gesture_type_string(gesture->type),
|
gesture_type_string(gesture->type),
|
||||||
gesture->fingers, directions);
|
gesture->fingers, directions);
|
||||||
free(directions);
|
free(directions);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
lib_sway_common = static_library(
|
lib_sway_common = static_library(
|
||||||
'sway-common',
|
'sway-common',
|
||||||
files(
|
files(
|
||||||
'background-image.c',
|
|
||||||
'cairo.c',
|
'cairo.c',
|
||||||
'gesture.c',
|
'gesture.c',
|
||||||
'ipc-client.c',
|
'ipc-client.c',
|
||||||
|
@ -14,7 +13,6 @@ lib_sway_common = static_library(
|
||||||
),
|
),
|
||||||
dependencies: [
|
dependencies: [
|
||||||
cairo,
|
cairo,
|
||||||
gdk_pixbuf,
|
|
||||||
pango,
|
pango,
|
||||||
pangocairo,
|
pangocairo,
|
||||||
wayland_client.partial_dependency(compile_args: true)
|
wayland_client.partial_dependency(compile_args: true)
|
||||||
|
|
|
@ -84,18 +84,11 @@ void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width,
|
||||||
int *baseline, double scale, bool markup, const char *fmt, ...) {
|
int *baseline, double scale, bool markup, const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
// Add one since vsnprintf excludes null terminator.
|
char *buf = vformat_str(fmt, args);
|
||||||
int length = vsnprintf(NULL, 0, fmt, args) + 1;
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
char *buf = malloc(length);
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
sway_log(SWAY_ERROR, "Failed to allocate memory");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
va_start(args, fmt);
|
|
||||||
vsnprintf(buf, length, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
PangoLayout *layout = get_pango_layout(cairo, desc, buf, scale, markup);
|
PangoLayout *layout = get_pango_layout(cairo, desc, buf, scale, markup);
|
||||||
pango_cairo_update_layout(cairo, layout);
|
pango_cairo_update_layout(cairo, layout);
|
||||||
|
@ -104,6 +97,7 @@ void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width,
|
||||||
*baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
|
*baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
|
||||||
}
|
}
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,18 +119,11 @@ void render_text(cairo_t *cairo, const PangoFontDescription *desc,
|
||||||
double scale, bool markup, const char *fmt, ...) {
|
double scale, bool markup, const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
// Add one since vsnprintf excludes null terminator.
|
char *buf = vformat_str(fmt, args);
|
||||||
int length = vsnprintf(NULL, 0, fmt, args) + 1;
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
char *buf = malloc(length);
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
sway_log(SWAY_ERROR, "Failed to allocate memory");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
va_start(args, fmt);
|
|
||||||
vsnprintf(buf, length, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
PangoLayout *layout = get_pango_layout(cairo, desc, buf, scale, markup);
|
PangoLayout *layout = get_pango_layout(cairo, desc, buf, scale, markup);
|
||||||
cairo_font_options_t *fo = cairo_font_options_create();
|
cairo_font_options_t *fo = cairo_font_options_create();
|
||||||
|
@ -146,5 +133,6 @@ void render_text(cairo_t *cairo, const PangoFontDescription *desc,
|
||||||
pango_cairo_update_layout(cairo, layout);
|
pango_cairo_update_layout(cairo, layout);
|
||||||
pango_cairo_show_layout(cairo, layout);
|
pango_cairo_show_layout(cairo, layout);
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -328,3 +329,35 @@ bool expand_path(char **path) {
|
||||||
wordfree(&p);
|
wordfree(&p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *vformat_str(const char *fmt, va_list args) {
|
||||||
|
char *str = NULL;
|
||||||
|
va_list args_copy;
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
|
||||||
|
int len = vsnprintf(NULL, 0, fmt, args);
|
||||||
|
if (len < 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "vsnprintf(\"%s\") failed", fmt);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = malloc(len + 1);
|
||||||
|
if (str == NULL) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "malloc() failed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
vsnprintf(str, len + 1, fmt, args_copy);
|
||||||
|
|
||||||
|
out:
|
||||||
|
va_end(args_copy);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *format_str(const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
char *str = vformat_str(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ bar {
|
||||||
|
|
||||||
# When the status_command prints a new line to stdout, swaybar updates.
|
# When the status_command prints a new line to stdout, swaybar updates.
|
||||||
# The default just shows the current date and time.
|
# The default just shows the current date and time.
|
||||||
status_command while date +'%Y-%m-%d %I:%M:%S %p'; do sleep 1; done
|
status_command while date +'%Y-%m-%d %X'; do sleep 1; done
|
||||||
|
|
||||||
colors {
|
colors {
|
||||||
statusline #ffffff
|
statusline #ffffff
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# This script requires i3ipc-python package (install it from a system package manager
|
|
||||||
# or pip).
|
|
||||||
# It adds icons to the workspace name for each open window.
|
|
||||||
# Set your keybindings like this: set $workspace1 workspace number 1
|
|
||||||
# Add your icons to WINDOW_ICONS.
|
|
||||||
# Based on https://github.com/maximbaz/dotfiles/blob/master/bin/i3-autoname-workspaces
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import i3ipc
|
|
||||||
import logging
|
|
||||||
import re
|
|
||||||
import signal
|
|
||||||
import sys
|
|
||||||
|
|
||||||
WINDOW_ICONS = {
|
|
||||||
"firefox": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFAULT_ICON = ""
|
|
||||||
|
|
||||||
|
|
||||||
def icon_for_window(window):
|
|
||||||
name = None
|
|
||||||
if window.app_id is not None and len(window.app_id) > 0:
|
|
||||||
name = window.app_id.lower()
|
|
||||||
elif window.window_class is not None and len(window.window_class) > 0:
|
|
||||||
name = window.window_class.lower()
|
|
||||||
|
|
||||||
if name in WINDOW_ICONS:
|
|
||||||
return WINDOW_ICONS[name]
|
|
||||||
|
|
||||||
logging.info("No icon available for window with name: %s" % str(name))
|
|
||||||
return DEFAULT_ICON
|
|
||||||
|
|
||||||
def rename_workspaces(ipc):
|
|
||||||
for workspace in ipc.get_tree().workspaces():
|
|
||||||
name_parts = parse_workspace_name(workspace.name)
|
|
||||||
icon_tuple = ()
|
|
||||||
for w in workspace:
|
|
||||||
if w.app_id is not None or w.window_class is not None:
|
|
||||||
icon = icon_for_window(w)
|
|
||||||
if not ARGUMENTS.duplicates and icon in icon_tuple:
|
|
||||||
continue
|
|
||||||
icon_tuple += (icon,)
|
|
||||||
name_parts["icons"] = " ".join(icon_tuple) + " "
|
|
||||||
new_name = construct_workspace_name(name_parts)
|
|
||||||
ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))
|
|
||||||
|
|
||||||
|
|
||||||
def undo_window_renaming(ipc):
|
|
||||||
for workspace in ipc.get_tree().workspaces():
|
|
||||||
name_parts = parse_workspace_name(workspace.name)
|
|
||||||
name_parts["icons"] = None
|
|
||||||
new_name = construct_workspace_name(name_parts)
|
|
||||||
ipc.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))
|
|
||||||
ipc.main_quit()
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_workspace_name(name):
|
|
||||||
return re.match(
|
|
||||||
"(?P<num>[0-9]+):?(?P<shortname>\w+)? ?(?P<icons>.+)?", name
|
|
||||||
).groupdict()
|
|
||||||
|
|
||||||
|
|
||||||
def construct_workspace_name(parts):
|
|
||||||
new_name = str(parts["num"])
|
|
||||||
if parts["shortname"] or parts["icons"]:
|
|
||||||
new_name += ":"
|
|
||||||
|
|
||||||
if parts["shortname"]:
|
|
||||||
new_name += parts["shortname"]
|
|
||||||
|
|
||||||
if parts["icons"]:
|
|
||||||
new_name += " " + parts["icons"]
|
|
||||||
|
|
||||||
return new_name
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="This script automatically changes the workspace name in sway depending on your open applications."
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--duplicates",
|
|
||||||
"-d",
|
|
||||||
action="store_true",
|
|
||||||
help="Set it when you want an icon for each instance of the same application per workspace.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--logfile",
|
|
||||||
"-l",
|
|
||||||
type=str,
|
|
||||||
default="/tmp/sway-autoname-workspaces.log",
|
|
||||||
help="Path for the logfile.",
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
global ARGUMENTS
|
|
||||||
ARGUMENTS = args
|
|
||||||
|
|
||||||
logging.basicConfig(
|
|
||||||
level=logging.INFO,
|
|
||||||
filename=ARGUMENTS.logfile,
|
|
||||||
filemode="w",
|
|
||||||
format="%(message)s",
|
|
||||||
)
|
|
||||||
|
|
||||||
ipc = i3ipc.Connection()
|
|
||||||
|
|
||||||
for sig in [signal.SIGINT, signal.SIGTERM]:
|
|
||||||
signal.signal(sig, lambda signal, frame: undo_window_renaming(ipc))
|
|
||||||
|
|
||||||
def window_event_handler(ipc, e):
|
|
||||||
if e.change in ["new", "close", "move"]:
|
|
||||||
rename_workspaces(ipc)
|
|
||||||
|
|
||||||
ipc.on("window", window_event_handler)
|
|
||||||
|
|
||||||
rename_workspaces(ipc)
|
|
||||||
|
|
||||||
ipc.main()
|
|
||||||
|
|
168
contrib/grimshot
168
contrib/grimshot
|
@ -1,168 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
## Grimshot: a helper for screenshots within sway
|
|
||||||
## Requirements:
|
|
||||||
## - `grim`: screenshot utility for wayland
|
|
||||||
## - `slurp`: to select an area
|
|
||||||
## - `swaymsg`: to read properties of current window
|
|
||||||
## - `wl-copy`: clipboard utility
|
|
||||||
## - `jq`: json utility to parse swaymsg output
|
|
||||||
## - `notify-send`: to show notifications
|
|
||||||
## Those are needed to be installed, if unsure, run `grimshot check`
|
|
||||||
##
|
|
||||||
## See `man 1 grimshot` or `grimshot usage` for further details.
|
|
||||||
|
|
||||||
getTargetDirectory() {
|
|
||||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" && \
|
|
||||||
. "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs"
|
|
||||||
|
|
||||||
echo "${XDG_SCREENSHOTS_DIR:-${XDG_PICTURES_DIR:-$HOME}}"
|
|
||||||
}
|
|
||||||
|
|
||||||
NOTIFY=no
|
|
||||||
CURSOR=
|
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
key="$1"
|
|
||||||
|
|
||||||
case $key in
|
|
||||||
-n|--notify)
|
|
||||||
NOTIFY=yes
|
|
||||||
shift # past argument
|
|
||||||
;;
|
|
||||||
-c|--cursor)
|
|
||||||
CURSOR=yes
|
|
||||||
shift # past argument
|
|
||||||
;;
|
|
||||||
*) # unknown option
|
|
||||||
break # done with parsing --flags
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
ACTION=${1:-usage}
|
|
||||||
SUBJECT=${2:-screen}
|
|
||||||
FILE=${3:-$(getTargetDirectory)/$(date -Ins).png}
|
|
||||||
|
|
||||||
if [ "$ACTION" != "save" ] && [ "$ACTION" != "copy" ] && [ "$ACTION" != "check" ]; then
|
|
||||||
echo "Usage:"
|
|
||||||
echo " grimshot [--notify] [--cursor] (copy|save) [active|screen|output|area|window] [FILE|-]"
|
|
||||||
echo " grimshot check"
|
|
||||||
echo " grimshot usage"
|
|
||||||
echo ""
|
|
||||||
echo "Commands:"
|
|
||||||
echo " copy: Copy the screenshot data into the clipboard."
|
|
||||||
echo " save: Save the screenshot to a regular file or '-' to pipe to STDOUT."
|
|
||||||
echo " check: Verify if required tools are installed and exit."
|
|
||||||
echo " usage: Show this message and exit."
|
|
||||||
echo ""
|
|
||||||
echo "Targets:"
|
|
||||||
echo " active: Currently active window."
|
|
||||||
echo " screen: All visible outputs."
|
|
||||||
echo " output: Currently active output."
|
|
||||||
echo " area: Manually select a region."
|
|
||||||
echo " window: Manually select a window."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
notify() {
|
|
||||||
notify-send -t 3000 -a grimshot "$@"
|
|
||||||
}
|
|
||||||
notifyOk() {
|
|
||||||
[ "$NOTIFY" = "no" ] && return
|
|
||||||
|
|
||||||
TITLE=${2:-"Screenshot"}
|
|
||||||
MESSAGE=${1:-"OK"}
|
|
||||||
notify "$TITLE" "$MESSAGE"
|
|
||||||
}
|
|
||||||
notifyError() {
|
|
||||||
if [ $NOTIFY = "yes" ]; then
|
|
||||||
TITLE=${2:-"Screenshot"}
|
|
||||||
MESSAGE=${1:-"Error taking screenshot with grim"}
|
|
||||||
notify -u critical "$TITLE" "$MESSAGE"
|
|
||||||
else
|
|
||||||
echo "$1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
die() {
|
|
||||||
MSG=${1:-Bye}
|
|
||||||
notifyError "Error: $MSG"
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
check() {
|
|
||||||
COMMAND=$1
|
|
||||||
if command -v "$COMMAND" > /dev/null 2>&1; then
|
|
||||||
RESULT="OK"
|
|
||||||
else
|
|
||||||
RESULT="NOT FOUND"
|
|
||||||
fi
|
|
||||||
echo " $COMMAND: $RESULT"
|
|
||||||
}
|
|
||||||
|
|
||||||
takeScreenshot() {
|
|
||||||
FILE=$1
|
|
||||||
GEOM=$2
|
|
||||||
OUTPUT=$3
|
|
||||||
if [ -n "$OUTPUT" ]; then
|
|
||||||
grim ${CURSOR:+-c} -o "$OUTPUT" "$FILE" || die "Unable to invoke grim"
|
|
||||||
elif [ -z "$GEOM" ]; then
|
|
||||||
grim ${CURSOR:+-c} "$FILE" || die "Unable to invoke grim"
|
|
||||||
else
|
|
||||||
grim ${CURSOR:+-c} -g "$GEOM" "$FILE" || die "Unable to invoke grim"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$ACTION" = "check" ] ; then
|
|
||||||
echo "Checking if required tools are installed. If something is missing, install it to your system and make it available in PATH..."
|
|
||||||
check grim
|
|
||||||
check slurp
|
|
||||||
check swaymsg
|
|
||||||
check wl-copy
|
|
||||||
check jq
|
|
||||||
check notify-send
|
|
||||||
exit
|
|
||||||
elif [ "$SUBJECT" = "area" ] ; then
|
|
||||||
GEOM=$(slurp -d)
|
|
||||||
# Check if user exited slurp without selecting the area
|
|
||||||
if [ -z "$GEOM" ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
WHAT="Area"
|
|
||||||
elif [ "$SUBJECT" = "active" ] ; then
|
|
||||||
FOCUSED=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused)')
|
|
||||||
GEOM=$(echo "$FOCUSED" | jq -r '.rect | "\(.x),\(.y) \(.width)x\(.height)"')
|
|
||||||
APP_ID=$(echo "$FOCUSED" | jq -r '.app_id')
|
|
||||||
WHAT="$APP_ID window"
|
|
||||||
elif [ "$SUBJECT" = "screen" ] ; then
|
|
||||||
GEOM=""
|
|
||||||
WHAT="Screen"
|
|
||||||
elif [ "$SUBJECT" = "output" ] ; then
|
|
||||||
GEOM=""
|
|
||||||
OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused)' | jq -r '.name')
|
|
||||||
WHAT="$OUTPUT"
|
|
||||||
elif [ "$SUBJECT" = "window" ] ; then
|
|
||||||
GEOM=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)
|
|
||||||
# Check if user exited slurp without selecting the area
|
|
||||||
if [ -z "$GEOM" ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
WHAT="Window"
|
|
||||||
else
|
|
||||||
die "Unknown subject to take a screen shot from" "$SUBJECT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$ACTION" = "copy" ] ; then
|
|
||||||
takeScreenshot - "$GEOM" "$OUTPUT" | wl-copy --type image/png || die "Clipboard error"
|
|
||||||
notifyOk "$WHAT copied to buffer"
|
|
||||||
else
|
|
||||||
if takeScreenshot "$FILE" "$GEOM" "$OUTPUT"; then
|
|
||||||
TITLE="Screenshot of $SUBJECT"
|
|
||||||
MESSAGE=$(basename "$FILE")
|
|
||||||
notifyOk "$MESSAGE" "$TITLE"
|
|
||||||
echo "$FILE"
|
|
||||||
else
|
|
||||||
notifyError "Error taking screenshot with grim"
|
|
||||||
fi
|
|
||||||
fi
|
|
|
@ -1,109 +0,0 @@
|
||||||
.\" Generated by scdoc 1.11.2
|
|
||||||
.\" Complete documentation for this program is not available as a GNU info page
|
|
||||||
.ie \n(.g .ds Aq \(aq
|
|
||||||
.el .ds Aq '
|
|
||||||
.nh
|
|
||||||
.ad l
|
|
||||||
.\" Begin generated content:
|
|
||||||
.TH "grimshot" "1" "2022-03-31"
|
|
||||||
.P
|
|
||||||
.SH NAME
|
|
||||||
.P
|
|
||||||
grimshot - a helper for screenshots within sway
|
|
||||||
.P
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.P
|
|
||||||
\fBgrimshot\fR [--notify] [--cursor] (copy|save) [TARGET] [FILE]
|
|
||||||
.br
|
|
||||||
\fBgrimshot\fR check
|
|
||||||
.br
|
|
||||||
\fBgrimshot\fR usage
|
|
||||||
.P
|
|
||||||
.SH OPTIONS
|
|
||||||
.P
|
|
||||||
\fB--notify\fR
|
|
||||||
.RS 4
|
|
||||||
Show notifications to the user that a screenshot has been taken.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fB--cursor\fR
|
|
||||||
.RS 4
|
|
||||||
Include cursors in the screenshot.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fBsave\fR
|
|
||||||
.RS 4
|
|
||||||
Save the screenshot into a regular file.\& Grimshot will write images
|
|
||||||
files to \fBXDG_SCREENSHOTS_DIR\fR if this is set (or defined
|
|
||||||
in \fBuser-dirs.\&dir\fR), or otherwise fall back to \fBXDG_PICTURES_DIR\fR.\&
|
|
||||||
Set FILE to '\&-'\& to pipe the output to STDOUT.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fBcopy\fR
|
|
||||||
.RS 4
|
|
||||||
Copy the screenshot data (as image/png) into the clipboard.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.P
|
|
||||||
Grimshot is an easy-to-use screenshot utility for sway.\& It provides a
|
|
||||||
convenient interface over grim, slurp and jq, and supports storing the
|
|
||||||
screenshot either directly to the clipboard using wl-copy or to a file.\&
|
|
||||||
.P
|
|
||||||
.SH EXAMPLES
|
|
||||||
.P
|
|
||||||
An example usage pattern is to add these bindings to your sway config:
|
|
||||||
.P
|
|
||||||
.nf
|
|
||||||
.RS 4
|
|
||||||
# Screenshots:
|
|
||||||
# Super+P: Current window
|
|
||||||
# Super+Shift+p: Select area
|
|
||||||
# Super+Alt+p Current output
|
|
||||||
# Super+Ctrl+p Select a window
|
|
||||||
|
|
||||||
bindsym Mod4+p exec grimshot save active
|
|
||||||
bindsym Mod4+Shift+p exec grimshot save area
|
|
||||||
bindsym Mod4+Mod1+p exec grimshot save output
|
|
||||||
bindsym Mod4+Ctrl+p exec grimshot save window
|
|
||||||
.fi
|
|
||||||
.RE
|
|
||||||
.P
|
|
||||||
.SH TARGETS
|
|
||||||
.P
|
|
||||||
grimshot can capture the following named targets:
|
|
||||||
.P
|
|
||||||
\fIactive\fR
|
|
||||||
.RS 4
|
|
||||||
Captures the currently active window.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fIscreen\fR
|
|
||||||
.RS 4
|
|
||||||
Captures the entire screen.\& This includes all visible outputs.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fIarea\fR
|
|
||||||
.RS 4
|
|
||||||
Allows manually selecting a rectangular region, and captures that.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fIwindow\fR
|
|
||||||
.RS 4
|
|
||||||
Allows manually selecting a single window (by clicking on it), and
|
|
||||||
captures it.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
\fIoutput\fR
|
|
||||||
.RS 4
|
|
||||||
Captures the currently active output.\&
|
|
||||||
.P
|
|
||||||
.RE
|
|
||||||
.SH OUTPUT
|
|
||||||
.P
|
|
||||||
Grimshot will print the filename of the captured screenshot to stdout if called
|
|
||||||
with the \fIsave\fR subcommand.\&
|
|
||||||
.P
|
|
||||||
.SH SEE ALSO
|
|
||||||
.P
|
|
||||||
\fBgrim\fR(1)
|
|
|
@ -1,80 +0,0 @@
|
||||||
grimshot(1)
|
|
||||||
|
|
||||||
# NAME
|
|
||||||
|
|
||||||
grimshot - a helper for screenshots within sway
|
|
||||||
|
|
||||||
# SYNOPSIS
|
|
||||||
|
|
||||||
*grimshot* [--notify] [--cursor] (copy|save) [TARGET] [FILE]++
|
|
||||||
*grimshot* check++
|
|
||||||
*grimshot* usage
|
|
||||||
|
|
||||||
# OPTIONS
|
|
||||||
|
|
||||||
*--notify*
|
|
||||||
Show notifications to the user that a screenshot has been taken.
|
|
||||||
|
|
||||||
*--cursor*
|
|
||||||
Include cursors in the screenshot.
|
|
||||||
|
|
||||||
*save*
|
|
||||||
Save the screenshot into a regular file. Grimshot will write image
|
|
||||||
files to *XDG_SCREENSHOTS_DIR* if this is set (or defined
|
|
||||||
in *user-dirs.dir*), or otherwise fall back to *XDG_PICTURES_DIR*.
|
|
||||||
Set FILE to '-' to pipe the output to STDOUT.
|
|
||||||
|
|
||||||
*copy*
|
|
||||||
Copy the screenshot data (as image/png) into the clipboard.
|
|
||||||
|
|
||||||
# DESCRIPTION
|
|
||||||
|
|
||||||
Grimshot is an easy-to-use screenshot utility for sway. It provides a
|
|
||||||
convenient interface over grim, slurp and jq, and supports storing the
|
|
||||||
screenshot either directly to the clipboard using wl-copy or to a file.
|
|
||||||
|
|
||||||
# EXAMPLES
|
|
||||||
|
|
||||||
An example usage pattern is to add these bindings to your sway config:
|
|
||||||
|
|
||||||
```
|
|
||||||
# Screenshots:
|
|
||||||
# Super+P: Current window
|
|
||||||
# Super+Shift+p: Select area
|
|
||||||
# Super+Alt+p Current output
|
|
||||||
# Super+Ctrl+p Select a window
|
|
||||||
|
|
||||||
bindsym Mod4+p exec grimshot save active
|
|
||||||
bindsym Mod4+Shift+p exec grimshot save area
|
|
||||||
bindsym Mod4+Mod1+p exec grimshot save output
|
|
||||||
bindsym Mod4+Ctrl+p exec grimshot save window
|
|
||||||
```
|
|
||||||
|
|
||||||
# TARGETS
|
|
||||||
|
|
||||||
grimshot can capture the following named targets:
|
|
||||||
|
|
||||||
_active_
|
|
||||||
Captures the currently active window.
|
|
||||||
|
|
||||||
_screen_
|
|
||||||
Captures the entire screen. This includes all visible outputs.
|
|
||||||
|
|
||||||
_area_
|
|
||||||
Allows manually selecting a rectangular region, and captures that.
|
|
||||||
|
|
||||||
_window_
|
|
||||||
Allows manually selecting a single window (by clicking on it), and
|
|
||||||
captures it.
|
|
||||||
|
|
||||||
_output_
|
|
||||||
Captures the currently active output.
|
|
||||||
|
|
||||||
# OUTPUT
|
|
||||||
|
|
||||||
Grimshot will print the filename of the captured screenshot to stdout if called
|
|
||||||
with the _save_ subcommand.
|
|
||||||
|
|
||||||
# SEE ALSO
|
|
||||||
|
|
||||||
*grim*(1)
|
|
|
@ -1,69 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# This script requires i3ipc-python package (install it from a system package manager
|
|
||||||
# or pip).
|
|
||||||
# It makes inactive windows transparent. Use `transparency_val` variable to control
|
|
||||||
# transparency strength in range of 0…1 or use the command line argument -o.
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import i3ipc
|
|
||||||
import signal
|
|
||||||
import sys
|
|
||||||
from functools import partial
|
|
||||||
|
|
||||||
def on_window_focus(inactive_opacity, ipc, event):
|
|
||||||
global prev_focused
|
|
||||||
global prev_workspace
|
|
||||||
|
|
||||||
focused_workspace = ipc.get_tree().find_focused()
|
|
||||||
|
|
||||||
if focused_workspace == None:
|
|
||||||
return
|
|
||||||
|
|
||||||
focused = event.container
|
|
||||||
workspace = focused_workspace.workspace().num
|
|
||||||
|
|
||||||
if focused.id != prev_focused.id: # https://github.com/swaywm/sway/issues/2859
|
|
||||||
focused.command("opacity 1")
|
|
||||||
if workspace == prev_workspace:
|
|
||||||
prev_focused.command("opacity " + inactive_opacity)
|
|
||||||
prev_focused = focused
|
|
||||||
prev_workspace = workspace
|
|
||||||
|
|
||||||
|
|
||||||
def remove_opacity(ipc):
|
|
||||||
for workspace in ipc.get_tree().workspaces():
|
|
||||||
for w in workspace:
|
|
||||||
w.command("opacity 1")
|
|
||||||
ipc.main_quit()
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
transparency_val = "0.80"
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="This script allows you to set the transparency of unfocused windows in sway."
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--opacity",
|
|
||||||
"-o",
|
|
||||||
type=str,
|
|
||||||
default=transparency_val,
|
|
||||||
help="set opacity value in range 0...1",
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
ipc = i3ipc.Connection()
|
|
||||||
prev_focused = None
|
|
||||||
prev_workspace = ipc.get_tree().find_focused().workspace().num
|
|
||||||
|
|
||||||
for window in ipc.get_tree():
|
|
||||||
if window.focused:
|
|
||||||
prev_focused = window
|
|
||||||
else:
|
|
||||||
window.command("opacity " + args.opacity)
|
|
||||||
for sig in [signal.SIGINT, signal.SIGTERM]:
|
|
||||||
signal.signal(sig, lambda signal, frame: remove_opacity(ipc))
|
|
||||||
ipc.on("window::focus", partial(on_window_focus, args.opacity))
|
|
||||||
ipc.main()
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef _SWAY_BACKGROUND_IMAGE_H
|
|
||||||
#define _SWAY_BACKGROUND_IMAGE_H
|
|
||||||
#include "cairo_util.h"
|
|
||||||
|
|
||||||
enum background_mode {
|
|
||||||
BACKGROUND_MODE_STRETCH,
|
|
||||||
BACKGROUND_MODE_FILL,
|
|
||||||
BACKGROUND_MODE_FIT,
|
|
||||||
BACKGROUND_MODE_CENTER,
|
|
||||||
BACKGROUND_MODE_TILE,
|
|
||||||
BACKGROUND_MODE_SOLID_COLOR,
|
|
||||||
BACKGROUND_MODE_INVALID,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum background_mode parse_background_mode(const char *mode);
|
|
||||||
cairo_surface_t *load_background_image(const char *path);
|
|
||||||
void render_background_image(cairo_t *cairo, cairo_surface_t *image,
|
|
||||||
enum background_mode mode, int buffer_width, int buffer_height);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function which escape characters a & < > ' ".
|
* Utility function which escape characters a & < > ' ".
|
||||||
|
@ -16,9 +17,9 @@ size_t escape_markup_text(const char *src, char *dest);
|
||||||
PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc,
|
PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc,
|
||||||
const char *text, double scale, bool markup);
|
const char *text, double scale, bool markup);
|
||||||
void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width, int *height,
|
void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width, int *height,
|
||||||
int *baseline, double scale, bool markup, const char *fmt, ...);
|
int *baseline, double scale, bool markup, const char *fmt, ...) _SWAY_ATTRIB_PRINTF(8, 9);
|
||||||
void get_text_metrics(const PangoFontDescription *desc, int *height, int *baseline);
|
void get_text_metrics(const PangoFontDescription *desc, int *height, int *baseline);
|
||||||
void render_text(cairo_t *cairo, PangoFontDescription *desc,
|
void render_text(cairo_t *cairo, PangoFontDescription *desc,
|
||||||
double scale, bool markup, const char *fmt, ...);
|
double scale, bool markup, const char *fmt, ...) _SWAY_ATTRIB_PRINTF(5, 6);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _SWAY_ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
|
||||||
|
#else
|
||||||
|
#define _SWAY_ATTRIB_PRINTF(start, end)
|
||||||
|
#endif
|
||||||
|
|
||||||
void strip_whitespace(char *str);
|
void strip_whitespace(char *str);
|
||||||
void strip_quotes(char *str);
|
void strip_quotes(char *str);
|
||||||
|
|
||||||
|
@ -31,4 +37,7 @@ char *argsep(char **stringp, const char *delim, char *matched_delim);
|
||||||
// Expand a path using shell replacements such as $HOME and ~
|
// Expand a path using shell replacements such as $HOME and ~
|
||||||
bool expand_path(char **path);
|
bool expand_path(char **path);
|
||||||
|
|
||||||
|
char *vformat_str(const char *fmt, va_list args) _SWAY_ATTRIB_PRINTF(1, 0);
|
||||||
|
char *format_str(const char *fmt, ...) _SWAY_ATTRIB_PRINTF(1, 2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <wlr/util/edges.h>
|
#include <wlr/util/edges.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
struct sway_container;
|
struct sway_container;
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ struct cmd_results *config_commands_command(char *exec);
|
||||||
/**
|
/**
|
||||||
* Allocates a cmd_results object.
|
* Allocates a cmd_results object.
|
||||||
*/
|
*/
|
||||||
struct cmd_results *cmd_results_new(enum cmd_status status, const char *error, ...);
|
struct cmd_results *cmd_results_new(enum cmd_status status, const char *error, ...) _SWAY_ATTRIB_PRINTF(2, 3);
|
||||||
/**
|
/**
|
||||||
* Frees a cmd_results object.
|
* Frees a cmd_results object.
|
||||||
*/
|
*/
|
||||||
|
@ -265,6 +266,7 @@ sway_cmd input_cmd_scroll_factor;
|
||||||
sway_cmd input_cmd_repeat_delay;
|
sway_cmd input_cmd_repeat_delay;
|
||||||
sway_cmd input_cmd_repeat_rate;
|
sway_cmd input_cmd_repeat_rate;
|
||||||
sway_cmd input_cmd_scroll_button;
|
sway_cmd input_cmd_scroll_button;
|
||||||
|
sway_cmd input_cmd_scroll_button_lock;
|
||||||
sway_cmd input_cmd_scroll_method;
|
sway_cmd input_cmd_scroll_method;
|
||||||
sway_cmd input_cmd_tap;
|
sway_cmd input_cmd_tap;
|
||||||
sway_cmd input_cmd_tap_button_map;
|
sway_cmd input_cmd_tap_button_map;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../include/config.h"
|
#include "../include/config.h"
|
||||||
#include "gesture.h"
|
#include "gesture.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "stringop.h"
|
||||||
#include "swaynag.h"
|
#include "swaynag.h"
|
||||||
#include "tree/container.h"
|
#include "tree/container.h"
|
||||||
#include "sway/input/tablet.h"
|
#include "sway/input/tablet.h"
|
||||||
|
@ -160,6 +161,7 @@ struct input_config {
|
||||||
int repeat_delay;
|
int repeat_delay;
|
||||||
int repeat_rate;
|
int repeat_rate;
|
||||||
int scroll_button;
|
int scroll_button;
|
||||||
|
int scroll_button_lock;
|
||||||
int scroll_method;
|
int scroll_method;
|
||||||
int send_events;
|
int send_events;
|
||||||
int tap;
|
int tap;
|
||||||
|
@ -625,7 +627,7 @@ void run_deferred_bindings(void);
|
||||||
/**
|
/**
|
||||||
* Adds a warning entry to the swaynag instance used for errors.
|
* Adds a warning entry to the swaynag instance used for errors.
|
||||||
*/
|
*/
|
||||||
void config_add_swaynag_warning(char *fmt, ...);
|
void config_add_swaynag_warning(char *fmt, ...) _SWAY_ATTRIB_PRINTF(1, 2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free config struct
|
* Free config struct
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct criteria {
|
||||||
struct pattern *window_role;
|
struct pattern *window_role;
|
||||||
enum atom_name window_type;
|
enum atom_name window_type;
|
||||||
#endif
|
#endif
|
||||||
|
bool all;
|
||||||
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
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
#ifndef _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
||||||
#define _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
#define _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
||||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||||
#include <wlr/types/wlr_idle.h>
|
|
||||||
#include "sway/server.h"
|
|
||||||
|
|
||||||
enum sway_idle_inhibit_mode {
|
enum sway_idle_inhibit_mode {
|
||||||
INHIBIT_IDLE_APPLICATION, // Application set inhibitor (when visible)
|
INHIBIT_IDLE_APPLICATION, // Application set inhibitor (when visible)
|
||||||
|
@ -16,12 +14,9 @@ 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;
|
||||||
struct wl_list inhibitors;
|
struct wl_list inhibitors;
|
||||||
|
|
||||||
struct wlr_idle *idle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_idle_inhibitor_v1 {
|
struct sway_idle_inhibitor_v1 {
|
||||||
struct sway_idle_inhibit_manager_v1 *manager;
|
|
||||||
struct wlr_idle_inhibitor_v1 *wlr_inhibitor;
|
struct wlr_idle_inhibitor_v1 *wlr_inhibitor;
|
||||||
struct sway_view *view;
|
struct sway_view *view;
|
||||||
enum sway_idle_inhibit_mode mode;
|
enum sway_idle_inhibit_mode mode;
|
||||||
|
@ -33,8 +28,7 @@ struct sway_idle_inhibitor_v1 {
|
||||||
bool sway_idle_inhibit_v1_is_active(
|
bool sway_idle_inhibit_v1_is_active(
|
||||||
struct sway_idle_inhibitor_v1 *inhibitor);
|
struct sway_idle_inhibitor_v1 *inhibitor);
|
||||||
|
|
||||||
void sway_idle_inhibit_v1_check_active(
|
void sway_idle_inhibit_v1_check_active(void);
|
||||||
struct sway_idle_inhibit_manager_v1 *manager);
|
|
||||||
|
|
||||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||||
enum sway_idle_inhibit_mode mode);
|
enum sway_idle_inhibit_mode mode);
|
||||||
|
@ -48,6 +42,6 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_vi
|
||||||
void sway_idle_inhibit_v1_user_inhibitor_destroy(
|
void sway_idle_inhibit_v1_user_inhibitor_destroy(
|
||||||
struct sway_idle_inhibitor_v1 *inhibitor);
|
struct sway_idle_inhibitor_v1 *inhibitor);
|
||||||
|
|
||||||
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
|
bool sway_idle_inhibit_manager_v1_init(void);
|
||||||
struct wl_display *wl_display, struct wlr_idle *idle);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,6 @@ struct sway_cursor {
|
||||||
pixman_region32_t confine; // invalid if active_constraint == NULL
|
pixman_region32_t confine; // invalid if active_constraint == NULL
|
||||||
bool active_confine_requires_warp;
|
bool active_confine_requires_warp;
|
||||||
|
|
||||||
struct wlr_pointer_gestures_v1 *pointer_gestures;
|
|
||||||
struct wl_listener hold_begin;
|
struct wl_listener hold_begin;
|
||||||
struct wl_listener hold_end;
|
struct wl_listener hold_end;
|
||||||
struct wl_listener pinch_begin;
|
struct wl_listener pinch_begin;
|
||||||
|
@ -53,6 +52,7 @@ struct sway_cursor {
|
||||||
|
|
||||||
struct wl_listener touch_down;
|
struct wl_listener touch_down;
|
||||||
struct wl_listener touch_up;
|
struct wl_listener touch_up;
|
||||||
|
struct wl_listener touch_cancel;
|
||||||
struct wl_listener touch_motion;
|
struct wl_listener touch_motion;
|
||||||
struct wl_listener touch_frame;
|
struct wl_listener touch_frame;
|
||||||
bool simulating_pointer_from_touch;
|
bool simulating_pointer_from_touch;
|
||||||
|
@ -145,4 +145,6 @@ uint32_t get_mouse_button(const char *name, char **error);
|
||||||
|
|
||||||
const char *get_mouse_button_name(uint32_t button);
|
const char *get_mouse_button_name(uint32_t button);
|
||||||
|
|
||||||
|
void handle_request_set_cursor_shape(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef _SWAY_INPUT_INPUT_MANAGER_H
|
#ifndef _SWAY_INPUT_INPUT_MANAGER_H
|
||||||
#define _SWAY_INPUT_INPUT_MANAGER_H
|
#define _SWAY_INPUT_INPUT_MANAGER_H
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <wlr/types/wlr_input_inhibitor.h>
|
|
||||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||||
|
@ -21,10 +20,10 @@ struct sway_input_manager {
|
||||||
struct wl_list devices;
|
struct wl_list devices;
|
||||||
struct wl_list seats;
|
struct wl_list seats;
|
||||||
|
|
||||||
struct wlr_input_inhibit_manager *inhibit;
|
|
||||||
struct wlr_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
struct wlr_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||||
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
|
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
|
||||||
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
|
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
|
||||||
|
struct wlr_pointer_gestures_v1 *pointer_gestures;
|
||||||
|
|
||||||
struct wl_listener new_input;
|
struct wl_listener new_input;
|
||||||
struct wl_listener inhibit_activate;
|
struct wl_listener inhibit_activate;
|
||||||
|
@ -44,7 +43,7 @@ void input_manager_configure_xcursor(void);
|
||||||
|
|
||||||
void input_manager_apply_input_config(struct input_config *input_config);
|
void input_manager_apply_input_config(struct input_config *input_config);
|
||||||
|
|
||||||
void input_manager_configure_all_inputs(void);
|
void input_manager_configure_all_input_mappings(void);
|
||||||
|
|
||||||
void input_manager_reset_input(struct sway_input_device *input_device);
|
void input_manager_reset_input(struct sway_input_device *input_device);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "sway/input/text_input.h"
|
#include "sway/input/text_input.h"
|
||||||
|
|
||||||
struct sway_seat;
|
struct sway_seat;
|
||||||
|
struct render_context;
|
||||||
|
|
||||||
struct sway_seatop_impl {
|
struct sway_seatop_impl {
|
||||||
void (*button)(struct sway_seat *seat, uint32_t time_msec,
|
void (*button)(struct sway_seat *seat, uint32_t time_msec,
|
||||||
|
@ -43,14 +44,15 @@ struct sway_seatop_impl {
|
||||||
struct wlr_touch_up_event *event);
|
struct wlr_touch_up_event *event);
|
||||||
void (*touch_down)(struct sway_seat *seat,
|
void (*touch_down)(struct sway_seat *seat,
|
||||||
struct wlr_touch_down_event *event, double lx, double ly);
|
struct wlr_touch_down_event *event, double lx, double ly);
|
||||||
|
void (*touch_cancel)(struct sway_seat *seat,
|
||||||
|
struct wlr_touch_cancel_event *event);
|
||||||
void (*tablet_tool_motion)(struct sway_seat *seat,
|
void (*tablet_tool_motion)(struct sway_seat *seat,
|
||||||
struct sway_tablet_tool *tool, uint32_t time_msec);
|
struct sway_tablet_tool *tool, uint32_t time_msec);
|
||||||
void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool,
|
void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool,
|
||||||
uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
|
uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
|
||||||
void (*end)(struct sway_seat *seat);
|
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 render_context *ctx);
|
||||||
const pixman_region32_t *damage);
|
|
||||||
bool allow_set_cursor;
|
bool allow_set_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,8 +104,9 @@ struct sway_seat {
|
||||||
struct sway_workspace *workspace;
|
struct sway_workspace *workspace;
|
||||||
char *prev_workspace_name; // for workspace back_and_forth
|
char *prev_workspace_name; // for workspace back_and_forth
|
||||||
|
|
||||||
// If the focused layer is set, views cannot receive keyboard focus
|
|
||||||
struct wlr_layer_surface_v1 *focused_layer;
|
struct wlr_layer_surface_v1 *focused_layer;
|
||||||
|
// If the exclusive layer is set, views cannot receive keyboard focus
|
||||||
|
bool has_exclusive_layer;
|
||||||
|
|
||||||
// If exclusive_client is set, no other clients will receive input events
|
// If exclusive_client is set, no other clients will receive input events
|
||||||
struct wl_client *exclusive_client;
|
struct wl_client *exclusive_client;
|
||||||
|
@ -165,6 +168,9 @@ void seat_add_device(struct sway_seat *seat,
|
||||||
void seat_configure_device(struct sway_seat *seat,
|
void seat_configure_device(struct sway_seat *seat,
|
||||||
struct sway_input_device *device);
|
struct sway_input_device *device);
|
||||||
|
|
||||||
|
void seat_configure_device_mapping(struct sway_seat *seat,
|
||||||
|
struct sway_input_device *input_device);
|
||||||
|
|
||||||
void seat_reset_device(struct sway_seat *seat,
|
void seat_reset_device(struct sway_seat *seat,
|
||||||
struct sway_input_device *input_device);
|
struct sway_input_device *input_device);
|
||||||
|
|
||||||
|
@ -338,6 +344,9 @@ void seatop_touch_up(struct sway_seat *seat,
|
||||||
void seatop_touch_down(struct sway_seat *seat,
|
void seatop_touch_down(struct sway_seat *seat,
|
||||||
struct wlr_touch_down_event *event, double lx, double ly);
|
struct wlr_touch_down_event *event, double lx, double ly);
|
||||||
|
|
||||||
|
void seatop_touch_cancel(struct sway_seat *seat,
|
||||||
|
struct wlr_touch_cancel_event *event);
|
||||||
|
|
||||||
void seatop_rebase(struct sway_seat *seat, uint32_t time_msec);
|
void seatop_rebase(struct sway_seat *seat, uint32_t time_msec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -356,8 +365,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con);
|
||||||
* Instructs a seatop to render anything that it needs to render
|
* Instructs a seatop to render anything that it needs to render
|
||||||
* (eg. dropzone for move-tiling)
|
* (eg. dropzone for move-tiling)
|
||||||
*/
|
*/
|
||||||
void seatop_render(struct sway_seat *seat, struct sway_output *output,
|
void seatop_render(struct sway_seat *seat, struct render_context *ctx);
|
||||||
const pixman_region32_t *damage);
|
|
||||||
|
|
||||||
bool seatop_allows_set_cursor(struct sway_seat *seat);
|
bool seatop_allows_set_cursor(struct sway_seat *seat);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
/**
|
/**
|
||||||
* The relay structure manages the relationship between text-input and
|
* The relay structure manages the relationship between text-input and
|
||||||
* input_method interfaces on a given seat. Multiple text-input interfaces may
|
* input_method interfaces on a given seat. Multiple text-input interfaces may
|
||||||
* be bound to a relay, but at most one will be focused (reveiving events) at
|
* be bound to a relay, but at most one will be focused (receiving events) at
|
||||||
* a time. At most one input-method interface may be bound to the seat. The
|
* a time. At most one input-method interface may be bound to the seat. The
|
||||||
* relay manages life cycle of both sides. When both sides are present and
|
* relay manages life cycle of both sides. When both sides are present and
|
||||||
* focused, the relay passes messages between them.
|
* focused, the relay passes messages between them.
|
||||||
|
|
|
@ -55,6 +55,10 @@ struct sway_layer_subsurface {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_output;
|
struct sway_output;
|
||||||
|
|
||||||
|
struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||||
|
struct wlr_surface *surface);
|
||||||
|
|
||||||
void arrange_layers(struct sway_output *output);
|
void arrange_layers(struct sway_output *output);
|
||||||
|
|
||||||
struct sway_layer_surface *layer_from_wlr_layer_surface_v1(
|
struct sway_layer_surface *layer_from_wlr_layer_surface_v1(
|
||||||
|
|
|
@ -33,8 +33,6 @@ struct sway_output {
|
||||||
int width, height; // transformed buffer size
|
int width, height; // transformed buffer size
|
||||||
enum wl_output_subpixel detected_subpixel;
|
enum wl_output_subpixel detected_subpixel;
|
||||||
enum scale_filter_mode scale_filter;
|
enum scale_filter_mode scale_filter;
|
||||||
// last applied mode when the output is powered off
|
|
||||||
struct wlr_output_mode *current_mode;
|
|
||||||
|
|
||||||
bool enabling, enabled;
|
bool enabling, enabled;
|
||||||
list_t *workspaces;
|
list_t *workspaces;
|
||||||
|
@ -57,6 +55,7 @@ struct sway_output {
|
||||||
uint32_t refresh_nsec;
|
uint32_t refresh_nsec;
|
||||||
int max_render_time; // In milliseconds
|
int max_render_time; // In milliseconds
|
||||||
struct wl_event_source *repaint_timer;
|
struct wl_event_source *repaint_timer;
|
||||||
|
bool gamma_lut_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_output_non_desktop {
|
struct sway_output_non_desktop {
|
||||||
|
@ -65,6 +64,14 @@ struct sway_output_non_desktop {
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct render_context {
|
||||||
|
struct sway_output *output;
|
||||||
|
struct wlr_renderer *renderer;
|
||||||
|
const pixman_region32_t *output_damage;
|
||||||
|
|
||||||
|
struct wlr_render_pass *pass;
|
||||||
|
};
|
||||||
|
|
||||||
struct sway_output *output_create(struct wlr_output *wlr_output);
|
struct sway_output *output_create(struct wlr_output *wlr_output);
|
||||||
|
|
||||||
void output_destroy(struct sway_output *output);
|
void output_destroy(struct sway_output *output);
|
||||||
|
@ -96,6 +103,9 @@ 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);
|
||||||
|
|
||||||
|
bool output_match_name_or_id(struct sway_output *output,
|
||||||
|
const char *name_or_id);
|
||||||
|
|
||||||
// this ONLY includes the enabled outputs
|
// 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);
|
||||||
|
|
||||||
|
@ -112,7 +122,7 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
|
||||||
|
|
||||||
struct sway_workspace *output_get_active_workspace(struct sway_output *output);
|
struct sway_workspace *output_get_active_workspace(struct sway_output *output);
|
||||||
|
|
||||||
void output_render(struct sway_output *output, pixman_region32_t *damage);
|
void output_render(struct render_context *ctx);
|
||||||
|
|
||||||
void output_surface_for_each_surface(struct sway_output *output,
|
void output_surface_for_each_surface(struct sway_output *output,
|
||||||
struct wlr_surface *surface, double ox, double oy,
|
struct wlr_surface *surface, double ox, double oy,
|
||||||
|
@ -165,8 +175,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 sway_output *output,
|
void render_rect(struct render_context *ctx, const struct wlr_box *_box,
|
||||||
const pixman_region32_t *output_damage, const struct wlr_box *_box,
|
|
||||||
float color[static 4]);
|
float color[static 4]);
|
||||||
|
|
||||||
void premultiply_alpha(float color[4], float opacity);
|
void premultiply_alpha(float color[4], float opacity);
|
||||||
|
@ -177,6 +186,8 @@ enum wlr_direction opposite_direction(enum wlr_direction d);
|
||||||
|
|
||||||
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "sway/desktop/idle_inhibit_v1.h"
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
#include "sway/xwayland.h"
|
#include "sway/xwayland.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,15 +52,14 @@ struct sway_server {
|
||||||
struct wl_listener new_output;
|
struct wl_listener new_output;
|
||||||
struct wl_listener output_layout_change;
|
struct wl_listener output_layout_change;
|
||||||
|
|
||||||
struct wlr_idle *idle;
|
|
||||||
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
||||||
struct sway_idle_inhibit_manager_v1 *idle_inhibit_manager_v1;
|
struct sway_idle_inhibit_manager_v1 idle_inhibit_manager_v1;
|
||||||
|
|
||||||
struct wlr_layer_shell_v1 *layer_shell;
|
struct wlr_layer_shell_v1 *layer_shell;
|
||||||
struct wl_listener layer_shell_surface;
|
struct wl_listener layer_shell_surface;
|
||||||
|
|
||||||
struct wlr_xdg_shell *xdg_shell;
|
struct wlr_xdg_shell *xdg_shell;
|
||||||
struct wl_listener xdg_shell_surface;
|
struct wl_listener xdg_shell_toplevel;
|
||||||
|
|
||||||
struct wlr_tablet_manager_v2 *tablet_v2;
|
struct wlr_tablet_manager_v2 *tablet_v2;
|
||||||
|
|
||||||
|
@ -91,6 +91,9 @@ struct sway_server {
|
||||||
struct wl_listener output_manager_apply;
|
struct wl_listener output_manager_apply;
|
||||||
struct wl_listener output_manager_test;
|
struct wl_listener output_manager_test;
|
||||||
|
|
||||||
|
struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1;
|
||||||
|
struct wl_listener gamma_control_set_gamma;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool locked;
|
bool locked;
|
||||||
struct wlr_session_lock_manager_v1 *manager;
|
struct wlr_session_lock_manager_v1 *manager;
|
||||||
|
@ -111,11 +114,17 @@ struct sway_server {
|
||||||
struct wlr_text_input_manager_v3 *text_input;
|
struct wlr_text_input_manager_v3 *text_input;
|
||||||
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
||||||
struct wlr_content_type_manager_v1 *content_type_manager_v1;
|
struct wlr_content_type_manager_v1 *content_type_manager_v1;
|
||||||
|
struct wlr_data_control_manager_v1 *data_control_manager_v1;
|
||||||
|
struct wlr_screencopy_manager_v1 *screencopy_manager_v1;
|
||||||
|
struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1;
|
||||||
|
struct wlr_security_context_manager_v1 *security_context_manager_v1;
|
||||||
|
|
||||||
struct wlr_xdg_activation_v1 *xdg_activation_v1;
|
struct wlr_xdg_activation_v1 *xdg_activation_v1;
|
||||||
struct wl_listener xdg_activation_v1_request_activate;
|
struct wl_listener xdg_activation_v1_request_activate;
|
||||||
struct wl_listener xdg_activation_v1_new_token;
|
struct wl_listener xdg_activation_v1_new_token;
|
||||||
|
|
||||||
|
struct wl_listener request_set_cursor_shape;
|
||||||
|
|
||||||
struct wl_list pending_launcher_ctxs; // launcher_ctx::link
|
struct wl_list pending_launcher_ctxs; // launcher_ctx::link
|
||||||
|
|
||||||
// The timeout for transactions, after which a transaction is applied
|
// The timeout for transactions, after which a transaction is applied
|
||||||
|
@ -167,7 +176,7 @@ void handle_new_output(struct wl_listener *listener, void *data);
|
||||||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
||||||
void handle_layer_shell_surface(struct wl_listener *listener, void *data);
|
void handle_layer_shell_surface(struct wl_listener *listener, void *data);
|
||||||
void sway_session_lock_init(void);
|
void sway_session_lock_init(void);
|
||||||
void handle_xdg_shell_surface(struct wl_listener *listener, void *data);
|
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data);
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef _SWAY_SWAYNAG_H
|
#ifndef _SWAY_SWAYNAG_H
|
||||||
#define _SWAY_SWAYNAG_H
|
#define _SWAY_SWAYNAG_H
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
struct swaynag_instance {
|
struct swaynag_instance {
|
||||||
struct wl_client *client;
|
struct wl_client *client;
|
||||||
|
@ -21,7 +22,7 @@ bool swaynag_spawn(const char *swaynag_command,
|
||||||
// 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,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...) _SWAY_ATTRIB_PRINTF(3, 4);
|
||||||
|
|
||||||
// If swaynag->detailed, close swaynag->fd[1] so swaynag displays
|
// If swaynag->detailed, close swaynag->fd[1] so swaynag displays
|
||||||
void swaynag_show(struct swaynag_instance *swaynag);
|
void swaynag_show(struct swaynag_instance *swaynag);
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct sway_root {
|
||||||
} events;
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_root *root_create(void);
|
struct sway_root *root_create(struct wl_display *display);
|
||||||
|
|
||||||
void root_destroy(struct sway_root *root);
|
void root_destroy(struct sway_root *root);
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,8 @@ struct sway_xwayland_view {
|
||||||
struct wl_listener set_window_type;
|
struct wl_listener set_window_type;
|
||||||
struct wl_listener set_hints;
|
struct wl_listener set_hints;
|
||||||
struct wl_listener set_decorations;
|
struct wl_listener set_decorations;
|
||||||
|
struct wl_listener associate;
|
||||||
|
struct wl_listener dissociate;
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
@ -177,6 +179,8 @@ struct sway_xwayland_unmanaged {
|
||||||
struct wl_listener request_fullscreen;
|
struct wl_listener request_fullscreen;
|
||||||
struct wl_listener commit;
|
struct wl_listener commit;
|
||||||
struct wl_listener set_geometry;
|
struct wl_listener set_geometry;
|
||||||
|
struct wl_listener associate;
|
||||||
|
struct wl_listener dissociate;
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
@ -222,6 +226,7 @@ struct sway_xdg_popup {
|
||||||
|
|
||||||
struct wlr_xdg_popup *wlr_xdg_popup;
|
struct wlr_xdg_popup *wlr_xdg_popup;
|
||||||
|
|
||||||
|
struct wl_listener surface_commit;
|
||||||
struct wl_listener new_popup;
|
struct wl_listener new_popup;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,4 +16,6 @@ struct sway_xdg_decoration {
|
||||||
struct sway_xdg_decoration *xdg_decoration_from_surface(
|
struct sway_xdg_decoration *xdg_decoration_from_surface(
|
||||||
struct wlr_surface *surface);
|
struct wlr_surface *surface);
|
||||||
|
|
||||||
|
void set_xdg_decoration_mode(struct sway_xdg_decoration *deco);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "pool-buffer.h"
|
#include "pool-buffer.h"
|
||||||
|
#include "cursor-shape-v1-client-protocol.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ struct swaybar {
|
||||||
struct wl_compositor *compositor;
|
struct wl_compositor *compositor;
|
||||||
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 wp_cursor_shape_manager_v1 *cursor_shape_manager;
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
|
|
||||||
struct swaybar_config *config;
|
struct swaybar_config *config;
|
||||||
|
|
7
include/swaybar/image.h
Normal file
7
include/swaybar/image.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef _SWAYBAR_IMAGE_H
|
||||||
|
#define _SWAYBAR_IMAGE_H
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
|
cairo_surface_t *load_image(const char *path);
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,6 +4,8 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "pool-buffer.h"
|
#include "pool-buffer.h"
|
||||||
|
#include "cursor-shape-v1-client-protocol.h"
|
||||||
|
|
||||||
#include "swaynag/types.h"
|
#include "swaynag/types.h"
|
||||||
|
|
||||||
#define SWAYNAG_MAX_HEIGHT 500
|
#define SWAYNAG_MAX_HEIGHT 500
|
||||||
|
@ -85,6 +87,7 @@ struct swaynag {
|
||||||
struct swaynag_output *output;
|
struct swaynag_output *output;
|
||||||
struct zwlr_layer_shell_v1 *layer_shell;
|
struct zwlr_layer_shell_v1 *layer_shell;
|
||||||
struct zwlr_layer_surface_v1 *layer_surface;
|
struct zwlr_layer_surface_v1 *layer_surface;
|
||||||
|
struct wp_cursor_shape_manager_v1 *cursor_shape_manager;
|
||||||
struct wl_surface *surface;
|
struct wl_surface *surface;
|
||||||
|
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
|
|
|
@ -18,6 +18,7 @@ add_project_arguments(
|
||||||
'-Wno-unused-parameter',
|
'-Wno-unused-parameter',
|
||||||
'-Wno-unused-result',
|
'-Wno-unused-result',
|
||||||
'-Wno-missing-braces',
|
'-Wno-missing-braces',
|
||||||
|
'-Wno-format-zero-length',
|
||||||
'-Wundef',
|
'-Wundef',
|
||||||
'-Wvla',
|
'-Wvla',
|
||||||
],
|
],
|
||||||
|
@ -36,7 +37,7 @@ if is_freebsd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Execute the wlroots subproject, if any
|
# Execute the wlroots subproject, if any
|
||||||
wlroots_version = ['>=0.17.0', '<0.18.0']
|
wlroots_version = ['>=0.18.0', '<0.19.0']
|
||||||
subproject(
|
subproject(
|
||||||
'wlroots',
|
'wlroots',
|
||||||
default_options: ['examples=false'],
|
default_options: ['examples=false'],
|
||||||
|
@ -47,7 +48,6 @@ wlroots = dependency('wlroots', version: wlroots_version)
|
||||||
wlroots_features = {
|
wlroots_features = {
|
||||||
'xwayland': false,
|
'xwayland': false,
|
||||||
'libinput_backend': false,
|
'libinput_backend': false,
|
||||||
'gles2_renderer': false,
|
|
||||||
'session': false,
|
'session': false,
|
||||||
}
|
}
|
||||||
foreach name, _ : wlroots_features
|
foreach name, _ : wlroots_features
|
||||||
|
@ -74,7 +74,6 @@ pango = dependency('pango')
|
||||||
pangocairo = dependency('pangocairo')
|
pangocairo = dependency('pangocairo')
|
||||||
gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf'))
|
gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf'))
|
||||||
pixman = dependency('pixman-1')
|
pixman = dependency('pixman-1')
|
||||||
glesv2 = wlroots_features['gles2_renderer'] ? dependency('glesv2') : null_dep
|
|
||||||
libevdev = dependency('libevdev')
|
libevdev = dependency('libevdev')
|
||||||
libinput = wlroots_features['libinput_backend'] ? dependency('libinput', version: '>=1.21.0') : null_dep
|
libinput = wlroots_features['libinput_backend'] ? dependency('libinput', version: '>=1.21.0') : null_dep
|
||||||
xcb = dependency('xcb', required: get_option('xwayland'))
|
xcb = dependency('xcb', required: get_option('xwayland'))
|
||||||
|
|
|
@ -2,7 +2,7 @@ wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
||||||
|
|
||||||
wayland_scanner_dep = dependency('wayland-scanner', native: true)
|
wayland_scanner_dep = dependency('wayland-scanner', native: true)
|
||||||
wayland_scanner = find_program(
|
wayland_scanner = find_program(
|
||||||
wayland_scanner_dep.get_variable(pkgconfig: 'wayland_scanner'),
|
wayland_scanner_dep.get_variable('wayland_scanner'),
|
||||||
native: true,
|
native: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ protocols = [
|
||||||
wl_protocol_dir / 'unstable/tablet/tablet-unstable-v2.xml',
|
wl_protocol_dir / 'unstable/tablet/tablet-unstable-v2.xml',
|
||||||
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
||||||
wl_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
wl_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
||||||
|
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||||
'wlr-layer-shell-unstable-v1.xml',
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
'idle.xml',
|
'idle.xml',
|
||||||
'wlr-input-inhibitor-unstable-v1.xml',
|
|
||||||
'wlr-output-power-management-unstable-v1.xml',
|
'wlr-output-power-management-unstable-v1.xml',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<protocol name="wlr_input_inhibit_unstable_v1">
|
|
||||||
<copyright>
|
|
||||||
Copyright © 2018 Drew DeVault
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that copyright notice and this permission
|
|
||||||
notice appear in supporting documentation, and that the name of
|
|
||||||
the copyright holders not be used in advertising or publicity
|
|
||||||
pertaining to distribution of the software without specific,
|
|
||||||
written prior permission. The copyright holders make no
|
|
||||||
representations about the suitability of this software for any
|
|
||||||
purpose. It is provided "as is" without express or implied
|
|
||||||
warranty.
|
|
||||||
|
|
||||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
||||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
||||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
||||||
THIS SOFTWARE.
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<interface name="zwlr_input_inhibit_manager_v1" version="1">
|
|
||||||
<description summary="inhibits input events to other clients">
|
|
||||||
Clients can use this interface to prevent input events from being sent to
|
|
||||||
any surfaces but its own, which is useful for example in lock screen
|
|
||||||
software. It is assumed that access to this interface will be locked down
|
|
||||||
to whitelisted clients by the compositor.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="get_inhibitor">
|
|
||||||
<description summary="inhibit input to other clients">
|
|
||||||
Activates the input inhibitor. As long as the inhibitor is active, the
|
|
||||||
compositor will not send input events to other clients.
|
|
||||||
</description>
|
|
||||||
<arg name="id" type="new_id" interface="zwlr_input_inhibitor_v1"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<enum name="error">
|
|
||||||
<entry name="already_inhibited" value="0" summary="an input inhibitor is already in use on the compositor"/>
|
|
||||||
</enum>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
<interface name="zwlr_input_inhibitor_v1" version="1">
|
|
||||||
<description summary="inhibits input to other clients">
|
|
||||||
While this resource exists, input to clients other than the owner of the
|
|
||||||
inhibitor resource will not receive input events. The client that owns
|
|
||||||
this resource will receive all input events normally. The compositor will
|
|
||||||
also disable all of its own input processing (such as keyboard shortcuts)
|
|
||||||
while the inhibitor is active.
|
|
||||||
|
|
||||||
The compositor may continue to send input events to selected clients,
|
|
||||||
such as an on-screen keyboard (via the input-method protocol).
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="destroy the input inhibitor object">
|
|
||||||
Destroy the inhibitor and allow other clients to receive input.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
</protocol>
|
|
|
@ -381,10 +381,13 @@ struct cmd_results *config_command(char *exec, char **new_block) {
|
||||||
sway_log(SWAY_INFO, "Config command: %s", exec);
|
sway_log(SWAY_INFO, "Config command: %s", exec);
|
||||||
const struct cmd_handler *handler = find_core_handler(argv[0]);
|
const struct cmd_handler *handler = find_core_handler(argv[0]);
|
||||||
if (!handler || !handler->handle) {
|
if (!handler || !handler->handle) {
|
||||||
const char *error = handler
|
if (handler) {
|
||||||
? "Command '%s' is shimmed, but unimplemented"
|
results = cmd_results_new(CMD_INVALID,
|
||||||
: "Unknown/invalid command '%s'";
|
"Command '%s' is shimmed, but unimplemented", argv[0]);
|
||||||
results = cmd_results_new(CMD_INVALID, error, argv[0]);
|
} else {
|
||||||
|
results = cmd_results_new(CMD_INVALID,
|
||||||
|
"Unknown/invalid command '%s'", argv[0]);
|
||||||
|
}
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,20 +489,10 @@ struct cmd_results *cmd_results_new(enum cmd_status status,
|
||||||
}
|
}
|
||||||
results->status = status;
|
results->status = status;
|
||||||
if (format) {
|
if (format) {
|
||||||
char *error = NULL;
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
int slen = vsnprintf(NULL, 0, format, args);
|
results->error = vformat_str(format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
if (slen > 0) {
|
|
||||||
error = malloc(slen + 1);
|
|
||||||
if (error != NULL) {
|
|
||||||
va_start(args, format);
|
|
||||||
vsnprintf(error, slen + 1, format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
results->error = error;
|
|
||||||
} else {
|
} else {
|
||||||
results->error = NULL;
|
results->error = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
|
||||||
char *err_str = NULL;
|
char *err_str = NULL;
|
||||||
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
||||||
if (!criteria) {
|
if (!criteria) {
|
||||||
error = cmd_results_new(CMD_INVALID, err_str);
|
error = cmd_results_new(CMD_INVALID, "%s", err_str);
|
||||||
free(err_str);
|
free(err_str);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,12 +73,10 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
++argv; --argc;
|
++argv; --argc;
|
||||||
} else if (config->reading && !config->current_bar) {
|
} else if (config->reading && !config->current_bar) {
|
||||||
int len = snprintf(NULL, 0, "bar-%d", config->bars->length) + 1;
|
id = format_str("bar-%d", config->bars->length);
|
||||||
id = malloc(len * sizeof(char));
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return cmd_results_new(CMD_FAILURE, "Unable to allocate bar id");
|
return cmd_results_new(CMD_FAILURE, "Unable to allocate bar id");
|
||||||
}
|
}
|
||||||
snprintf(id, len, "bar-%d", config->bars->length);
|
|
||||||
} else if (!config->reading && strcmp(argv[0], "mode") != 0 &&
|
} else if (!config->reading && strcmp(argv[0], "mode") != 0 &&
|
||||||
strcmp(argv[0], "hidden_state") != 0) {
|
strcmp(argv[0], "hidden_state") != 0) {
|
||||||
if (is_subcommand(argv[0])) {
|
if (is_subcommand(argv[0])) {
|
||||||
|
|
|
@ -96,7 +96,7 @@ static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code,
|
||||||
}
|
}
|
||||||
if (message) {
|
if (message) {
|
||||||
free_bar_binding(binding);
|
free_bar_binding(binding);
|
||||||
error = cmd_results_new(CMD_INVALID, message);
|
error = cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else if (!binding->button) {
|
} else if (!binding->button) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ static struct cmd_results *tray_bind(int argc, char **argv, bool code) {
|
||||||
}
|
}
|
||||||
if (message) {
|
if (message) {
|
||||||
free(binding);
|
free(binding);
|
||||||
error = cmd_results_new(CMD_INVALID, message);
|
error = cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else if (!binding->button) {
|
} else if (!binding->button) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
|
||||||
if (!button) {
|
if (!button) {
|
||||||
if (message) {
|
if (message) {
|
||||||
struct cmd_results *error =
|
struct cmd_results *error =
|
||||||
cmd_results_new(CMD_INVALID, message);
|
cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,7 +143,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
|
||||||
if (!button) {
|
if (!button) {
|
||||||
if (message) {
|
if (message) {
|
||||||
struct cmd_results *error =
|
struct cmd_results *error =
|
||||||
cmd_results_new(CMD_INVALID, message);
|
cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else {
|
} else {
|
||||||
|
@ -182,7 +182,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
|
||||||
uint32_t button = get_mouse_bindsym(name, &message);
|
uint32_t button = get_mouse_bindsym(name, &message);
|
||||||
if (message) {
|
if (message) {
|
||||||
struct cmd_results *error =
|
struct cmd_results *error =
|
||||||
cmd_results_new(CMD_INVALID, message);
|
cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else if (button) {
|
} else if (button) {
|
||||||
|
@ -539,7 +539,7 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
|
||||||
free_switch_binding(binding);
|
free_switch_binding(binding);
|
||||||
return cmd_results_new(CMD_FAILURE,
|
return cmd_results_new(CMD_FAILURE,
|
||||||
"Invalid %s command (expected binding with the form "
|
"Invalid %s command (expected binding with the form "
|
||||||
"<switch>:<state>)", bindtype, argc);
|
"<switch>:<state>)", bindtype);
|
||||||
}
|
}
|
||||||
if (strcmp(split->items[0], "tablet") == 0) {
|
if (strcmp(split->items[0], "tablet") == 0) {
|
||||||
binding->type = WLR_SWITCH_TYPE_TABLET_MODE;
|
binding->type = WLR_SWITCH_TYPE_TABLET_MODE;
|
||||||
|
@ -549,7 +549,8 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
|
||||||
free_switch_binding(binding);
|
free_switch_binding(binding);
|
||||||
return cmd_results_new(CMD_FAILURE,
|
return cmd_results_new(CMD_FAILURE,
|
||||||
"Invalid %s command (expected switch binding: "
|
"Invalid %s command (expected switch binding: "
|
||||||
"unknown switch %s)", bindtype, split->items[0]);
|
"unknown switch %s)", bindtype,
|
||||||
|
(const char *)split->items[0]);
|
||||||
}
|
}
|
||||||
if (strcmp(split->items[1], "on") == 0) {
|
if (strcmp(split->items[1], "on") == 0) {
|
||||||
binding->trigger = SWAY_SWITCH_TRIGGER_ON;
|
binding->trigger = SWAY_SWITCH_TRIGGER_ON;
|
||||||
|
@ -562,7 +563,7 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
|
||||||
return cmd_results_new(CMD_FAILURE,
|
return cmd_results_new(CMD_FAILURE,
|
||||||
"Invalid %s command "
|
"Invalid %s command "
|
||||||
"(expected switch state: unknown state %s)",
|
"(expected switch state: unknown state %s)",
|
||||||
bindtype, split->items[1]);
|
bindtype, (const char *)split->items[1]);
|
||||||
}
|
}
|
||||||
list_free_items_and_destroy(split);
|
list_free_items_and_destroy(split);
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,16 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
|
||||||
char *err;
|
char *err;
|
||||||
int width = (int)strtol(argv[0], &err, 10);
|
int width = (int)strtol(argv[0], &err, 10);
|
||||||
if (*err) {
|
if (*err) {
|
||||||
return cmd_results_new(CMD_INVALID, cmd_name, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[1], "x") != 0) {
|
if (strcmp(argv[1], "x") != 0) {
|
||||||
return cmd_results_new(CMD_INVALID, cmd_name, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int height = (int)strtol(argv[2], &err, 10);
|
int height = (int)strtol(argv[2], &err, 10);
|
||||||
if (*err) {
|
if (*err) {
|
||||||
return cmd_results_new(CMD_INVALID, cmd_name, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
*config_width = width;
|
*config_width = width;
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) {
|
||||||
char *err_str = NULL;
|
char *err_str = NULL;
|
||||||
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
||||||
if (!criteria) {
|
if (!criteria) {
|
||||||
error = cmd_results_new(CMD_INVALID, err_str);
|
error = cmd_results_new(CMD_INVALID, "%s", err_str);
|
||||||
free(err_str);
|
free(err_str);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[0], "none") == 0) {
|
if (strcmp(argv[0], "none") == 0) {
|
||||||
|
@ -38,7 +38,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
|
||||||
config->hide_edge_borders = E_NONE;
|
config->hide_edge_borders = E_NONE;
|
||||||
config->hide_edge_borders_smart = ESMART_NO_GAPS;
|
config->hide_edge_borders_smart = ESMART_NO_GAPS;
|
||||||
} else {
|
} else {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
config->hide_lone_tab = hide_lone_tab;
|
config->hide_lone_tab = hide_lone_tab;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct cmd_results *cmd_inhibit_idle(int argc, char **argv) {
|
||||||
sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor);
|
sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor);
|
||||||
} else {
|
} else {
|
||||||
inhibitor->mode = mode;
|
inhibitor->mode = mode;
|
||||||
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
sway_idle_inhibit_v1_check_active();
|
||||||
}
|
}
|
||||||
} else if (!clear) {
|
} else if (!clear) {
|
||||||
sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode);
|
sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode);
|
||||||
|
|
|
@ -27,6 +27,7 @@ static const struct cmd_handler input_handlers[] = {
|
||||||
{ "repeat_rate", input_cmd_repeat_rate },
|
{ "repeat_rate", input_cmd_repeat_rate },
|
||||||
{ "rotation_angle", input_cmd_rotation_angle },
|
{ "rotation_angle", input_cmd_rotation_angle },
|
||||||
{ "scroll_button", input_cmd_scroll_button },
|
{ "scroll_button", input_cmd_scroll_button },
|
||||||
|
{ "scroll_button_lock", input_cmd_scroll_button_lock },
|
||||||
{ "scroll_factor", input_cmd_scroll_factor },
|
{ "scroll_factor", input_cmd_scroll_factor },
|
||||||
{ "scroll_method", input_cmd_scroll_method },
|
{ "scroll_method", input_cmd_scroll_method },
|
||||||
{ "tap", input_cmd_tap },
|
{ "tap", input_cmd_tap },
|
||||||
|
|
|
@ -11,11 +11,21 @@ static bool parse_coords(const char *str, double *x, double *y, bool *mm) {
|
||||||
*mm = false;
|
*mm = false;
|
||||||
|
|
||||||
char *end;
|
char *end;
|
||||||
*x = strtod(str, &end);
|
|
||||||
if (end[0] != 'x') {
|
// Check for "0x" prefix to avoid strtod treating the string as hex
|
||||||
return false;
|
if (str[0] == '0' && str[1] == 'x') {
|
||||||
|
if (strlen(str) < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*x = 0;
|
||||||
|
end = (char *)str + 2;
|
||||||
|
} else {
|
||||||
|
*x = strtod(str, &end);
|
||||||
|
if (end[0] != 'x') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++end;
|
||||||
}
|
}
|
||||||
++end;
|
|
||||||
|
|
||||||
*y = strtod(end, &end);
|
*y = strtod(end, &end);
|
||||||
if (end[0] == 'm') {
|
if (end[0] == 'm') {
|
||||||
|
|
|
@ -49,5 +49,5 @@ struct cmd_results *input_cmd_map_to_region(int argc, char **argv) {
|
||||||
error:
|
error:
|
||||||
free(ic->mapped_to_region);
|
free(ic->mapped_to_region);
|
||||||
ic->mapped_to_region = NULL;
|
ic->mapped_to_region = NULL;
|
||||||
return cmd_results_new(CMD_FAILURE, errstr);
|
return cmd_results_new(CMD_FAILURE, "%s", errstr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct cmd_results *input_cmd_scroll_button(int argc, char **argv) {
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
uint32_t button = get_mouse_button(*argv, &message);
|
uint32_t button = get_mouse_button(*argv, &message);
|
||||||
if (message) {
|
if (message) {
|
||||||
error = cmd_results_new(CMD_INVALID, message);
|
error = cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN
|
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN
|
||||||
|
|
26
sway/commands/input/scroll_button_lock.c
Normal file
26
sway/commands/input/scroll_button_lock.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <libinput.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "sway/config.h"
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/input/input-manager.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *input_cmd_scroll_button_lock(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "scroll_button_lock", EXPECTED_AT_LEAST, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
struct input_config *ic = config->handler_context.input_config;
|
||||||
|
if (!ic) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "No input device defined.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_boolean(argv[0], true)) {
|
||||||
|
ic->scroll_button_lock = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED;
|
||||||
|
} else {
|
||||||
|
ic->scroll_button_lock = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
|
}
|
|
@ -153,7 +153,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
|
||||||
workspace->output);
|
workspace->output);
|
||||||
}
|
}
|
||||||
if (new_layout == L_NONE) {
|
if (new_layout == L_NONE) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
if (new_layout != old_layout) {
|
if (new_layout != old_layout) {
|
||||||
if (container) {
|
if (container) {
|
||||||
|
|
|
@ -470,7 +470,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
|
||||||
if (strcasecmp(argv[1], "number") == 0) {
|
if (strcasecmp(argv[1], "number") == 0) {
|
||||||
// move [window|container] [to] "workspace number x"
|
// move [window|container] [to] "workspace number x"
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
if (!isdigit(argv[2][0])) {
|
if (!isdigit(argv[2][0])) {
|
||||||
return cmd_results_new(CMD_INVALID,
|
return cmd_results_new(CMD_INVALID,
|
||||||
|
@ -530,7 +530,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
|
||||||
}
|
}
|
||||||
destination = &dest_con->node;
|
destination = &dest_con->node;
|
||||||
} else {
|
} else {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destination->type == N_CONTAINER &&
|
if (destination->type == N_CONTAINER &&
|
||||||
|
@ -829,7 +829,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_position_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool absolute = false;
|
bool absolute = false;
|
||||||
|
@ -839,19 +839,19 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
||||||
++argv;
|
++argv;
|
||||||
}
|
}
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_position_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", 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_INVALID, expected_position_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", 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) {
|
if (absolute) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_position_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
|
||||||
}
|
}
|
||||||
return cmd_move_to_position_pointer(container);
|
return cmd_move_to_position_pointer(container);
|
||||||
} else if (strcmp(argv[0], "center") == 0) {
|
} else if (strcmp(argv[0], "center") == 0) {
|
||||||
|
@ -873,7 +873,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
return cmd_results_new(CMD_FAILURE, expected_position_syntax);
|
return cmd_results_new(CMD_FAILURE, "%s", expected_position_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct movement_amount lx = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
|
struct movement_amount lx = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
|
||||||
|
@ -886,7 +886,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
return cmd_results_new(CMD_FAILURE, expected_position_syntax);
|
return cmd_results_new(CMD_FAILURE, "%s", expected_position_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct movement_amount ly = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
|
struct movement_amount ly = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
|
||||||
|
@ -895,7 +895,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
|
||||||
argc -= num_consumed_args;
|
argc -= num_consumed_args;
|
||||||
argv += num_consumed_args;
|
argv += num_consumed_args;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_position_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
|
||||||
}
|
}
|
||||||
if (ly.unit == MOVEMENT_UNIT_INVALID) {
|
if (ly.unit == MOVEMENT_UNIT_INVALID) {
|
||||||
return cmd_results_new(CMD_INVALID, "Invalid y position specified");
|
return cmd_results_new(CMD_INVALID, "Invalid y position specified");
|
||||||
|
@ -1041,13 +1041,13 @@ struct cmd_results *cmd_move(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_full_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only `move [window|container] [to] workspace` supports
|
// Only `move [window|container] [to] workspace` supports
|
||||||
// `--no-auto-back-and-forth` so treat others as invalid syntax
|
// `--no-auto-back-and-forth` so treat others as invalid syntax
|
||||||
if (no_auto_back_and_forth && strcasecmp(argv[0], "workspace") != 0) {
|
if (no_auto_back_and_forth && strcasecmp(argv[0], "workspace") != 0) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_full_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(argv[0], "workspace") == 0 ||
|
if (strcasecmp(argv[0], "workspace") == 0 ||
|
||||||
|
@ -1061,5 +1061,5 @@ struct cmd_results *cmd_move(int argc, char **argv) {
|
||||||
strcasecmp(argv[1], "position") == 0)) {
|
strcasecmp(argv[1], "position") == 0)) {
|
||||||
return cmd_move_to_position(argc, argv);
|
return cmd_move_to_position(argc, argv);
|
||||||
}
|
}
|
||||||
return cmd_results_new(CMD_INVALID, expected_full_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct cmd_results *cmd_no_focus(int argc, char **argv) {
|
||||||
char *err_str = NULL;
|
char *err_str = NULL;
|
||||||
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
struct criteria *criteria = criteria_parse(argv[0], &err_str);
|
||||||
if (!criteria) {
|
if (!criteria) {
|
||||||
error = cmd_results_new(CMD_INVALID, err_str);
|
error = cmd_results_new(CMD_INVALID, "%s", err_str);
|
||||||
free(err_str);
|
free(err_str);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <wlr/util/transform.h>
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
|
@ -26,7 +26,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
||||||
"Can't run this command while there's no outputs connected.");
|
"Can't run this command while there's no outputs connected.");
|
||||||
}
|
}
|
||||||
if (strcasecmp(argv[0], "workspace") != 0) {
|
if (strcasecmp(argv[0], "workspace") != 0) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
int argn = 1;
|
int argn = 1;
|
||||||
|
@ -65,7 +65,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
||||||
++argn; // move past "to"
|
++argn; // move past "to"
|
||||||
|
|
||||||
if (argn >= argc) {
|
if (argn >= argc) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *new_name = join_args(argv + argn, argc - argn);
|
char *new_name = join_args(argv + argn, argc - argn);
|
||||||
|
|
|
@ -75,6 +75,10 @@ void container_resize_tiled(struct sway_container *con,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (container_is_scratchpad_hidden_or_child(con)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// For HORIZONTAL or VERTICAL, we are growing in two directions so select
|
// For HORIZONTAL or VERTICAL, we are growing in two directions so select
|
||||||
// both adjacent siblings. For RIGHT or DOWN, just select the next sibling.
|
// both adjacent siblings. For RIGHT or DOWN, just select the next sibling.
|
||||||
// For LEFT or UP, convert it to a RIGHT or DOWN resize and reassign con to
|
// For LEFT or UP, convert it to a RIGHT or DOWN resize and reassign con to
|
||||||
|
@ -249,16 +253,35 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis,
|
||||||
struct movement_amount *amount) {
|
struct movement_amount *amount) {
|
||||||
struct sway_container *current = config->handler_context.container;
|
struct sway_container *current = config->handler_context.container;
|
||||||
|
|
||||||
|
if (container_is_scratchpad_hidden_or_child(current)) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "Cannot resize a hidden scratchpad container");
|
||||||
|
}
|
||||||
|
|
||||||
if (amount->unit == MOVEMENT_UNIT_DEFAULT) {
|
if (amount->unit == MOVEMENT_UNIT_DEFAULT) {
|
||||||
amount->unit = MOVEMENT_UNIT_PPT;
|
amount->unit = MOVEMENT_UNIT_PPT;
|
||||||
}
|
}
|
||||||
if (amount->unit == MOVEMENT_UNIT_PPT) {
|
if (amount->unit == MOVEMENT_UNIT_PPT) {
|
||||||
|
struct sway_container *parent = current->pending.parent;
|
||||||
float pct = amount->amount / 100.0f;
|
float pct = amount->amount / 100.0f;
|
||||||
|
|
||||||
if (is_horizontal(axis)) {
|
if (is_horizontal(axis)) {
|
||||||
amount->amount = (float)current->pending.width * pct;
|
while (parent && parent->pending.layout != L_HORIZ) {
|
||||||
|
parent = parent->pending.parent;
|
||||||
|
}
|
||||||
|
if (parent) {
|
||||||
|
amount->amount = (float)parent->pending.width * pct;
|
||||||
|
} else {
|
||||||
|
amount->amount = (float)current->pending.workspace->width * pct;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
amount->amount = (float)current->pending.height * pct;
|
while (parent && parent->pending.layout != L_VERT) {
|
||||||
|
parent = parent->pending.parent;
|
||||||
|
}
|
||||||
|
if (parent) {
|
||||||
|
amount->amount = (float)parent->pending.height * pct;
|
||||||
|
} else {
|
||||||
|
amount->amount = (float)current->pending.workspace->height * pct;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,6 +300,11 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis,
|
||||||
*/
|
*/
|
||||||
static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
||||||
struct movement_amount *width, struct movement_amount *height) {
|
struct movement_amount *width, struct movement_amount *height) {
|
||||||
|
|
||||||
|
if (container_is_scratchpad_hidden_or_child(con)) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "Cannot resize a hidden scratchpad container");
|
||||||
|
}
|
||||||
|
|
||||||
if (width->amount) {
|
if (width->amount) {
|
||||||
if (width->unit == MOVEMENT_UNIT_PPT ||
|
if (width->unit == MOVEMENT_UNIT_PPT ||
|
||||||
width->unit == MOVEMENT_UNIT_DEFAULT) {
|
width->unit == MOVEMENT_UNIT_DEFAULT) {
|
||||||
|
@ -415,7 +443,7 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
|
||||||
argc -= num_consumed_args;
|
argc -= num_consumed_args;
|
||||||
argv += num_consumed_args;
|
argv += num_consumed_args;
|
||||||
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,10 +455,10 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
int num_consumed_args = parse_movement_amount(argc, argv, &height);
|
int num_consumed_args = parse_movement_amount(argc, argv, &height);
|
||||||
if (argc > num_consumed_args) {
|
if (argc > num_consumed_args) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +490,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
||||||
"[<amount> px|ppt [or <amount> px|ppt]]'";
|
"[<amount> px|ppt [or <amount> px|ppt]]'";
|
||||||
uint32_t axis = parse_resize_axis(*argv);
|
uint32_t axis = parse_resize_axis(*argv);
|
||||||
if (axis == WLR_EDGE_NONE) {
|
if (axis == WLR_EDGE_NONE) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
--argc; ++argv;
|
--argc; ++argv;
|
||||||
|
|
||||||
|
@ -473,7 +501,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
||||||
argc -= num_consumed_args;
|
argc -= num_consumed_args;
|
||||||
argv += num_consumed_args;
|
argv += num_consumed_args;
|
||||||
if (first_amount.unit == MOVEMENT_UNIT_INVALID) {
|
if (first_amount.unit == MOVEMENT_UNIT_INVALID) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
first_amount.amount = 10;
|
first_amount.amount = 10;
|
||||||
|
@ -483,7 +511,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
||||||
// "or"
|
// "or"
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if (strcmp(*argv, "or") != 0) {
|
if (strcmp(*argv, "or") != 0) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
--argc; ++argv;
|
--argc; ++argv;
|
||||||
}
|
}
|
||||||
|
@ -493,10 +521,10 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
||||||
if (argc) {
|
if (argc) {
|
||||||
int num_consumed_args = parse_movement_amount(argc, argv, &second_amount);
|
int num_consumed_args = parse_movement_amount(argc, argv, &second_amount);
|
||||||
if (argc > num_consumed_args) {
|
if (argc > num_consumed_args) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
if (second_amount.unit == MOVEMENT_UNIT_INVALID) {
|
if (second_amount.unit == MOVEMENT_UNIT_INVALID) {
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
second_amount.amount = 0;
|
second_amount.amount = 0;
|
||||||
|
@ -566,5 +594,5 @@ struct cmd_results *cmd_resize(int argc, char **argv) {
|
||||||
const char usage[] = "Expected 'resize <shrink|grow> "
|
const char usage[] = "Expected 'resize <shrink|grow> "
|
||||||
"<width|height|up|down|left|right> [<amount>] [px|ppt]'";
|
"<width|height|up|down|left|right> [<amount>] [px|ppt]'";
|
||||||
|
|
||||||
return cmd_results_new(CMD_INVALID, usage);
|
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor,
|
||||||
int argc, char **argv) {
|
int argc, char **argv) {
|
||||||
if (strcasecmp(argv[0], "move") == 0) {
|
if (strcasecmp(argv[0], "move") == 0) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
int delta_x = strtol(argv[1], NULL, 10);
|
int delta_x = strtol(argv[1], NULL, 10);
|
||||||
int delta_y = strtol(argv[2], NULL, 10);
|
int delta_y = strtol(argv[2], NULL, 10);
|
||||||
|
@ -27,7 +27,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor,
|
||||||
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
||||||
} else if (strcasecmp(argv[0], "set") == 0) {
|
} else if (strcasecmp(argv[0], "set") == 0) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
// map absolute coords (0..1,0..1) to root container coords
|
// map absolute coords (0..1,0..1) to root container coords
|
||||||
float x = strtof(argv[1], NULL) / root->width;
|
float x = strtof(argv[1], NULL) / root->width;
|
||||||
|
@ -37,7 +37,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor,
|
||||||
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
||||||
} else {
|
} else {
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
struct cmd_results *error = NULL;
|
struct cmd_results *error = NULL;
|
||||||
if ((error = press_or_release(cursor, argv[0], argv[1]))) {
|
if ((error = press_or_release(cursor, argv[0], argv[1]))) {
|
||||||
|
@ -92,14 +92,14 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor,
|
||||||
} else if (strcasecmp(action, "release") == 0) {
|
} else if (strcasecmp(action, "release") == 0) {
|
||||||
state = WLR_BUTTON_RELEASED;
|
state = WLR_BUTTON_RELEASED;
|
||||||
} else {
|
} else {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
button = get_mouse_button(button_str, &message);
|
button = get_mouse_button(button_str, &message);
|
||||||
if (message) {
|
if (message) {
|
||||||
struct cmd_results *error =
|
struct cmd_results *error =
|
||||||
cmd_results_new(CMD_INVALID, message);
|
cmd_results_new(CMD_INVALID, "%s", message);
|
||||||
free(message);
|
free(message);
|
||||||
return error;
|
return error;
|
||||||
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN
|
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "log.h"
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/input/seat.h"
|
#include "sway/input/seat.h"
|
||||||
|
@ -69,5 +70,10 @@ struct cmd_results *seat_cmd_idle_wake(int argc, char **argv) {
|
||||||
return cmd_results_new(CMD_FAILURE, "Invalid idle source");
|
return cmd_results_new(CMD_FAILURE, "Invalid idle source");
|
||||||
}
|
}
|
||||||
config->handler_context.seat_config->idle_wake_sources = sources;
|
config->handler_context.seat_config->idle_wake_sources = sources;
|
||||||
|
sway_log(SWAY_INFO, "Warning: seat idle_wake is deprecated");
|
||||||
|
if (config->reading) {
|
||||||
|
config_add_swaynag_warning("seat idle_wake is deprecated. "
|
||||||
|
"Only seat idle_inhibit is supported.");
|
||||||
|
}
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ static struct cmd_results *do_split(int layout) {
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cmd_results *do_unsplit() {
|
static struct cmd_results *do_unsplit(void) {
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(argv[0], "container") || strcasecmp(argv[1], "with")) {
|
if (strcasecmp(argv[0], "container") || strcasecmp(argv[1], "with")) {
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_container *current = config->handler_context.container;
|
struct sway_container *current = config->handler_context.container;
|
||||||
|
@ -65,7 +65,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|
||||||
other = root_find_container(test_mark, value);
|
other = root_find_container(test_mark, value);
|
||||||
} else {
|
} else {
|
||||||
free(value);
|
free(value);
|
||||||
return cmd_results_new(CMD_INVALID, expected_syntax);
|
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!other) {
|
if (!other) {
|
||||||
|
|
|
@ -61,7 +61,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
|
||||||
const char expected[] = "Expected 'workspace <name> gaps "
|
const char expected[] = "Expected 'workspace <name> gaps "
|
||||||
"inner|outer|horizontal|vertical|top|right|bottom|left <px>'";
|
"inner|outer|horizontal|vertical|top|right|bottom|left <px>'";
|
||||||
if (gaps_location == 0) {
|
if (gaps_location == 0) {
|
||||||
return cmd_results_new(CMD_INVALID, expected);
|
return cmd_results_new(CMD_INVALID, "%s", expected);
|
||||||
}
|
}
|
||||||
struct cmd_results *error = NULL;
|
struct cmd_results *error = NULL;
|
||||||
if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO,
|
if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO,
|
||||||
|
@ -79,7 +79,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
|
||||||
char *end;
|
char *end;
|
||||||
int amount = strtol(argv[gaps_location + 2], &end, 10);
|
int amount = strtol(argv[gaps_location + 2], &end, 10);
|
||||||
if (strlen(end)) {
|
if (strlen(end)) {
|
||||||
return cmd_results_new(CMD_FAILURE, expected);
|
return cmd_results_new(CMD_FAILURE, "%s", expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
@ -110,7 +110,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return cmd_results_new(CMD_INVALID, expected);
|
return cmd_results_new(CMD_INVALID, "%s", expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent invalid gaps configurations.
|
// Prevent invalid gaps configurations.
|
||||||
|
@ -174,7 +174,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root->fullscreen_global) {
|
if (root->fullscreen_global) {
|
||||||
return cmd_results_new(CMD_FAILURE, "workspace",
|
return cmd_results_new(CMD_FAILURE,
|
||||||
"Can't switch workspaces while fullscreen global");
|
"Can't switch workspaces while fullscreen global");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -924,23 +924,18 @@ void config_add_swaynag_warning(char *fmt, ...) {
|
||||||
if (config->reading && !config->validating) {
|
if (config->reading && !config->validating) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
|
char *str = vformat_str(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
if (str == NULL) {
|
||||||
char *temp = malloc(length + 1);
|
|
||||||
if (!temp) {
|
|
||||||
sway_log(SWAY_ERROR, "Failed to allocate buffer for warning.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
vsnprintf(temp, length, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
swaynag_log(config->swaynag_command, &config->swaynag_config_errors,
|
swaynag_log(config->swaynag_command, &config->swaynag_config_errors,
|
||||||
"Warning on line %i (%s) '%s': %s",
|
"Warning on line %i (%s) '%s': %s",
|
||||||
config->current_config_line_number, config->current_config_path,
|
config->current_config_line_number, config->current_config_path,
|
||||||
config->current_config_line, temp);
|
config->current_config_line, str);
|
||||||
|
|
||||||
|
free(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct input_config *new_input_config(const char* identifier) {
|
||||||
input->pointer_accel = FLT_MIN;
|
input->pointer_accel = FLT_MIN;
|
||||||
input->scroll_factor = FLT_MIN;
|
input->scroll_factor = FLT_MIN;
|
||||||
input->scroll_button = INT_MIN;
|
input->scroll_button = INT_MIN;
|
||||||
|
input->scroll_button_lock = INT_MIN;
|
||||||
input->scroll_method = INT_MIN;
|
input->scroll_method = INT_MIN;
|
||||||
input->left_handed = INT_MIN;
|
input->left_handed = INT_MIN;
|
||||||
input->repeat_delay = INT_MIN;
|
input->repeat_delay = INT_MIN;
|
||||||
|
@ -96,6 +97,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
|
||||||
if (src->scroll_button != INT_MIN) {
|
if (src->scroll_button != INT_MIN) {
|
||||||
dst->scroll_button = src->scroll_button;
|
dst->scroll_button = src->scroll_button;
|
||||||
}
|
}
|
||||||
|
if (src->scroll_button_lock != INT_MIN) {
|
||||||
|
dst->scroll_button_lock = src->scroll_button_lock;
|
||||||
|
}
|
||||||
if (src->send_events != INT_MIN) {
|
if (src->send_events != INT_MIN) {
|
||||||
dst->send_events = src->send_events;
|
dst->send_events = src->send_events;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,25 +153,16 @@ static void merge_wildcard_on_all(struct output_config *wildcard) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void merge_id_on_name(struct output_config *oc) {
|
static void merge_id_on_name(struct output_config *oc) {
|
||||||
char *id_on_name = NULL;
|
struct sway_output *output = all_output_by_name_or_id(oc->name);
|
||||||
char id[128];
|
if (output == NULL) {
|
||||||
char *name = NULL;
|
return;
|
||||||
struct sway_output *output;
|
|
||||||
wl_list_for_each(output, &root->all_outputs, link) {
|
|
||||||
name = output->wlr_output->name;
|
|
||||||
output_get_identifier(id, sizeof(id), output);
|
|
||||||
if (strcmp(name, oc->name) == 0 || strcmp(id, oc->name) == 0) {
|
|
||||||
size_t length = snprintf(NULL, 0, "%s on %s", id, name) + 1;
|
|
||||||
id_on_name = malloc(length);
|
|
||||||
if (!id_on_name) {
|
|
||||||
sway_log(SWAY_ERROR, "Failed to allocate id on name string");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
snprintf(id_on_name, length, "%s on %s", id, name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *name = output->wlr_output->name;
|
||||||
|
char id[128];
|
||||||
|
output_get_identifier(id, sizeof(id), output);
|
||||||
|
|
||||||
|
char *id_on_name = format_str("%s on %s", id, name);
|
||||||
if (!id_on_name) {
|
if (!id_on_name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -258,6 +249,8 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
|
||||||
// as (int)(1000 * mHz / 1000.f)
|
// as (int)(1000 * mHz / 1000.f)
|
||||||
// round() the result to avoid any error
|
// round() the result to avoid any error
|
||||||
int mhz = (int)roundf(refresh_rate * 1000);
|
int mhz = (int)roundf(refresh_rate * 1000);
|
||||||
|
// If no target refresh rate is given, match highest available
|
||||||
|
mhz = mhz <= 0 ? INT_MAX : mhz;
|
||||||
|
|
||||||
if (wl_list_empty(&output->modes) || custom) {
|
if (wl_list_empty(&output->modes) || custom) {
|
||||||
sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
|
sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
|
||||||
|
@ -267,23 +260,28 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_mode *mode, *best = NULL;
|
struct wlr_output_mode *mode, *best = NULL;
|
||||||
|
int best_diff_mhz = INT_MAX;
|
||||||
wl_list_for_each(mode, &output->modes, link) {
|
wl_list_for_each(mode, &output->modes, link) {
|
||||||
if (mode->width == width && mode->height == height) {
|
if (mode->width == width && mode->height == height) {
|
||||||
if (mode->refresh == mhz) {
|
int diff_mhz = abs(mode->refresh - mhz);
|
||||||
best = mode;
|
if (diff_mhz < best_diff_mhz) {
|
||||||
break;
|
best_diff_mhz = diff_mhz;
|
||||||
}
|
|
||||||
if (best == NULL || mode->refresh > best->refresh) {
|
|
||||||
best = mode;
|
best = mode;
|
||||||
|
if (best_diff_mhz == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!best) {
|
if (best) {
|
||||||
sway_log(SWAY_ERROR, "Configured mode for %s not available", output->name);
|
sway_log(SWAY_INFO, "Assigning configured mode (%dx%d@%.3fHz) to %s",
|
||||||
sway_log(SWAY_INFO, "Picking preferred mode instead");
|
best->width, best->height, best->refresh / 1000.f, output->name);
|
||||||
best = wlr_output_preferred_mode(output);
|
|
||||||
} else {
|
} else {
|
||||||
sway_log(SWAY_DEBUG, "Assigning configured mode to %s", output->name);
|
best = wlr_output_preferred_mode(output);
|
||||||
|
sway_log(SWAY_INFO, "Configured mode (%dx%d@%.3fHz) not available, "
|
||||||
|
"applying preferred mode (%dx%d@%.3fHz)",
|
||||||
|
width, height, refresh_rate,
|
||||||
|
best->width, best->height, best->refresh / 1000.f);
|
||||||
}
|
}
|
||||||
wlr_output_state_set_mode(pending, best);
|
wlr_output_state_set_mode(pending, best);
|
||||||
}
|
}
|
||||||
|
@ -519,10 +517,6 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
struct wlr_output_state pending = {0};
|
struct wlr_output_state pending = {0};
|
||||||
queue_output_config(oc, output, &pending);
|
queue_output_config(oc, output, &pending);
|
||||||
|
|
||||||
if (!oc || oc->power != 0) {
|
|
||||||
output->current_mode = pending.mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
|
sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
|
||||||
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
||||||
// Failed to commit output changes, maybe the output is missing a CRTC.
|
// Failed to commit output changes, maybe the output is missing a CRTC.
|
||||||
|
@ -596,7 +590,7 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
// Reconfigure all devices, since input config may have been applied before
|
// Reconfigure all devices, since input config may have been applied before
|
||||||
// this output came online, and some config items (like map_to_output) are
|
// this output came online, and some config items (like map_to_output) are
|
||||||
// dependent on an output being present.
|
// dependent on an output being present.
|
||||||
input_manager_configure_all_inputs();
|
input_manager_configure_all_input_mappings();
|
||||||
// Reconfigure the cursor images, since the scale may have changed.
|
// Reconfigure the cursor images, since the scale may have changed.
|
||||||
input_manager_configure_xcursor();
|
input_manager_configure_xcursor();
|
||||||
return true;
|
return true;
|
||||||
|
@ -639,9 +633,7 @@ static struct output_config *get_output_config(char *identifier,
|
||||||
struct output_config *oc_name = NULL;
|
struct output_config *oc_name = NULL;
|
||||||
struct output_config *oc_id = NULL;
|
struct output_config *oc_id = NULL;
|
||||||
|
|
||||||
size_t length = snprintf(NULL, 0, "%s on %s", identifier, name) + 1;
|
char *id_on_name = format_str("%s on %s", identifier, name);
|
||||||
char *id_on_name = malloc(length);
|
|
||||||
snprintf(id_on_name, length, "%s on %s", identifier, name);
|
|
||||||
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
|
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
oc_id_on_name = config->output_configs->items[i];
|
oc_id_on_name = config->output_configs->items[i];
|
||||||
|
@ -728,12 +720,11 @@ void apply_output_config_to_outputs(struct output_config *oc) {
|
||||||
// this is during startup then there will be no container and config
|
// this is during startup then there will be no container and config
|
||||||
// will be applied during normal "new output" event from wlroots.
|
// will be applied during normal "new output" event from wlroots.
|
||||||
bool wildcard = strcmp(oc->name, "*") == 0;
|
bool wildcard = strcmp(oc->name, "*") == 0;
|
||||||
char id[128];
|
|
||||||
struct sway_output *sway_output, *tmp;
|
struct sway_output *sway_output, *tmp;
|
||||||
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
|
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
|
||||||
char *name = sway_output->wlr_output->name;
|
if (output_match_name_or_id(sway_output, oc->name)) {
|
||||||
output_get_identifier(id, sizeof(id), sway_output);
|
char id[128];
|
||||||
if (wildcard || !strcmp(name, oc->name) || !strcmp(id, oc->name)) {
|
output_get_identifier(id, sizeof(id), sway_output);
|
||||||
struct output_config *current = get_output_config(id, sway_output);
|
struct output_config *current = get_output_config(id, sway_output);
|
||||||
if (!current) {
|
if (!current) {
|
||||||
// No stored output config matched, apply oc directly
|
// No stored output config matched, apply oc directly
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
bool criteria_is_empty(struct criteria *criteria) {
|
bool criteria_is_empty(struct criteria *criteria) {
|
||||||
return !criteria->title
|
return !criteria->title
|
||||||
&& !criteria->shell
|
&& !criteria->shell
|
||||||
|
&& !criteria->all
|
||||||
&& !criteria->app_id
|
&& !criteria->app_id
|
||||||
&& !criteria->con_mark
|
&& !criteria->con_mark
|
||||||
&& !criteria->con_id
|
&& !criteria->con_id
|
||||||
|
@ -456,6 +457,7 @@ static enum atom_name parse_window_type(const char *type) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum criteria_token {
|
enum criteria_token {
|
||||||
|
T_ALL,
|
||||||
T_APP_ID,
|
T_APP_ID,
|
||||||
T_CON_ID,
|
T_CON_ID,
|
||||||
T_CON_MARK,
|
T_CON_MARK,
|
||||||
|
@ -478,7 +480,9 @@ enum criteria_token {
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum criteria_token token_from_name(char *name) {
|
static enum criteria_token token_from_name(char *name) {
|
||||||
if (strcmp(name, "app_id") == 0) {
|
if (strcmp(name, "all") == 0) {
|
||||||
|
return T_ALL;
|
||||||
|
} else if (strcmp(name, "app_id") == 0) {
|
||||||
return T_APP_ID;
|
return T_APP_ID;
|
||||||
} else if (strcmp(name, "con_id") == 0) {
|
} else if (strcmp(name, "con_id") == 0) {
|
||||||
return T_CON_ID;
|
return T_CON_ID;
|
||||||
|
@ -524,8 +528,8 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Require value, unless token is floating or tiled
|
// Require value, unless token is all, floating or tiled
|
||||||
if (!value && token != T_FLOATING && token != T_TILING) {
|
if (!value && token != T_ALL && token != T_FLOATING && token != T_TILING) {
|
||||||
const char *fmt = "Token '%s' requires a value";
|
const char *fmt = "Token '%s' requires a value";
|
||||||
int len = strlen(fmt) + strlen(name) - 1;
|
int len = strlen(fmt) + strlen(name) - 1;
|
||||||
error = malloc(len);
|
error = malloc(len);
|
||||||
|
@ -535,6 +539,9 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
||||||
|
|
||||||
char *endptr = NULL;
|
char *endptr = NULL;
|
||||||
switch (token) {
|
switch (token) {
|
||||||
|
case T_ALL:
|
||||||
|
criteria->all = true;
|
||||||
|
break;
|
||||||
case T_TITLE:
|
case T_TITLE:
|
||||||
pattern_create(&criteria->title, value);
|
pattern_create(&criteria->title, value);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wlr/types/wlr_idle.h>
|
|
||||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "sway/desktop/idle_inhibit_v1.h"
|
#include "sway/desktop/idle_inhibit_v1.h"
|
||||||
|
@ -12,7 +11,7 @@
|
||||||
static void destroy_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor) {
|
static void destroy_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||||
wl_list_remove(&inhibitor->link);
|
wl_list_remove(&inhibitor->link);
|
||||||
wl_list_remove(&inhibitor->destroy.link);
|
wl_list_remove(&inhibitor->destroy.link);
|
||||||
sway_idle_inhibit_v1_check_active(inhibitor->manager);
|
sway_idle_inhibit_v1_check_active();
|
||||||
free(inhibitor);
|
free(inhibitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +34,6 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inhibitor->manager = manager;
|
|
||||||
inhibitor->mode = INHIBIT_IDLE_APPLICATION;
|
inhibitor->mode = INHIBIT_IDLE_APPLICATION;
|
||||||
inhibitor->wlr_inhibitor = wlr_inhibitor;
|
inhibitor->wlr_inhibitor = wlr_inhibitor;
|
||||||
wl_list_insert(&manager->inhibitors, &inhibitor->link);
|
wl_list_insert(&manager->inhibitors, &inhibitor->link);
|
||||||
|
@ -43,33 +41,34 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
||||||
inhibitor->destroy.notify = handle_destroy;
|
inhibitor->destroy.notify = handle_destroy;
|
||||||
wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy);
|
wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy);
|
||||||
|
|
||||||
sway_idle_inhibit_v1_check_active(manager);
|
sway_idle_inhibit_v1_check_active();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||||
enum sway_idle_inhibit_mode mode) {
|
enum sway_idle_inhibit_mode mode) {
|
||||||
|
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||||
|
|
||||||
struct sway_idle_inhibitor_v1 *inhibitor =
|
struct sway_idle_inhibitor_v1 *inhibitor =
|
||||||
calloc(1, sizeof(struct sway_idle_inhibitor_v1));
|
calloc(1, sizeof(struct sway_idle_inhibitor_v1));
|
||||||
if (!inhibitor) {
|
if (!inhibitor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inhibitor->manager = server.idle_inhibit_manager_v1;
|
|
||||||
inhibitor->mode = mode;
|
inhibitor->mode = mode;
|
||||||
inhibitor->view = view;
|
inhibitor->view = view;
|
||||||
wl_list_insert(&inhibitor->manager->inhibitors, &inhibitor->link);
|
wl_list_insert(&manager->inhibitors, &inhibitor->link);
|
||||||
|
|
||||||
inhibitor->destroy.notify = handle_destroy;
|
inhibitor->destroy.notify = handle_destroy;
|
||||||
wl_signal_add(&view->events.unmap, &inhibitor->destroy);
|
wl_signal_add(&view->events.unmap, &inhibitor->destroy);
|
||||||
|
|
||||||
sway_idle_inhibit_v1_check_active(inhibitor->manager);
|
sway_idle_inhibit_v1_check_active();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
||||||
struct sway_view *view) {
|
struct sway_view *view) {
|
||||||
|
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||||
wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors,
|
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||||
link) {
|
|
||||||
if (inhibitor->mode != INHIBIT_IDLE_APPLICATION &&
|
if (inhibitor->mode != INHIBIT_IDLE_APPLICATION &&
|
||||||
inhibitor->view == view) {
|
inhibitor->view == view) {
|
||||||
return inhibitor;
|
return inhibitor;
|
||||||
|
@ -80,9 +79,9 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
||||||
|
|
||||||
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_view(
|
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_view(
|
||||||
struct sway_view *view) {
|
struct sway_view *view) {
|
||||||
|
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||||
wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors,
|
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||||
link) {
|
|
||||||
if (inhibitor->mode == INHIBIT_IDLE_APPLICATION &&
|
if (inhibitor->mode == INHIBIT_IDLE_APPLICATION &&
|
||||||
view_from_wlr_surface(inhibitor->wlr_inhibitor->surface) == view) {
|
view_from_wlr_surface(inhibitor->wlr_inhibitor->surface) == view) {
|
||||||
return inhibitor;
|
return inhibitor;
|
||||||
|
@ -131,8 +130,8 @@ bool sway_idle_inhibit_v1_is_active(struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_idle_inhibit_v1_check_active(
|
void sway_idle_inhibit_v1_check_active(void) {
|
||||||
struct sway_idle_inhibit_manager_v1 *manager) {
|
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||||
bool inhibited = false;
|
bool inhibited = false;
|
||||||
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||||
|
@ -140,28 +139,21 @@ void sway_idle_inhibit_v1_check_active(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wlr_idle_set_enabled(manager->idle, NULL, !inhibited);
|
|
||||||
wlr_idle_notifier_v1_set_inhibited(server.idle_notifier_v1, inhibited);
|
wlr_idle_notifier_v1_set_inhibited(server.idle_notifier_v1, inhibited);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
|
bool sway_idle_inhibit_manager_v1_init(void) {
|
||||||
struct wl_display *wl_display, struct wlr_idle *idle) {
|
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||||
struct sway_idle_inhibit_manager_v1 *manager =
|
|
||||||
calloc(1, sizeof(struct sway_idle_inhibit_manager_v1));
|
manager->wlr_manager = wlr_idle_inhibit_v1_create(server.wl_display);
|
||||||
if (!manager) {
|
if (!manager->wlr_manager) {
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
manager->wlr_manager = wlr_idle_inhibit_v1_create(wl_display);
|
|
||||||
if (!manager->wlr_manager) {
|
|
||||||
free(manager);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
manager->idle = idle;
|
|
||||||
wl_signal_add(&manager->wlr_manager->events.new_inhibitor,
|
wl_signal_add(&manager->wlr_manager->events.new_inhibitor,
|
||||||
&manager->new_idle_inhibitor_v1);
|
&manager->new_idle_inhibitor_v1);
|
||||||
manager->new_idle_inhibitor_v1.notify = handle_idle_inhibitor_v1;
|
manager->new_idle_inhibitor_v1.notify = handle_idle_inhibitor_v1;
|
||||||
wl_list_init(&manager->inhibitors);
|
wl_list_init(&manager->inhibitors);
|
||||||
|
|
||||||
return manager;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a context with a new token for the internal launcher
|
// Creates a context with a new token for the internal launcher
|
||||||
struct launcher_ctx *launcher_ctx_create_internal() {
|
struct launcher_ctx *launcher_ctx_create_internal(void) {
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
struct sway_workspace *ws = seat_get_focused_workspace(seat);
|
struct sway_workspace *ws = seat_get_focused_workspace(seat);
|
||||||
if (!ws) {
|
if (!ws) {
|
||||||
|
|
|
@ -17,6 +17,39 @@
|
||||||
#include "sway/tree/arrange.h"
|
#include "sway/tree/arrange.h"
|
||||||
#include "sway/tree/workspace.h"
|
#include "sway/tree/workspace.h"
|
||||||
|
|
||||||
|
struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||||
|
struct wlr_surface *surface) {
|
||||||
|
struct wlr_layer_surface_v1 *layer;
|
||||||
|
do {
|
||||||
|
if (!surface) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Topmost layer surface
|
||||||
|
if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) {
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
// Layer subsurface
|
||||||
|
if (wlr_subsurface_try_from_wlr_surface(surface)) {
|
||||||
|
surface = wlr_surface_get_root_surface(surface);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer surface popup
|
||||||
|
struct wlr_xdg_surface *xdg_surface = NULL;
|
||||||
|
if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(surface)) &&
|
||||||
|
xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP && xdg_surface->popup != NULL) {
|
||||||
|
if (!xdg_surface->popup->parent) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
surface = wlr_surface_get_root_surface(xdg_surface->popup->parent);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return early if the surface is not a layer/xdg_popup/sub surface
|
||||||
|
return NULL;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
static void apply_exclusive(struct wlr_box *usable_area,
|
static void apply_exclusive(struct wlr_box *usable_area,
|
||||||
uint32_t anchor, int32_t exclusive,
|
uint32_t anchor, int32_t exclusive,
|
||||||
int32_t margin_top, int32_t margin_right,
|
int32_t margin_top, int32_t margin_right,
|
||||||
|
@ -218,8 +251,9 @@ void arrange_layers(struct sway_output *output) {
|
||||||
for (size_t i = 0; i < nlayers; ++i) {
|
for (size_t i = 0; i < nlayers; ++i) {
|
||||||
wl_list_for_each_reverse(layer,
|
wl_list_for_each_reverse(layer,
|
||||||
&output->layers[layers_above_shell[i]], link) {
|
&output->layers[layers_above_shell[i]], link) {
|
||||||
if (layer->layer_surface->current.keyboard_interactive &&
|
if (layer->layer_surface->current.keyboard_interactive
|
||||||
layer->layer_surface->mapped) {
|
== ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE &&
|
||||||
|
layer->layer_surface->surface->mapped) {
|
||||||
topmost = layer;
|
topmost = layer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -231,10 +265,12 @@ void arrange_layers(struct sway_output *output) {
|
||||||
|
|
||||||
struct sway_seat *seat;
|
struct sway_seat *seat;
|
||||||
wl_list_for_each(seat, &server.input->seats, link) {
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
seat->has_exclusive_layer = false;
|
||||||
if (topmost != NULL) {
|
if (topmost != NULL) {
|
||||||
seat_set_focus_layer(seat, topmost->layer_surface);
|
seat_set_focus_layer(seat, topmost->layer_surface);
|
||||||
} else if (seat->focused_layer &&
|
} else if (seat->focused_layer &&
|
||||||
!seat->focused_layer->current.keyboard_interactive) {
|
seat->focused_layer->current.keyboard_interactive
|
||||||
|
!= ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
|
||||||
seat_set_focus_layer(seat, NULL);
|
seat_set_focus_layer(seat, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +289,7 @@ static struct sway_layer_surface *find_mapped_layer_by_client(
|
||||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
|
||||||
struct wl_resource *resource = lsurface->layer_surface->resource;
|
struct wl_resource *resource = lsurface->layer_surface->resource;
|
||||||
if (wl_resource_get_client(resource) == client
|
if (wl_resource_get_client(resource) == client
|
||||||
&& lsurface->layer_surface->mapped) {
|
&& lsurface->layer_surface->surface->mapped) {
|
||||||
return lsurface;
|
return lsurface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,8 +329,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
bool layer_changed = false;
|
bool layer_changed = false;
|
||||||
if (layer_surface->current.committed != 0
|
if (layer_surface->current.committed != 0
|
||||||
|| layer->mapped != layer_surface->mapped) {
|
|| layer->mapped != layer_surface->surface->mapped) {
|
||||||
layer->mapped = layer_surface->mapped;
|
layer->mapped = layer_surface->surface->mapped;
|
||||||
layer_changed = layer->layer != layer_surface->current.layer;
|
layer_changed = layer->layer != layer_surface->current.layer;
|
||||||
if (layer_changed) {
|
if (layer_changed) {
|
||||||
wl_list_remove(&layer->link);
|
wl_list_remove(&layer->link);
|
||||||
|
@ -312,6 +348,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
||||||
bool extent_changed =
|
bool extent_changed =
|
||||||
memcmp(&old_extent, &layer->extent, sizeof(struct wlr_box)) != 0;
|
memcmp(&old_extent, &layer->extent, sizeof(struct wlr_box)) != 0;
|
||||||
if (extent_changed || layer_changed) {
|
if (extent_changed || layer_changed) {
|
||||||
|
old_extent.x += output->lx;
|
||||||
|
old_extent.y += output->ly;
|
||||||
output_damage_box(output, &old_extent);
|
output_damage_box(output, &old_extent);
|
||||||
output_damage_surface(output, layer->geo.x, layer->geo.y,
|
output_damage_surface(output, layer->geo.x, layer->geo.y,
|
||||||
layer_surface->surface, true);
|
layer_surface->surface, true);
|
||||||
|
@ -347,7 +385,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, sway_layer, destroy);
|
wl_container_of(listener, sway_layer, destroy);
|
||||||
sway_log(SWAY_DEBUG, "Layer surface destroyed (%s)",
|
sway_log(SWAY_DEBUG, "Layer surface destroyed (%s)",
|
||||||
sway_layer->layer_surface->namespace);
|
sway_layer->layer_surface->namespace);
|
||||||
if (sway_layer->layer_surface->mapped) {
|
if (sway_layer->layer_surface->surface->mapped) {
|
||||||
unmap(sway_layer);
|
unmap(sway_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,9 +490,9 @@ static struct sway_layer_subsurface *create_subsurface(
|
||||||
wl_list_insert(&layer_surface->subsurfaces, &subsurface->link);
|
wl_list_insert(&layer_surface->subsurfaces, &subsurface->link);
|
||||||
|
|
||||||
subsurface->map.notify = subsurface_handle_map;
|
subsurface->map.notify = subsurface_handle_map;
|
||||||
wl_signal_add(&wlr_subsurface->events.map, &subsurface->map);
|
wl_signal_add(&wlr_subsurface->surface->events.map, &subsurface->map);
|
||||||
subsurface->unmap.notify = subsurface_handle_unmap;
|
subsurface->unmap.notify = subsurface_handle_unmap;
|
||||||
wl_signal_add(&wlr_subsurface->events.unmap, &subsurface->unmap);
|
wl_signal_add(&wlr_subsurface->surface->events.unmap, &subsurface->unmap);
|
||||||
subsurface->destroy.notify = subsurface_handle_destroy;
|
subsurface->destroy.notify = subsurface_handle_destroy;
|
||||||
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
|
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
|
||||||
subsurface->commit.notify = subsurface_handle_commit;
|
subsurface->commit.notify = subsurface_handle_commit;
|
||||||
|
@ -504,36 +542,6 @@ static void popup_damage(struct sway_layer_popup *layer_popup, bool whole) {
|
||||||
output_damage_surface(output, ox, oy, surface, whole);
|
output_damage_surface(output, ox, oy, surface, whole);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, map);
|
|
||||||
struct sway_layer_surface *layer = popup_get_layer(popup);
|
|
||||||
struct wlr_output *wlr_output = layer->layer_surface->output;
|
|
||||||
sway_assert(wlr_output, "wlr_layer_surface_v1 has null output");
|
|
||||||
surface_enter_output(popup->wlr_popup->base->surface, wlr_output->data);
|
|
||||||
popup_damage(popup, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, unmap);
|
|
||||||
popup_damage(popup, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void popup_handle_commit(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_layer_popup *popup = wl_container_of(listener, popup, commit);
|
|
||||||
popup_damage(popup, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_layer_popup *popup =
|
|
||||||
wl_container_of(listener, popup, destroy);
|
|
||||||
|
|
||||||
wl_list_remove(&popup->map.link);
|
|
||||||
wl_list_remove(&popup->unmap.link);
|
|
||||||
wl_list_remove(&popup->destroy.link);
|
|
||||||
wl_list_remove(&popup->commit.link);
|
|
||||||
free(popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void popup_unconstrain(struct sway_layer_popup *popup) {
|
static void popup_unconstrain(struct sway_layer_popup *popup) {
|
||||||
struct sway_layer_surface *layer = popup_get_layer(popup);
|
struct sway_layer_surface *layer = popup_get_layer(popup);
|
||||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
||||||
|
@ -554,6 +562,39 @@ static void popup_unconstrain(struct sway_layer_popup *popup) {
|
||||||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_layer_popup *popup = wl_container_of(listener, popup, map);
|
||||||
|
struct sway_layer_surface *layer = popup_get_layer(popup);
|
||||||
|
struct wlr_output *wlr_output = layer->layer_surface->output;
|
||||||
|
sway_assert(wlr_output, "wlr_layer_surface_v1 has null output");
|
||||||
|
surface_enter_output(popup->wlr_popup->base->surface, wlr_output->data);
|
||||||
|
popup_damage(popup, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_layer_popup *popup = wl_container_of(listener, popup, unmap);
|
||||||
|
popup_damage(popup, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popup_handle_commit(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_layer_popup *popup = wl_container_of(listener, popup, commit);
|
||||||
|
if (popup->wlr_popup->base->initial_commit) {
|
||||||
|
popup_unconstrain(popup);
|
||||||
|
}
|
||||||
|
popup_damage(popup, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_layer_popup *popup =
|
||||||
|
wl_container_of(listener, popup, destroy);
|
||||||
|
|
||||||
|
wl_list_remove(&popup->map.link);
|
||||||
|
wl_list_remove(&popup->unmap.link);
|
||||||
|
wl_list_remove(&popup->destroy.link);
|
||||||
|
wl_list_remove(&popup->commit.link);
|
||||||
|
free(popup);
|
||||||
|
}
|
||||||
|
|
||||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
|
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
||||||
|
@ -569,9 +610,9 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
||||||
popup->parent_layer = parent;
|
popup->parent_layer = parent;
|
||||||
|
|
||||||
popup->map.notify = popup_handle_map;
|
popup->map.notify = popup_handle_map;
|
||||||
wl_signal_add(&wlr_popup->base->events.map, &popup->map);
|
wl_signal_add(&wlr_popup->base->surface->events.map, &popup->map);
|
||||||
popup->unmap.notify = popup_handle_unmap;
|
popup->unmap.notify = popup_handle_unmap;
|
||||||
wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap);
|
wl_signal_add(&wlr_popup->base->surface->events.unmap, &popup->unmap);
|
||||||
popup->destroy.notify = popup_handle_destroy;
|
popup->destroy.notify = popup_handle_destroy;
|
||||||
wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
|
wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
|
||||||
popup->commit.notify = popup_handle_commit;
|
popup->commit.notify = popup_handle_commit;
|
||||||
|
@ -579,8 +620,6 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
||||||
popup->new_popup.notify = popup_handle_new_popup;
|
popup->new_popup.notify = popup_handle_new_popup;
|
||||||
wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
|
wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
|
||||||
|
|
||||||
popup_unconstrain(popup);
|
|
||||||
|
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,9 +698,9 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
|
||||||
sway_layer->destroy.notify = handle_destroy;
|
sway_layer->destroy.notify = handle_destroy;
|
||||||
wl_signal_add(&layer_surface->events.destroy, &sway_layer->destroy);
|
wl_signal_add(&layer_surface->events.destroy, &sway_layer->destroy);
|
||||||
sway_layer->map.notify = handle_map;
|
sway_layer->map.notify = handle_map;
|
||||||
wl_signal_add(&layer_surface->events.map, &sway_layer->map);
|
wl_signal_add(&layer_surface->surface->events.map, &sway_layer->map);
|
||||||
sway_layer->unmap.notify = handle_unmap;
|
sway_layer->unmap.notify = handle_unmap;
|
||||||
wl_signal_add(&layer_surface->events.unmap, &sway_layer->unmap);
|
wl_signal_add(&layer_surface->surface->events.unmap, &sway_layer->unmap);
|
||||||
sway_layer->new_popup.notify = handle_new_popup;
|
sway_layer->new_popup.notify = handle_new_popup;
|
||||||
wl_signal_add(&layer_surface->events.new_popup, &sway_layer->new_popup);
|
wl_signal_add(&layer_surface->events.new_popup, &sway_layer->new_popup);
|
||||||
sway_layer->new_subsurface.notify = handle_new_subsurface;
|
sway_layer->new_subsurface.notify = handle_new_subsurface;
|
||||||
|
|
|
@ -6,14 +6,17 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/config.h>
|
#include <wlr/config.h>
|
||||||
#include <wlr/backend/headless.h>
|
#include <wlr/backend/headless.h>
|
||||||
|
#include <wlr/render/swapchain.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_buffer.h>
|
#include <wlr/types/wlr_buffer.h>
|
||||||
|
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||||
#include <wlr/types/wlr_matrix.h>
|
#include <wlr/types/wlr_matrix.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
#include <wlr/types/wlr_presentation_time.h>
|
#include <wlr/types/wlr_presentation_time.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/util/region.h>
|
#include <wlr/util/region.h>
|
||||||
|
#include <wlr/util/transform.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
@ -36,13 +39,22 @@
|
||||||
#include <wlr/types/wlr_drm_lease_v1.h>
|
#include <wlr/types/wlr_drm_lease_v1.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool output_match_name_or_id(struct sway_output *output,
|
||||||
|
const char *name_or_id) {
|
||||||
|
if (strcmp(name_or_id, "*") == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char identifier[128];
|
||||||
|
output_get_identifier(identifier, sizeof(identifier), output);
|
||||||
|
return strcasecmp(identifier, name_or_id) == 0
|
||||||
|
|| strcasecmp(output->wlr_output->name, name_or_id) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
for (int i = 0; i < root->outputs->length; ++i) {
|
for (int i = 0; i < root->outputs->length; ++i) {
|
||||||
struct sway_output *output = root->outputs->items[i];
|
struct sway_output *output = root->outputs->items[i];
|
||||||
char identifier[128];
|
if (output_match_name_or_id(output, name_or_id)) {
|
||||||
output_get_identifier(identifier, sizeof(identifier), output);
|
|
||||||
if (strcasecmp(identifier, name_or_id) == 0
|
|
||||||
|| strcasecmp(output->wlr_output->name, name_or_id) == 0) {
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,10 +64,7 @@ struct sway_output *output_by_name_or_id(const char *name_or_id) {
|
||||||
struct sway_output *all_output_by_name_or_id(const char *name_or_id) {
|
struct sway_output *all_output_by_name_or_id(const char *name_or_id) {
|
||||||
struct sway_output *output;
|
struct sway_output *output;
|
||||||
wl_list_for_each(output, &root->all_outputs, link) {
|
wl_list_for_each(output, &root->all_outputs, link) {
|
||||||
char identifier[128];
|
if (output_match_name_or_id(output, name_or_id)) {
|
||||||
output_get_identifier(identifier, sizeof(identifier), output);
|
|
||||||
if (strcasecmp(identifier, name_or_id) == 0
|
|
||||||
|| strcasecmp(output->wlr_output->name, name_or_id) == 0) {
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +267,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output,
|
||||||
double ox = drag_icon->x - output->lx;
|
double ox = drag_icon->x - output->lx;
|
||||||
double oy = drag_icon->y - output->ly;
|
double oy = drag_icon->y - output->ly;
|
||||||
|
|
||||||
if (drag_icon->wlr_drag_icon->mapped) {
|
if (drag_icon->wlr_drag_icon->surface->mapped) {
|
||||||
output_surface_for_each_surface(output,
|
output_surface_for_each_surface(output,
|
||||||
drag_icon->wlr_drag_icon->surface, ox, oy,
|
drag_icon->wlr_drag_icon->surface, ox, oy,
|
||||||
iterator, user_data);
|
iterator, user_data);
|
||||||
|
@ -288,7 +297,7 @@ static void output_for_each_surface(struct sway_output *output,
|
||||||
if (lock_surface->output != output->wlr_output) {
|
if (lock_surface->output != output->wlr_output) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!lock_surface->mapped) {
|
if (!lock_surface->surface->mapped) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +459,7 @@ static void count_surface_iterator(struct sway_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool scan_out_fullscreen_view(struct sway_output *output,
|
static bool scan_out_fullscreen_view(struct sway_output *output,
|
||||||
struct sway_view *view) {
|
struct wlr_output_state *pending, struct sway_view *view) {
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
struct sway_workspace *workspace = output->current.active_workspace;
|
struct sway_workspace *workspace = output->current.active_workspace;
|
||||||
if (!sway_assert(workspace, "Expected an active workspace")) {
|
if (!sway_assert(workspace, "Expected an active workspace")) {
|
||||||
|
@ -512,15 +521,20 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_attach_buffer(wlr_output, &surface->buffer->base);
|
if (!wlr_output_is_direct_scanout_allowed(wlr_output)) {
|
||||||
if (!wlr_output_test(wlr_output)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_presentation_surface_sampled_on_output(server.presentation, surface,
|
wlr_output_state_set_buffer(pending, &surface->buffer->base);
|
||||||
|
|
||||||
|
if (!wlr_output_test_state(wlr_output, pending)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_presentation_surface_scanned_out_on_output(server.presentation, surface,
|
||||||
wlr_output);
|
wlr_output);
|
||||||
|
|
||||||
return wlr_output_commit(wlr_output);
|
return wlr_output_commit_state(wlr_output, pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_frame_damage(struct sway_output *output,
|
static void get_frame_damage(struct sway_output *output,
|
||||||
|
@ -552,6 +566,12 @@ static int output_repaint_timer_handler(void *data) {
|
||||||
|
|
||||||
wlr_output->frame_pending = false;
|
wlr_output->frame_pending = false;
|
||||||
|
|
||||||
|
if (!wlr_output->needs_frame &&
|
||||||
|
!output->gamma_lut_changed &&
|
||||||
|
!pixman_region32_not_empty(&output->damage_ring.current)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct sway_workspace *workspace = output->current.active_workspace;
|
struct sway_workspace *workspace = output->current.active_workspace;
|
||||||
if (workspace == NULL) {
|
if (workspace == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -562,11 +582,31 @@ static int output_repaint_timer_handler(void *data) {
|
||||||
fullscreen_con = workspace->current.fullscreen;
|
fullscreen_con = workspace->current.fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_output_state pending = {0};
|
||||||
|
|
||||||
|
if (output->gamma_lut_changed) {
|
||||||
|
output->gamma_lut_changed = false;
|
||||||
|
struct wlr_gamma_control_v1 *gamma_control =
|
||||||
|
wlr_gamma_control_manager_v1_get_control(
|
||||||
|
server.gamma_control_manager_v1, wlr_output);
|
||||||
|
if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!wlr_output_test_state(wlr_output, &pending)) {
|
||||||
|
wlr_output_state_finish(&pending);
|
||||||
|
pending = (struct wlr_output_state){0};
|
||||||
|
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pending.committed |= WLR_OUTPUT_STATE_DAMAGE;
|
||||||
|
get_frame_damage(output, &pending.damage);
|
||||||
|
|
||||||
if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
|
if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
|
||||||
// Try to scan-out the fullscreen view
|
// Try to scan-out the fullscreen view
|
||||||
static bool last_scanned_out = false;
|
static bool last_scanned_out = false;
|
||||||
bool scanned_out =
|
bool scanned_out =
|
||||||
scan_out_fullscreen_view(output, fullscreen_con->view);
|
scan_out_fullscreen_view(output, &pending, fullscreen_con->view);
|
||||||
|
|
||||||
if (scanned_out && !last_scanned_out) {
|
if (scanned_out && !last_scanned_out) {
|
||||||
sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s",
|
sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s",
|
||||||
|
@ -580,43 +620,68 @@ static int output_repaint_timer_handler(void *data) {
|
||||||
last_scanned_out = scanned_out;
|
last_scanned_out = scanned_out;
|
||||||
|
|
||||||
if (scanned_out) {
|
if (scanned_out) {
|
||||||
return 0;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output->wlr_output->needs_frame &&
|
if (!wlr_output_configure_primary_swapchain(wlr_output, &pending, &wlr_output->swapchain)) {
|
||||||
!pixman_region32_not_empty(&output->damage_ring.current)) {
|
goto out;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int buffer_age;
|
int buffer_age;
|
||||||
if (!wlr_output_attach_render(output->wlr_output, &buffer_age)) {
|
struct wlr_buffer *buffer = wlr_swapchain_acquire(wlr_output->swapchain, &buffer_age);
|
||||||
return 0;
|
if (buffer == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_render_pass *render_pass = wlr_renderer_begin_buffer_pass(
|
||||||
|
wlr_output->renderer, buffer, NULL);
|
||||||
|
if (render_pass == NULL) {
|
||||||
|
wlr_buffer_unlock(buffer);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);
|
wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);
|
||||||
|
|
||||||
|
if (debug.damage == DAMAGE_RERENDER) {
|
||||||
|
int width, height;
|
||||||
|
wlr_output_transformed_resolution(wlr_output, &width, &height);
|
||||||
|
pixman_region32_union_rect(&damage, &damage, 0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct render_context ctx = {
|
||||||
|
.output_damage = &damage,
|
||||||
|
.renderer = wlr_output->renderer,
|
||||||
|
.output = output,
|
||||||
|
.pass = render_pass,
|
||||||
|
};
|
||||||
|
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
output_render(output, &damage);
|
output_render(&ctx);
|
||||||
|
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
|
|
||||||
pixman_region32_t frame_damage;
|
if (!wlr_render_pass_submit(render_pass)) {
|
||||||
get_frame_damage(output, &frame_damage);
|
wlr_buffer_unlock(buffer);
|
||||||
wlr_output_set_damage(wlr_output, &frame_damage);
|
goto out;
|
||||||
pixman_region32_fini(&frame_damage);
|
}
|
||||||
|
|
||||||
if (!wlr_output_commit(wlr_output)) {
|
wlr_output_state_set_buffer(&pending, buffer);
|
||||||
return 0;
|
wlr_buffer_unlock(buffer);
|
||||||
|
|
||||||
|
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_damage_ring_rotate(&output->damage_ring);
|
wlr_damage_ring_rotate(&output->damage_ring);
|
||||||
output->last_frame = now;
|
output->last_frame = now;
|
||||||
|
|
||||||
|
out:
|
||||||
|
wlr_output_state_finish(&pending);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,9 +707,7 @@ static void handle_frame(struct wl_listener *listener, void *user_data) {
|
||||||
|
|
||||||
if (output->max_render_time != 0) {
|
if (output->max_render_time != 0) {
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clockid_t presentation_clock
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
= wlr_backend_get_presentation_clock(server.backend);
|
|
||||||
clock_gettime(presentation_clock, &now);
|
|
||||||
|
|
||||||
const long NSEC_IN_SECONDS = 1000000000;
|
const long NSEC_IN_SECONDS = 1000000000;
|
||||||
struct timespec predicted_refresh = output->last_presentation;
|
struct timespec predicted_refresh = output->last_presentation;
|
||||||
|
@ -819,12 +882,9 @@ static void update_output_manager_config(struct sway_server *server) {
|
||||||
wlr_output_layout_get_box(root->output_layout,
|
wlr_output_layout_get_box(root->output_layout,
|
||||||
output->wlr_output, &output_box);
|
output->wlr_output, &output_box);
|
||||||
// We mark the output enabled when it's switched off but not disabled
|
// We mark the output enabled when it's switched off but not disabled
|
||||||
config_head->state.enabled = output->current_mode != NULL && output->enabled;
|
config_head->state.enabled = !wlr_box_empty(&output_box);
|
||||||
config_head->state.mode = output->current_mode;
|
config_head->state.x = output_box.x;
|
||||||
if (!wlr_box_empty(&output_box)) {
|
config_head->state.y = output_box.y;
|
||||||
config_head->state.x = output_box.x;
|
|
||||||
config_head->state.y = output_box.y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_manager_v1_set_configuration(server->output_manager_v1, config);
|
wlr_output_manager_v1_set_configuration(server->output_manager_v1, config);
|
||||||
|
@ -862,36 +922,6 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
update_output_manager_config(server);
|
update_output_manager_config(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_mode(struct sway_output *output) {
|
|
||||||
if (!output->enabled && !output->enabling) {
|
|
||||||
struct output_config *oc = find_output_config(output);
|
|
||||||
if (output->wlr_output->current_mode != NULL &&
|
|
||||||
(!oc || oc->enabled)) {
|
|
||||||
// We want to enable this output, but it didn't work last time,
|
|
||||||
// possibly because we hadn't enough CRTCs. Try again now that the
|
|
||||||
// output has a mode.
|
|
||||||
sway_log(SWAY_DEBUG, "Output %s has gained a CRTC, "
|
|
||||||
"trying to enable it", output->wlr_output->name);
|
|
||||||
apply_output_config(oc, output);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!output->enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
arrange_layers(output);
|
|
||||||
arrange_output(output);
|
|
||||||
transaction_commit_dirty();
|
|
||||||
|
|
||||||
int width, height;
|
|
||||||
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
|
||||||
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
|
||||||
wlr_output_schedule_frame(output->wlr_output);
|
|
||||||
|
|
||||||
update_output_manager_config(output->server);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_textures(struct sway_container *con, void *data) {
|
static void update_textures(struct sway_container *con, void *data) {
|
||||||
container_update_title_textures(con);
|
container_update_title_textures(con);
|
||||||
container_update_marks_textures(con);
|
container_update_marks_textures(con);
|
||||||
|
@ -907,20 +937,19 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = wl_container_of(listener, output, commit);
|
struct sway_output *output = wl_container_of(listener, output, commit);
|
||||||
struct wlr_output_event_commit *event = data;
|
struct wlr_output_event_commit *event = data;
|
||||||
|
|
||||||
if (event->committed & WLR_OUTPUT_STATE_MODE) {
|
|
||||||
handle_mode(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output->enabled) {
|
if (!output->enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->committed & WLR_OUTPUT_STATE_SCALE) {
|
if (event->state->committed & WLR_OUTPUT_STATE_SCALE) {
|
||||||
output_for_each_container(output, update_textures, NULL);
|
output_for_each_container(output, update_textures, NULL);
|
||||||
output_for_each_surface(output, update_output_scale_iterator, NULL);
|
output_for_each_surface(output, update_output_scale_iterator, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->committed & (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE)) {
|
if (event->state->committed & (
|
||||||
|
WLR_OUTPUT_STATE_MODE |
|
||||||
|
WLR_OUTPUT_STATE_TRANSFORM |
|
||||||
|
WLR_OUTPUT_STATE_SCALE)) {
|
||||||
arrange_layers(output);
|
arrange_layers(output);
|
||||||
arrange_output(output);
|
arrange_output(output);
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
|
@ -928,12 +957,19 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
update_output_manager_config(output->server);
|
update_output_manager_config(output->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->committed & (WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_TRANSFORM)) {
|
if (event->state->committed & (
|
||||||
|
WLR_OUTPUT_STATE_MODE |
|
||||||
|
WLR_OUTPUT_STATE_TRANSFORM)) {
|
||||||
int width, height;
|
int width, height;
|
||||||
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
||||||
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
||||||
wlr_output_schedule_frame(output->wlr_output);
|
wlr_output_schedule_frame(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next time the output is enabled, try to re-apply the gamma LUT
|
||||||
|
if ((event->state->committed & WLR_OUTPUT_STATE_ENABLED) && !output->wlr_output->enabled) {
|
||||||
|
output->gamma_lut_changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_present(struct wl_listener *listener, void *data) {
|
static void handle_present(struct wl_listener *listener, void *data) {
|
||||||
|
@ -999,9 +1035,6 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
output->server = server;
|
output->server = server;
|
||||||
wlr_damage_ring_init(&output->damage_ring);
|
wlr_damage_ring_init(&output->damage_ring);
|
||||||
int width, height;
|
|
||||||
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
|
||||||
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
|
||||||
|
|
||||||
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
||||||
output->destroy.notify = handle_destroy;
|
output->destroy.notify = handle_destroy;
|
||||||
|
@ -1027,6 +1060,9 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
||||||
|
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
||||||
update_output_manager_config(server);
|
update_output_manager_config(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1037,6 +1073,21 @@ void handle_output_layout_change(struct wl_listener *listener,
|
||||||
update_output_manager_config(server);
|
update_output_manager_config(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_server *server =
|
||||||
|
wl_container_of(listener, server, gamma_control_set_gamma);
|
||||||
|
const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
|
||||||
|
|
||||||
|
struct sway_output *output = event->output->data;
|
||||||
|
|
||||||
|
if(!output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->gamma_lut_changed = true;
|
||||||
|
wlr_output_schedule_frame(output->wlr_output);
|
||||||
|
}
|
||||||
|
|
||||||
static void output_manager_apply(struct sway_server *server,
|
static void output_manager_apply(struct sway_server *server,
|
||||||
struct wlr_output_configuration_v1 *config, bool test_only) {
|
struct wlr_output_configuration_v1 *config, bool test_only) {
|
||||||
// TODO: perform atomic tests on the whole backend atomically
|
// TODO: perform atomic tests on the whole backend atomically
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -56,6 +56,7 @@ void surface_update_outputs(struct wlr_surface *surface) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wlr_fractional_scale_v1_notify_scale(surface, scale);
|
wlr_fractional_scale_v1_notify_scale(surface, scale);
|
||||||
|
wlr_surface_set_preferred_buffer_scale(surface, ceil(scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
void surface_enter_output(struct wlr_surface *surface,
|
void surface_enter_output(struct wlr_surface *surface,
|
||||||
|
|
|
@ -344,7 +344,7 @@ static void transaction_progress(void) {
|
||||||
server.queued_transaction = NULL;
|
server.queued_transaction = NULL;
|
||||||
|
|
||||||
if (!server.pending_transaction) {
|
if (!server.pending_transaction) {
|
||||||
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
sway_idle_inhibit_v1_check_active();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ static void popup_destroy(struct sway_view_child *child) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
|
struct sway_xdg_popup *popup = (struct sway_xdg_popup *)child;
|
||||||
|
wl_list_remove(&popup->surface_commit.link);
|
||||||
wl_list_remove(&popup->new_popup.link);
|
wl_list_remove(&popup->new_popup.link);
|
||||||
wl_list_remove(&popup->destroy.link);
|
wl_list_remove(&popup->destroy.link);
|
||||||
free(popup);
|
free(popup);
|
||||||
|
@ -51,23 +52,17 @@ static const struct sway_view_child_impl popup_impl = {
|
||||||
static struct sway_xdg_popup *popup_create(
|
static struct sway_xdg_popup *popup_create(
|
||||||
struct wlr_xdg_popup *wlr_popup, struct sway_view *view);
|
struct wlr_xdg_popup *wlr_popup, struct sway_view *view);
|
||||||
|
|
||||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_xdg_popup *popup =
|
|
||||||
wl_container_of(listener, popup, new_popup);
|
|
||||||
struct wlr_xdg_popup *wlr_popup = data;
|
|
||||||
popup_create(wlr_popup, popup->child.view);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
|
|
||||||
view_child_destroy(&popup->child);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void popup_unconstrain(struct sway_xdg_popup *popup) {
|
static void popup_unconstrain(struct sway_xdg_popup *popup) {
|
||||||
struct sway_view *view = popup->child.view;
|
struct sway_view *view = popup->child.view;
|
||||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
|
struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
|
||||||
|
|
||||||
struct sway_output *output = view->container->pending.workspace->output;
|
struct sway_workspace *workspace = view->container->pending.workspace;
|
||||||
|
if (!workspace) {
|
||||||
|
// is null if in the scratchpad
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_output *output = workspace->output;
|
||||||
|
|
||||||
// the output box expressed in the coordinate system of the toplevel parent
|
// the output box expressed in the coordinate system of the toplevel parent
|
||||||
// of the popup
|
// of the popup
|
||||||
|
@ -81,6 +76,25 @@ static void popup_unconstrain(struct sway_xdg_popup *popup) {
|
||||||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void popup_handle_surface_commit(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xdg_popup *popup = wl_container_of(listener, popup, surface_commit);
|
||||||
|
if (popup->wlr_xdg_popup->base->initial_commit) {
|
||||||
|
popup_unconstrain(popup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xdg_popup *popup =
|
||||||
|
wl_container_of(listener, popup, new_popup);
|
||||||
|
struct wlr_xdg_popup *wlr_popup = data;
|
||||||
|
popup_create(wlr_popup, popup->child.view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xdg_popup *popup = wl_container_of(listener, popup, destroy);
|
||||||
|
view_child_destroy(&popup->child);
|
||||||
|
}
|
||||||
|
|
||||||
static struct sway_xdg_popup *popup_create(
|
static struct sway_xdg_popup *popup_create(
|
||||||
struct wlr_xdg_popup *wlr_popup, struct sway_view *view) {
|
struct wlr_xdg_popup *wlr_popup, struct sway_view *view) {
|
||||||
struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
|
struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
|
||||||
|
@ -91,22 +105,21 @@ static struct sway_xdg_popup *popup_create(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface);
|
view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface);
|
||||||
popup->wlr_xdg_popup = xdg_surface->popup;
|
popup->wlr_xdg_popup = wlr_popup;
|
||||||
|
|
||||||
|
wl_signal_add(&xdg_surface->surface->events.commit, &popup->surface_commit);
|
||||||
|
popup->surface_commit.notify = popup_handle_surface_commit;
|
||||||
wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup);
|
wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup);
|
||||||
popup->new_popup.notify = popup_handle_new_popup;
|
popup->new_popup.notify = popup_handle_new_popup;
|
||||||
wl_signal_add(&xdg_surface->events.destroy, &popup->destroy);
|
wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
|
||||||
popup->destroy.notify = popup_handle_destroy;
|
popup->destroy.notify = popup_handle_destroy;
|
||||||
|
|
||||||
wl_signal_add(&xdg_surface->events.map, &popup->child.surface_map);
|
wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map);
|
||||||
wl_signal_add(&xdg_surface->events.unmap, &popup->child.surface_unmap);
|
wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap);
|
||||||
|
|
||||||
popup_unconstrain(popup);
|
|
||||||
|
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct sway_xdg_shell_view *xdg_shell_view_from_view(
|
static struct sway_xdg_shell_view *xdg_shell_view_from_view(
|
||||||
struct sway_view *view) {
|
struct sway_view *view) {
|
||||||
if (!sway_assert(view->type == SWAY_VIEW_XDG_SHELL,
|
if (!sway_assert(view->type == SWAY_VIEW_XDG_SHELL,
|
||||||
|
@ -163,12 +176,19 @@ static void set_tiled(struct sway_view *view, bool tiled) {
|
||||||
if (xdg_shell_view_from_view(view) == NULL) {
|
if (xdg_shell_view_from_view(view) == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enum wlr_edges edges = WLR_EDGE_NONE;
|
if (wl_resource_get_version(view->wlr_xdg_toplevel->resource) >=
|
||||||
if (tiled) {
|
XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) {
|
||||||
edges = WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP |
|
enum wlr_edges edges = WLR_EDGE_NONE;
|
||||||
WLR_EDGE_BOTTOM;
|
if (tiled) {
|
||||||
|
edges = WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP |
|
||||||
|
WLR_EDGE_BOTTOM;
|
||||||
|
}
|
||||||
|
wlr_xdg_toplevel_set_tiled(view->wlr_xdg_toplevel, edges);
|
||||||
|
} else {
|
||||||
|
// The version is too low for the tiled state; configure as maximized instead
|
||||||
|
// to stop the client from drawing decorations outside of the toplevel geometry.
|
||||||
|
wlr_xdg_toplevel_set_maximized(view->wlr_xdg_toplevel, tiled);
|
||||||
}
|
}
|
||||||
wlr_xdg_toplevel_set_tiled(view->wlr_xdg_toplevel, edges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_fullscreen(struct sway_view *view, bool fullscreen) {
|
static void set_fullscreen(struct sway_view *view, bool fullscreen) {
|
||||||
|
@ -273,6 +293,19 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
struct sway_view *view = &xdg_shell_view->view;
|
struct sway_view *view = &xdg_shell_view->view;
|
||||||
struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_toplevel->base;
|
struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_toplevel->base;
|
||||||
|
|
||||||
|
if (xdg_surface->initial_commit) {
|
||||||
|
if (view->xdg_decoration != NULL) {
|
||||||
|
set_xdg_decoration_mode(view->xdg_decoration);
|
||||||
|
}
|
||||||
|
// XXX: https://github.com/swaywm/sway/issues/2176
|
||||||
|
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xdg_surface->surface->mapped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_box new_geo;
|
struct wlr_box new_geo;
|
||||||
wlr_xdg_surface_get_geometry(xdg_surface, &new_geo);
|
wlr_xdg_surface_get_geometry(xdg_surface, &new_geo);
|
||||||
bool new_size = new_geo.width != view->geometry.width ||
|
bool new_size = new_geo.width != view->geometry.width ||
|
||||||
|
@ -288,6 +321,11 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
||||||
if (container_is_floating(view->container)) {
|
if (container_is_floating(view->container)) {
|
||||||
view_update_size(view);
|
view_update_size(view);
|
||||||
|
// Only set the toplevel size the current container actually has a size.
|
||||||
|
if (view->container->current.width) {
|
||||||
|
wlr_xdg_toplevel_set_size(view->wlr_xdg_toplevel, view->geometry.width,
|
||||||
|
view->geometry.height);
|
||||||
|
}
|
||||||
transaction_commit_dirty_client();
|
transaction_commit_dirty_client();
|
||||||
} else {
|
} else {
|
||||||
view_center_surface(view);
|
view_center_surface(view);
|
||||||
|
@ -338,7 +376,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
struct wlr_xdg_toplevel *toplevel = xdg_shell_view->view.wlr_xdg_toplevel;
|
struct wlr_xdg_toplevel *toplevel = xdg_shell_view->view.wlr_xdg_toplevel;
|
||||||
struct sway_view *view = &xdg_shell_view->view;
|
struct sway_view *view = &xdg_shell_view->view;
|
||||||
|
|
||||||
if (!toplevel->base->mapped) {
|
if (!toplevel->base->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +441,6 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
view_unmap(view);
|
view_unmap(view);
|
||||||
|
|
||||||
wl_list_remove(&xdg_shell_view->commit.link);
|
|
||||||
wl_list_remove(&xdg_shell_view->new_popup.link);
|
wl_list_remove(&xdg_shell_view->new_popup.link);
|
||||||
wl_list_remove(&xdg_shell_view->request_maximize.link);
|
wl_list_remove(&xdg_shell_view->request_maximize.link);
|
||||||
wl_list_remove(&xdg_shell_view->request_fullscreen.link);
|
wl_list_remove(&xdg_shell_view->request_fullscreen.link);
|
||||||
|
@ -446,10 +483,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
|
|
||||||
xdg_shell_view->commit.notify = handle_commit;
|
|
||||||
wl_signal_add(&toplevel->base->surface->events.commit,
|
|
||||||
&xdg_shell_view->commit);
|
|
||||||
|
|
||||||
xdg_shell_view->new_popup.notify = handle_new_popup;
|
xdg_shell_view->new_popup.notify = handle_new_popup;
|
||||||
wl_signal_add(&toplevel->base->events.new_popup,
|
wl_signal_add(&toplevel->base->events.new_popup,
|
||||||
&xdg_shell_view->new_popup);
|
&xdg_shell_view->new_popup);
|
||||||
|
@ -489,6 +522,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&xdg_shell_view->destroy.link);
|
wl_list_remove(&xdg_shell_view->destroy.link);
|
||||||
wl_list_remove(&xdg_shell_view->map.link);
|
wl_list_remove(&xdg_shell_view->map.link);
|
||||||
wl_list_remove(&xdg_shell_view->unmap.link);
|
wl_list_remove(&xdg_shell_view->unmap.link);
|
||||||
|
wl_list_remove(&xdg_shell_view->commit.link);
|
||||||
view->wlr_xdg_toplevel = NULL;
|
view->wlr_xdg_toplevel = NULL;
|
||||||
if (view->xdg_decoration) {
|
if (view->xdg_decoration) {
|
||||||
view->xdg_decoration->view = NULL;
|
view->xdg_decoration->view = NULL;
|
||||||
|
@ -501,17 +535,12 @@ struct sway_view *view_from_wlr_xdg_surface(
|
||||||
return xdg_surface->data;
|
return xdg_surface->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xdg_surface *xdg_surface = data;
|
struct wlr_xdg_toplevel *xdg_toplevel = data;
|
||||||
|
|
||||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
|
||||||
sway_log(SWAY_DEBUG, "New xdg_shell popup");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'",
|
sway_log(SWAY_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'",
|
||||||
xdg_surface->toplevel->title, xdg_surface->toplevel->app_id);
|
xdg_toplevel->title, xdg_toplevel->app_id);
|
||||||
wlr_xdg_surface_ping(xdg_surface);
|
wlr_xdg_surface_ping(xdg_toplevel->base);
|
||||||
|
|
||||||
struct sway_xdg_shell_view *xdg_shell_view =
|
struct sway_xdg_shell_view *xdg_shell_view =
|
||||||
calloc(1, sizeof(struct sway_xdg_shell_view));
|
calloc(1, sizeof(struct sway_xdg_shell_view));
|
||||||
|
@ -520,16 +549,20 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl);
|
view_init(&xdg_shell_view->view, SWAY_VIEW_XDG_SHELL, &view_impl);
|
||||||
xdg_shell_view->view.wlr_xdg_toplevel = xdg_surface->toplevel;
|
xdg_shell_view->view.wlr_xdg_toplevel = xdg_toplevel;
|
||||||
|
|
||||||
xdg_shell_view->map.notify = handle_map;
|
xdg_shell_view->map.notify = handle_map;
|
||||||
wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map);
|
wl_signal_add(&xdg_toplevel->base->surface->events.map, &xdg_shell_view->map);
|
||||||
|
|
||||||
xdg_shell_view->unmap.notify = handle_unmap;
|
xdg_shell_view->unmap.notify = handle_unmap;
|
||||||
wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_view->unmap);
|
wl_signal_add(&xdg_toplevel->base->surface->events.unmap, &xdg_shell_view->unmap);
|
||||||
|
|
||||||
|
xdg_shell_view->commit.notify = handle_commit;
|
||||||
|
wl_signal_add(&xdg_toplevel->base->surface->events.commit,
|
||||||
|
&xdg_shell_view->commit);
|
||||||
|
|
||||||
xdg_shell_view->destroy.notify = handle_destroy;
|
xdg_shell_view->destroy.notify = handle_destroy;
|
||||||
wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy);
|
wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy);
|
||||||
|
|
||||||
xdg_surface->data = xdg_shell_view;
|
xdg_toplevel->base->data = xdg_shell_view;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,10 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmanaged_handle_request_activate(struct wl_listener *listener, void *data) {
|
static void unmanaged_handle_request_activate(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xwayland_surface *xsurface = data;
|
struct sway_xwayland_unmanaged *surface =
|
||||||
if (!xsurface->mapped) {
|
wl_container_of(listener, surface, request_activate);
|
||||||
|
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||||
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
|
@ -138,12 +140,29 @@ static void unmanaged_handle_request_activate(struct wl_listener *listener, void
|
||||||
seat_set_focus_surface(seat, xsurface->surface, false);
|
seat_set_focus_surface(seat, xsurface->surface, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unmanaged_handle_associate(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_unmanaged *surface =
|
||||||
|
wl_container_of(listener, surface, associate);
|
||||||
|
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||||
|
wl_signal_add(&xsurface->surface->events.map, &surface->map);
|
||||||
|
surface->map.notify = unmanaged_handle_map;
|
||||||
|
wl_signal_add(&xsurface->surface->events.unmap, &surface->unmap);
|
||||||
|
surface->unmap.notify = unmanaged_handle_unmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unmanaged_handle_dissociate(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_unmanaged *surface =
|
||||||
|
wl_container_of(listener, surface, dissociate);
|
||||||
|
wl_list_remove(&surface->map.link);
|
||||||
|
wl_list_remove(&surface->unmap.link);
|
||||||
|
}
|
||||||
|
|
||||||
static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
|
static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xwayland_unmanaged *surface =
|
struct sway_xwayland_unmanaged *surface =
|
||||||
wl_container_of(listener, surface, destroy);
|
wl_container_of(listener, surface, destroy);
|
||||||
wl_list_remove(&surface->request_configure.link);
|
wl_list_remove(&surface->request_configure.link);
|
||||||
wl_list_remove(&surface->map.link);
|
wl_list_remove(&surface->associate.link);
|
||||||
wl_list_remove(&surface->unmap.link);
|
wl_list_remove(&surface->dissociate.link);
|
||||||
wl_list_remove(&surface->destroy.link);
|
wl_list_remove(&surface->destroy.link);
|
||||||
wl_list_remove(&surface->override_redirect.link);
|
wl_list_remove(&surface->override_redirect.link);
|
||||||
wl_list_remove(&surface->request_activate.link);
|
wl_list_remove(&surface->request_activate.link);
|
||||||
|
@ -159,7 +178,7 @@ static void unmanaged_handle_override_redirect(struct wl_listener *listener, voi
|
||||||
wl_container_of(listener, surface, override_redirect);
|
wl_container_of(listener, surface, override_redirect);
|
||||||
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||||
|
|
||||||
bool mapped = xsurface->mapped;
|
bool mapped = xsurface->surface != NULL && xsurface->surface->mapped;
|
||||||
if (mapped) {
|
if (mapped) {
|
||||||
unmanaged_handle_unmap(&surface->unmap, NULL);
|
unmanaged_handle_unmap(&surface->unmap, NULL);
|
||||||
}
|
}
|
||||||
|
@ -186,10 +205,10 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
|
||||||
wl_signal_add(&xsurface->events.request_configure,
|
wl_signal_add(&xsurface->events.request_configure,
|
||||||
&surface->request_configure);
|
&surface->request_configure);
|
||||||
surface->request_configure.notify = unmanaged_handle_request_configure;
|
surface->request_configure.notify = unmanaged_handle_request_configure;
|
||||||
wl_signal_add(&xsurface->events.map, &surface->map);
|
wl_signal_add(&xsurface->events.associate, &surface->associate);
|
||||||
surface->map.notify = unmanaged_handle_map;
|
surface->associate.notify = unmanaged_handle_associate;
|
||||||
wl_signal_add(&xsurface->events.unmap, &surface->unmap);
|
wl_signal_add(&xsurface->events.dissociate, &surface->dissociate);
|
||||||
surface->unmap.notify = unmanaged_handle_unmap;
|
surface->dissociate.notify = unmanaged_handle_dissociate;
|
||||||
wl_signal_add(&xsurface->events.destroy, &surface->destroy);
|
wl_signal_add(&xsurface->events.destroy, &surface->destroy);
|
||||||
surface->destroy.notify = unmanaged_handle_destroy;
|
surface->destroy.notify = unmanaged_handle_destroy;
|
||||||
wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect);
|
wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect);
|
||||||
|
@ -472,8 +491,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&xwayland_view->set_window_type.link);
|
wl_list_remove(&xwayland_view->set_window_type.link);
|
||||||
wl_list_remove(&xwayland_view->set_hints.link);
|
wl_list_remove(&xwayland_view->set_hints.link);
|
||||||
wl_list_remove(&xwayland_view->set_decorations.link);
|
wl_list_remove(&xwayland_view->set_decorations.link);
|
||||||
wl_list_remove(&xwayland_view->map.link);
|
wl_list_remove(&xwayland_view->associate.link);
|
||||||
wl_list_remove(&xwayland_view->unmap.link);
|
wl_list_remove(&xwayland_view->dissociate.link);
|
||||||
wl_list_remove(&xwayland_view->override_redirect.link);
|
wl_list_remove(&xwayland_view->override_redirect.link);
|
||||||
view_begin_destroy(&xwayland_view->view);
|
view_begin_destroy(&xwayland_view->view);
|
||||||
}
|
}
|
||||||
|
@ -495,8 +514,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
static void handle_map(struct wl_listener *listener, void *data) {
|
static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xwayland_view *xwayland_view =
|
struct sway_xwayland_view *xwayland_view =
|
||||||
wl_container_of(listener, xwayland_view, map);
|
wl_container_of(listener, xwayland_view, map);
|
||||||
struct wlr_xwayland_surface *xsurface = data;
|
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
|
|
||||||
view->natural_width = xsurface->width;
|
view->natural_width = xsurface->width;
|
||||||
view->natural_height = xsurface->height;
|
view->natural_height = xsurface->height;
|
||||||
|
@ -515,10 +534,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
static void handle_override_redirect(struct wl_listener *listener, void *data) {
|
static void handle_override_redirect(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xwayland_view *xwayland_view =
|
struct sway_xwayland_view *xwayland_view =
|
||||||
wl_container_of(listener, xwayland_view, override_redirect);
|
wl_container_of(listener, xwayland_view, override_redirect);
|
||||||
struct wlr_xwayland_surface *xsurface = data;
|
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
|
|
||||||
bool mapped = xsurface->mapped;
|
bool mapped = xsurface->surface != NULL && xsurface->surface->mapped;
|
||||||
if (mapped) {
|
if (mapped) {
|
||||||
handle_unmap(&xwayland_view->unmap, NULL);
|
handle_unmap(&xwayland_view->unmap, NULL);
|
||||||
}
|
}
|
||||||
|
@ -537,7 +556,7 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xwayland_surface_configure_event *ev = data;
|
struct wlr_xwayland_surface_configure_event *ev = data;
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
wlr_xwayland_surface_configure(xsurface, ev->x, ev->y,
|
wlr_xwayland_surface_configure(xsurface, ev->x, ev->y,
|
||||||
ev->width, ev->height);
|
ev->width, ev->height);
|
||||||
return;
|
return;
|
||||||
|
@ -566,7 +585,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
wl_container_of(listener, xwayland_view, request_fullscreen);
|
wl_container_of(listener, xwayland_view, request_fullscreen);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
container_set_fullscreen(view->container, xsurface->fullscreen);
|
container_set_fullscreen(view->container, xsurface->fullscreen);
|
||||||
|
@ -580,7 +599,7 @@ static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, request_minimize);
|
wl_container_of(listener, xwayland_view, request_minimize);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +614,7 @@ static void handle_request_move(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, request_move);
|
wl_container_of(listener, xwayland_view, request_move);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!container_is_floating(view->container) ||
|
if (!container_is_floating(view->container) ||
|
||||||
|
@ -611,7 +630,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, request_resize);
|
wl_container_of(listener, xwayland_view, request_resize);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!container_is_floating(view->container)) {
|
if (!container_is_floating(view->container)) {
|
||||||
|
@ -627,7 +646,7 @@ static void handle_request_activate(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, request_activate);
|
wl_container_of(listener, xwayland_view, request_activate);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view_request_activate(view, NULL);
|
view_request_activate(view, NULL);
|
||||||
|
@ -640,7 +659,7 @@ static void handle_set_title(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, set_title);
|
wl_container_of(listener, xwayland_view, set_title);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view_update_title(view, false);
|
view_update_title(view, false);
|
||||||
|
@ -652,7 +671,7 @@ static void handle_set_class(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, set_class);
|
wl_container_of(listener, xwayland_view, set_class);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view_execute_criteria(view);
|
view_execute_criteria(view);
|
||||||
|
@ -663,7 +682,7 @@ static void handle_set_role(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, set_role);
|
wl_container_of(listener, xwayland_view, set_role);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view_execute_criteria(view);
|
view_execute_criteria(view);
|
||||||
|
@ -699,7 +718,7 @@ static void handle_set_window_type(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, set_window_type);
|
wl_container_of(listener, xwayland_view, set_window_type);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view_execute_criteria(view);
|
view_execute_criteria(view);
|
||||||
|
@ -710,7 +729,7 @@ static void handle_set_hints(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, xwayland_view, set_hints);
|
wl_container_of(listener, xwayland_view, set_hints);
|
||||||
struct sway_view *view = &xwayland_view->view;
|
struct sway_view *view = &xwayland_view->view;
|
||||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
if (!xsurface->mapped) {
|
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool hints_urgency = xcb_icccm_wm_hints_get_urgency(xsurface->hints);
|
const bool hints_urgency = xcb_icccm_wm_hints_get_urgency(xsurface->hints);
|
||||||
|
@ -725,6 +744,24 @@ static void handle_set_hints(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_associate(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_view *xwayland_view =
|
||||||
|
wl_container_of(listener, xwayland_view, associate);
|
||||||
|
struct wlr_xwayland_surface *xsurface =
|
||||||
|
xwayland_view->view.wlr_xwayland_surface;
|
||||||
|
wl_signal_add(&xsurface->surface->events.unmap, &xwayland_view->unmap);
|
||||||
|
xwayland_view->unmap.notify = handle_unmap;
|
||||||
|
wl_signal_add(&xsurface->surface->events.map, &xwayland_view->map);
|
||||||
|
xwayland_view->map.notify = handle_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_dissociate(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_view *xwayland_view =
|
||||||
|
wl_container_of(listener, xwayland_view, dissociate);
|
||||||
|
wl_list_remove(&xwayland_view->map.link);
|
||||||
|
wl_list_remove(&xwayland_view->unmap.link);
|
||||||
|
}
|
||||||
|
|
||||||
struct sway_view *view_from_wlr_xwayland_surface(
|
struct sway_view *view_from_wlr_xwayland_surface(
|
||||||
struct wlr_xwayland_surface *xsurface) {
|
struct wlr_xwayland_surface *xsurface) {
|
||||||
return xsurface->data;
|
return xsurface->data;
|
||||||
|
@ -794,11 +831,11 @@ struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsu
|
||||||
&xwayland_view->set_decorations);
|
&xwayland_view->set_decorations);
|
||||||
xwayland_view->set_decorations.notify = handle_set_decorations;
|
xwayland_view->set_decorations.notify = handle_set_decorations;
|
||||||
|
|
||||||
wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap);
|
wl_signal_add(&xsurface->events.associate, &xwayland_view->associate);
|
||||||
xwayland_view->unmap.notify = handle_unmap;
|
xwayland_view->associate.notify = handle_associate;
|
||||||
|
|
||||||
wl_signal_add(&xsurface->events.map, &xwayland_view->map);
|
wl_signal_add(&xsurface->events.dissociate, &xwayland_view->dissociate);
|
||||||
xwayland_view->map.notify = handle_map;
|
xwayland_view->dissociate.notify = handle_dissociate;
|
||||||
|
|
||||||
wl_signal_add(&xsurface->events.set_override_redirect,
|
wl_signal_add(&xsurface->events.set_override_redirect,
|
||||||
&xwayland_view->override_redirect);
|
&xwayland_view->override_redirect);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_idle.h>
|
#include <wlr/types/wlr_cursor_shape_v1.h>
|
||||||
#include <wlr/types/wlr_pointer.h>
|
#include <wlr/types/wlr_pointer.h>
|
||||||
#include <wlr/types/wlr_touch.h>
|
#include <wlr/types/wlr_touch.h>
|
||||||
#include <wlr/types/wlr_tablet_v2.h>
|
#include <wlr/types/wlr_tablet_v2.h>
|
||||||
|
@ -55,7 +55,8 @@ static struct wlr_surface *layer_surface_at(struct sway_output *output,
|
||||||
static bool surface_is_xdg_popup(struct wlr_surface *surface) {
|
static bool surface_is_xdg_popup(struct wlr_surface *surface) {
|
||||||
struct wlr_xdg_surface *xdg_surface =
|
struct wlr_xdg_surface *xdg_surface =
|
||||||
wlr_xdg_surface_try_from_wlr_surface(surface);
|
wlr_xdg_surface_try_from_wlr_surface(surface);
|
||||||
return xdg_surface != NULL && xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP;
|
return xdg_surface != NULL && xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP &&
|
||||||
|
xdg_surface->popup != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
|
static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
|
||||||
|
@ -236,7 +237,7 @@ void cursor_update_image(struct sway_cursor *cursor,
|
||||||
// Try a node's resize edge
|
// Try a node's resize edge
|
||||||
enum wlr_edges edge = find_resize_edge(node->sway_container, NULL, cursor);
|
enum wlr_edges edge = find_resize_edge(node->sway_container, NULL, cursor);
|
||||||
if (edge == WLR_EDGE_NONE) {
|
if (edge == WLR_EDGE_NONE) {
|
||||||
cursor_set_image(cursor, "left_ptr", NULL);
|
cursor_set_image(cursor, "default", NULL);
|
||||||
} else if (container_is_floating(node->sway_container)) {
|
} else if (container_is_floating(node->sway_container)) {
|
||||||
cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
|
cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -247,12 +248,12 @@ void cursor_update_image(struct sway_cursor *cursor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cursor_set_image(cursor, "left_ptr", NULL);
|
cursor_set_image(cursor, "default", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cursor_hide(struct sway_cursor *cursor) {
|
static void cursor_hide(struct sway_cursor *cursor) {
|
||||||
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
wlr_cursor_unset_image(cursor->cursor);
|
||||||
cursor->hidden = true;
|
cursor->hidden = true;
|
||||||
wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat);
|
wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat);
|
||||||
}
|
}
|
||||||
|
@ -509,6 +510,24 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_cancel);
|
||||||
|
struct wlr_touch_cancel_event *event = data;
|
||||||
|
cursor_handle_activity_from_device(cursor, &event->touch->base);
|
||||||
|
|
||||||
|
struct sway_seat *seat = cursor->seat;
|
||||||
|
|
||||||
|
if (cursor->simulating_pointer_from_touch) {
|
||||||
|
if (cursor->pointer_touch_id == cursor->seat->touch_id) {
|
||||||
|
cursor->pointer_touch_up = true;
|
||||||
|
dispatch_cursor_button(cursor, &event->touch->base,
|
||||||
|
event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
seatop_touch_cancel(seat, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
||||||
struct sway_cursor *cursor =
|
struct sway_cursor *cursor =
|
||||||
wl_container_of(listener, cursor, touch_motion);
|
wl_container_of(listener, cursor, touch_motion);
|
||||||
|
@ -1050,10 +1069,9 @@ void cursor_set_image(struct sway_cursor *cursor, const char *image,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image) {
|
if (!image) {
|
||||||
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
wlr_cursor_unset_image(cursor->cursor);
|
||||||
} else if (!current_image || strcmp(current_image, image) != 0) {
|
} else if (!current_image || strcmp(current_image, image) != 0) {
|
||||||
wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image,
|
wlr_cursor_set_xcursor(cursor->cursor, cursor->xcursor_manager, image);
|
||||||
cursor->cursor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,6 +1118,7 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
|
||||||
wl_list_remove(&cursor->frame.link);
|
wl_list_remove(&cursor->frame.link);
|
||||||
wl_list_remove(&cursor->touch_down.link);
|
wl_list_remove(&cursor->touch_down.link);
|
||||||
wl_list_remove(&cursor->touch_up.link);
|
wl_list_remove(&cursor->touch_up.link);
|
||||||
|
wl_list_remove(&cursor->touch_cancel.link);
|
||||||
wl_list_remove(&cursor->touch_motion.link);
|
wl_list_remove(&cursor->touch_motion.link);
|
||||||
wl_list_remove(&cursor->touch_frame.link);
|
wl_list_remove(&cursor->touch_frame.link);
|
||||||
wl_list_remove(&cursor->tool_axis.link);
|
wl_list_remove(&cursor->tool_axis.link);
|
||||||
|
@ -1136,9 +1155,6 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
|
||||||
wl_list_init(&cursor->image_surface_destroy.link);
|
wl_list_init(&cursor->image_surface_destroy.link);
|
||||||
cursor->image_surface_destroy.notify = handle_image_surface_destroy;
|
cursor->image_surface_destroy.notify = handle_image_surface_destroy;
|
||||||
|
|
||||||
// gesture events
|
|
||||||
cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display);
|
|
||||||
|
|
||||||
wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin);
|
wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin);
|
||||||
cursor->hold_begin.notify = handle_pointer_hold_begin;
|
cursor->hold_begin.notify = handle_pointer_hold_begin;
|
||||||
wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end);
|
wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end);
|
||||||
|
@ -1181,6 +1197,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
|
||||||
wl_signal_add(&wlr_cursor->events.touch_up, &cursor->touch_up);
|
wl_signal_add(&wlr_cursor->events.touch_up, &cursor->touch_up);
|
||||||
cursor->touch_up.notify = handle_touch_up;
|
cursor->touch_up.notify = handle_touch_up;
|
||||||
|
|
||||||
|
wl_signal_add(&wlr_cursor->events.touch_cancel, &cursor->touch_cancel);
|
||||||
|
cursor->touch_cancel.notify = handle_touch_cancel;
|
||||||
|
|
||||||
wl_signal_add(&wlr_cursor->events.touch_motion,
|
wl_signal_add(&wlr_cursor->events.touch_motion,
|
||||||
&cursor->touch_motion);
|
&cursor->touch_motion);
|
||||||
cursor->touch_motion.notify = handle_touch_motion;
|
cursor->touch_motion.notify = handle_touch_motion;
|
||||||
|
@ -1273,11 +1292,7 @@ uint32_t get_mouse_bindsym(const char *name, char **error) {
|
||||||
// Get event code from name
|
// Get event code from name
|
||||||
int code = libevdev_event_code_from_name(EV_KEY, name);
|
int code = libevdev_event_code_from_name(EV_KEY, name);
|
||||||
if (code == -1) {
|
if (code == -1) {
|
||||||
size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1;
|
*error = format_str("Unknown event %s", name);
|
||||||
*error = malloc(len);
|
|
||||||
if (*error) {
|
|
||||||
snprintf(*error, len, "Unknown event %s", name);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
|
@ -1299,13 +1314,8 @@ uint32_t get_mouse_bindcode(const char *name, char **error) {
|
||||||
}
|
}
|
||||||
const char *event = libevdev_event_code_get_name(EV_KEY, code);
|
const char *event = libevdev_event_code_get_name(EV_KEY, code);
|
||||||
if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
|
if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
|
||||||
size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button",
|
*error = format_str("Event code %d (%s) is not a button",
|
||||||
code, event ? event : "(null)") + 1;
|
code, event ? event : "(null)");
|
||||||
*error = malloc(len);
|
|
||||||
if (*error) {
|
|
||||||
snprintf(*error, len, "Event code %d (%s) is not a button",
|
|
||||||
code, event ? event : "(null)");
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
|
@ -1458,3 +1468,26 @@ void sway_cursor_constrain(struct sway_cursor *cursor,
|
||||||
wl_signal_add(&constraint->surface->events.commit,
|
wl_signal_add(&constraint->surface->events.commit,
|
||||||
&cursor->constraint_commit);
|
&cursor->constraint_commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_request_set_cursor_shape(struct wl_listener *listener, void *data) {
|
||||||
|
const struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
|
||||||
|
struct sway_seat *seat = event->seat_client->seat->data;
|
||||||
|
|
||||||
|
if (!seatop_allows_set_cursor(seat)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_client *focused_client = NULL;
|
||||||
|
struct wlr_surface *focused_surface = seat->wlr_seat->pointer_state.focused_surface;
|
||||||
|
if (focused_surface != NULL) {
|
||||||
|
focused_client = wl_resource_get_client(focused_surface->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check cursor mode
|
||||||
|
if (focused_client == NULL || event->seat_client->client != focused_client) {
|
||||||
|
sway_log(SWAY_DEBUG, "denying request to set cursor from unfocused client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor_set_image(seat->cursor, wlr_cursor_shape_v1_name(event->shape), focused_client);
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <wlr/config.h>
|
#include <wlr/config.h>
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_keyboard_group.h>
|
#include <wlr/types/wlr_keyboard_group.h>
|
||||||
#include <wlr/types/wlr_input_inhibitor.h>
|
|
||||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
@ -80,15 +79,7 @@ char *input_device_get_identifier(struct wlr_input_device *device) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *fmt = "%d:%d:%s";
|
char *identifier = format_str("%d:%d:%s", vendor, product, name);
|
||||||
int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1;
|
|
||||||
char *identifier = malloc(len);
|
|
||||||
if (!identifier) {
|
|
||||||
sway_log(SWAY_ERROR, "Unable to allocate unique input device name");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(identifier, len, fmt, vendor, product, name);
|
|
||||||
free(name);
|
free(name);
|
||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
@ -292,34 +283,6 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_inhibit_activate(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_input_manager *input_manager = wl_container_of(
|
|
||||||
listener, input_manager, inhibit_activate);
|
|
||||||
struct sway_seat *seat;
|
|
||||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
|
||||||
seat_set_exclusive_client(seat, input_manager->inhibit->active_client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_inhibit_deactivate(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_input_manager *input_manager = wl_container_of(
|
|
||||||
listener, input_manager, inhibit_deactivate);
|
|
||||||
struct sway_seat *seat;
|
|
||||||
if (server.session_lock.locked) {
|
|
||||||
// Don't deactivate the grab of a screenlocker
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
|
||||||
seat_set_exclusive_client(seat, NULL);
|
|
||||||
struct sway_node *previous = seat_get_focus(seat);
|
|
||||||
if (previous) {
|
|
||||||
// Hack to get seat to re-focus the return value of get_focus
|
|
||||||
seat_set_focus(seat, NULL);
|
|
||||||
seat_set_focus(seat, previous);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_keyboard_shortcuts_inhibitor_destroy(
|
static void handle_keyboard_shortcuts_inhibitor_destroy(
|
||||||
struct wl_listener *listener, void *data) {
|
struct wl_listener *listener, void *data) {
|
||||||
struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
|
struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
|
||||||
|
@ -488,14 +451,6 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
|
||||||
&input->virtual_pointer_new);
|
&input->virtual_pointer_new);
|
||||||
input->virtual_pointer_new.notify = handle_virtual_pointer;
|
input->virtual_pointer_new.notify = handle_virtual_pointer;
|
||||||
|
|
||||||
input->inhibit = wlr_input_inhibit_manager_create(server->wl_display);
|
|
||||||
input->inhibit_activate.notify = handle_inhibit_activate;
|
|
||||||
wl_signal_add(&input->inhibit->events.activate,
|
|
||||||
&input->inhibit_activate);
|
|
||||||
input->inhibit_deactivate.notify = handle_inhibit_deactivate;
|
|
||||||
wl_signal_add(&input->inhibit->events.deactivate,
|
|
||||||
&input->inhibit_deactivate);
|
|
||||||
|
|
||||||
input->keyboard_shortcuts_inhibit =
|
input->keyboard_shortcuts_inhibit =
|
||||||
wlr_keyboard_shortcuts_inhibit_v1_create(server->wl_display);
|
wlr_keyboard_shortcuts_inhibit_v1_create(server->wl_display);
|
||||||
input->keyboard_shortcuts_inhibit_new_inhibitor.notify =
|
input->keyboard_shortcuts_inhibit_new_inhibitor.notify =
|
||||||
|
@ -503,6 +458,8 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
|
||||||
wl_signal_add(&input->keyboard_shortcuts_inhibit->events.new_inhibitor,
|
wl_signal_add(&input->keyboard_shortcuts_inhibit->events.new_inhibitor,
|
||||||
&input->keyboard_shortcuts_inhibit_new_inhibitor);
|
&input->keyboard_shortcuts_inhibit_new_inhibitor);
|
||||||
|
|
||||||
|
input->pointer_gestures = wlr_pointer_gestures_v1_create(server->wl_display);
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,6 +497,18 @@ static void retranslate_keysyms(struct input_config *input_config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < config->input_type_configs->length; ++i) {
|
||||||
|
struct input_config *ic = config->input_type_configs->items[i];
|
||||||
|
if (ic->xkb_layout || ic->xkb_file) {
|
||||||
|
// this is the first config with xkb_layout or xkb_file
|
||||||
|
if (ic->identifier == input_config->identifier) {
|
||||||
|
translate_keysyms(ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void input_manager_configure_input(
|
static void input_manager_configure_input(
|
||||||
|
@ -558,10 +527,13 @@ static void input_manager_configure_input(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_manager_configure_all_inputs(void) {
|
void input_manager_configure_all_input_mappings(void) {
|
||||||
struct sway_input_device *input_device = NULL;
|
struct sway_input_device *input_device;
|
||||||
wl_list_for_each(input_device, &server.input->devices, link) {
|
wl_list_for_each(input_device, &server.input->devices, link) {
|
||||||
input_manager_configure_input(input_device);
|
struct sway_seat *seat;
|
||||||
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
seat_configure_device_mapping(seat, input_device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue