mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -04:00
Merge branch 'master' into indonesian_translation
This commit is contained in:
commit
916838cd51
50 changed files with 687 additions and 198 deletions
38
.builds/alpine.yml
Normal file
38
.builds/alpine.yml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
image: alpine/edge
|
||||||
|
packages:
|
||||||
|
- cairo-dev
|
||||||
|
- eudev-dev
|
||||||
|
- gdk-pixbuf-dev
|
||||||
|
- json-c-dev
|
||||||
|
- libevdev-dev
|
||||||
|
- libinput-dev
|
||||||
|
- libxcb-dev
|
||||||
|
- libxkbcommon-dev
|
||||||
|
- mesa-dev
|
||||||
|
- meson
|
||||||
|
- pango-dev
|
||||||
|
- pixman-dev
|
||||||
|
- scdoc
|
||||||
|
- wayland-dev
|
||||||
|
- wayland-protocols
|
||||||
|
- xcb-util-image-dev
|
||||||
|
- xorg-server-xwayland
|
||||||
|
sources:
|
||||||
|
- https://github.com/swaywm/sway
|
||||||
|
- https://github.com/swaywm/wlroots
|
||||||
|
tasks:
|
||||||
|
- wlroots: |
|
||||||
|
cd wlroots
|
||||||
|
meson --prefix=/usr build -Drootston=false -Dexamples=false
|
||||||
|
ninja -C build
|
||||||
|
sudo ninja -C build install
|
||||||
|
- setup: |
|
||||||
|
cd sway
|
||||||
|
meson build
|
||||||
|
- build: |
|
||||||
|
cd sway
|
||||||
|
ninja -C build
|
||||||
|
- build-no-xwayland: |
|
||||||
|
cd sway
|
||||||
|
meson configure build -Dxwayland=disabled
|
||||||
|
ninja -C build
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
# vim: ft=yaml ts=2 sw=2 et :
|
|
||||||
image: archlinux
|
image: archlinux
|
||||||
packages:
|
packages:
|
||||||
- meson
|
|
||||||
- xorg-server-xwayland
|
|
||||||
- xcb-util-image
|
|
||||||
- json-c
|
|
||||||
- pango
|
|
||||||
- cairo
|
- cairo
|
||||||
|
- gdk-pixbuf2
|
||||||
|
- json-c
|
||||||
|
- libinput
|
||||||
|
- libxcb
|
||||||
|
- libxkbcommon
|
||||||
|
- meson
|
||||||
|
- pango
|
||||||
|
- scdoc
|
||||||
- wayland
|
- wayland
|
||||||
- wayland-protocols
|
- wayland-protocols
|
||||||
- gdk-pixbuf2
|
- xcb-util-image
|
||||||
- libinput
|
- xorg-server-xwayland
|
||||||
- libxkbcommon
|
|
||||||
- scdoc
|
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/swaywm/sway
|
- https://github.com/swaywm/sway
|
||||||
- https://github.com/swaywm/wlroots
|
- https://github.com/swaywm/wlroots
|
||||||
tasks:
|
tasks:
|
||||||
- wlroots: |
|
- wlroots: |
|
||||||
cd wlroots
|
cd wlroots
|
||||||
meson --prefix=/usr build
|
meson --prefix=/usr build -Drootston=false -Dexamples=false
|
||||||
ninja -C build
|
ninja -C build
|
||||||
sudo ninja -C build install
|
sudo ninja -C build install
|
||||||
- setup: |
|
- setup: |
|
||||||
53
.builds/freebsd.yml
Normal file
53
.builds/freebsd.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
image: freebsd/latest
|
||||||
|
packages:
|
||||||
|
- devel/json-c
|
||||||
|
- devel/libevdev
|
||||||
|
- devel/meson
|
||||||
|
- devel/pkgconf
|
||||||
|
- graphics/cairo
|
||||||
|
- graphics/gdk-pixbuf2
|
||||||
|
- graphics/wayland
|
||||||
|
- graphics/wayland-protocols
|
||||||
|
- textproc/scdoc
|
||||||
|
- x11-toolkits/pango
|
||||||
|
- x11/libxcb
|
||||||
|
- x11/libxkbcommon
|
||||||
|
# wlroots dependencies
|
||||||
|
- devel/evdev-proto
|
||||||
|
- devel/libepoll-shim
|
||||||
|
- devel/libudev-devd
|
||||||
|
- graphics/libdrm
|
||||||
|
- graphics/mesa-libs
|
||||||
|
- x11/libinput
|
||||||
|
- x11/libX11
|
||||||
|
- x11/pixman
|
||||||
|
- x11/xcb-util-wm
|
||||||
|
sources:
|
||||||
|
- https://github.com/swaywm/sway
|
||||||
|
- https://github.com/swaywm/wlroots
|
||||||
|
tasks:
|
||||||
|
- fixup_epoll: |
|
||||||
|
cat << 'EOF' | sudo tee /usr/local/libdata/pkgconfig/epoll-shim.pc
|
||||||
|
prefix=/usr/local
|
||||||
|
exec_prefix=\$\{\$prefix\}
|
||||||
|
libdir=${prefix}/lib
|
||||||
|
sharedlibdir=${prefix}/lib
|
||||||
|
includedir=${prefix}/include/libepoll-shim
|
||||||
|
Name: epoll-shim
|
||||||
|
Description: epoll shim implemented using kevent
|
||||||
|
Version: 0
|
||||||
|
Requires:
|
||||||
|
Libs: -L${libdir} -L${sharedlibdir} -lepoll-shim
|
||||||
|
Libs.private: -pthread -lrt
|
||||||
|
Cflags: -I${includedir}
|
||||||
|
EOF
|
||||||
|
- setup: |
|
||||||
|
cd sway
|
||||||
|
mkdir subprojects
|
||||||
|
cd subprojects
|
||||||
|
ln -s ../../wlroots wlroots
|
||||||
|
cd ..
|
||||||
|
meson build
|
||||||
|
- build: |
|
||||||
|
cd sway
|
||||||
|
ninja -C build
|
||||||
70
README.es.md
Normal file
70
README.es.md
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
# sway
|
||||||
|
|
||||||
|
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) -
|
||||||
|
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--)
|
||||||
|
|
||||||
|
sway es un compositor de [Wayland](http://wayland.freedesktop.org/) compatible con i3.
|
||||||
|
Lea el [FAQ](https://github.com/swaywm/sway/wiki). Únase al [canal de IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on
|
||||||
|
irc.freenode.net).
|
||||||
|
|
||||||
|
Si quiere apoyar el desarrollo de sway, por favor, contribuya en [la página de Patreon de SirCmpwn](https://patreon.com/sircmpwn).
|
||||||
|
|
||||||
|
## Firmas de las versiones
|
||||||
|
|
||||||
|
Las distintas versiones están firmadas con [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
|
||||||
|
y publicadas [en GitHub](https://github.com/swaywm/sway/releases).
|
||||||
|
|
||||||
|
## Instalación
|
||||||
|
|
||||||
|
### Usando paquetes
|
||||||
|
|
||||||
|
Sway está disponible en muchas distribuciones. Pruebe instalando el paquete "sway" desde la suya.
|
||||||
|
Si no está disponible, puede consultar [esta documentación](https://github.com/swaywm/sway/wiki/Unsupported-packages)
|
||||||
|
y así obtener información acerca de como instalarlo.
|
||||||
|
|
||||||
|
Si está interesado en crear un paquete para su distribución, únase al canal de IRC o
|
||||||
|
escriba un email a sir@cmpwn.com
|
||||||
|
|
||||||
|
### Compilando el código fuente
|
||||||
|
|
||||||
|
Instale las dependencias:
|
||||||
|
|
||||||
|
* meson \*
|
||||||
|
* [wlroots](https://github.com/swaywm/wlroots)
|
||||||
|
* wayland
|
||||||
|
* wayland-protocols \*
|
||||||
|
* pcre
|
||||||
|
* json-c
|
||||||
|
* pango
|
||||||
|
* cairo
|
||||||
|
* gdk-pixbuf2 \*\*
|
||||||
|
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) >= 1.8.1 (optional: man pages) \*
|
||||||
|
* git \*
|
||||||
|
|
||||||
|
_\*Compile-time dep_
|
||||||
|
|
||||||
|
_\*\*opcional: necesario para swaybg_
|
||||||
|
|
||||||
|
Desde su consola, ejecute las órdenes:
|
||||||
|
|
||||||
|
meson build
|
||||||
|
ninja -C build
|
||||||
|
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
|
||||||
|
|
||||||
|
Si ya utiliza i3, copie su archivo de configuración de i3 a `~/.config/sway/config` y
|
||||||
|
sway funcionará sin tener que configurar nada más. En otro caso, copie el archivo de
|
||||||
|
configuración básico a `~/.config/sway/config`, normalmente se encuentra en `/etc/sway/config`.
|
||||||
|
Ejecute `man 5 sway` para obtener información sobre la configuración.
|
||||||
|
|
||||||
|
## Ejecución
|
||||||
|
|
||||||
|
Ejecute `sway` desde su consola. Algunos gestores de pantalla pueden funcionar sin estar
|
||||||
|
soportados por `sway` (sabemos que gdm funciona bastante bien).
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
# sway
|
# sway
|
||||||
|
|
||||||
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Indonesian](https://github.com/swaywm/sway/blob/master/README.id.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) -
|
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Indonesian](https://github.com/swaywm/sway/blob/master/README.id.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) -
|
||||||
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--)
|
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--) -
|
||||||
|
[Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--)
|
||||||
|
|
||||||
|
|
||||||
sway is an i3-compatible [Wayland](http://wayland.freedesktop.org/) compositor.
|
sway is an i3-compatible [Wayland](http://wayland.freedesktop.org/) compositor.
|
||||||
Read the [FAQ](https://github.com/swaywm/sway/wiki). Join the [IRC
|
Read the [FAQ](https://github.com/swaywm/sway/wiki). Join the [IRC
|
||||||
|
|
|
||||||
71
README.pl.md
Normal file
71
README.pl.md
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# sway
|
||||||
|
|
||||||
|
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) -
|
||||||
|
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--) -
|
||||||
|
[Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--)
|
||||||
|
|
||||||
|
sway jest kompozytorem [Wayland](http://wayland.freedesktop.org/) kompatybilnym z i3.
|
||||||
|
Przeczytaj [FAQ](https://github.com/swaywm/sway/wiki). Dołącz do [kanału IRC](http://webchat.freenode.net/?channels=sway&uio=d4)
|
||||||
|
(#sway na irc.freenode.net).
|
||||||
|
|
||||||
|
Jeśli chcesz wesprzeć rozwój sway, rozważ wsparcie SirCmpwn na jego [stronie Patreon](https://patreon.com/sircmpwn).
|
||||||
|
|
||||||
|
## Podpisy cyfrowe wydań
|
||||||
|
|
||||||
|
Wydania są podpisywane przy pomocy klucza [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A)
|
||||||
|
i publikowane [na GitHubie](https://github.com/swaywm/sway/releases).
|
||||||
|
|
||||||
|
## Instalacja
|
||||||
|
|
||||||
|
### Z pakietów
|
||||||
|
|
||||||
|
Sway jest dostępny w wielu dystybucjach. Spróbuj zainstalować pakiet "sway" w swoim
|
||||||
|
menedżerze pakietów. Jeśli nie jest dostępny, sprawdź [tę stronę wiki](https://github.com/swaywm/sway/wiki/Unsupported-packages)
|
||||||
|
aby uzyskać informacje dotyczące instalacji w swojej dystrybucji.
|
||||||
|
|
||||||
|
Jeśli chciałbyś stworzyć pakiet sway dla swojej dystrybucji, odwiedź kanał IRC lub wyślij email na
|
||||||
|
adres sir@cmpwn.com w celu uzyskania wskazówek.
|
||||||
|
|
||||||
|
### Kompilacja ze Źródła
|
||||||
|
|
||||||
|
Zainstaluj zależności:
|
||||||
|
|
||||||
|
* meson \*
|
||||||
|
* [wlroots](https://github.com/swaywm/wlroots)
|
||||||
|
* wayland
|
||||||
|
* wayland-protocols \*
|
||||||
|
* pcre
|
||||||
|
* json-c
|
||||||
|
* pango
|
||||||
|
* cairo
|
||||||
|
* gdk-pixbuf2 \*\*
|
||||||
|
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) >= 1.8.1 (opcjonalnie: strony pomocy man) \*
|
||||||
|
* git \*
|
||||||
|
|
||||||
|
_\*zależności kompilacji_
|
||||||
|
|
||||||
|
_\*\*opcjonalnie: wymagane dla swaybg_
|
||||||
|
|
||||||
|
Wykonaj następujące polecenia:
|
||||||
|
|
||||||
|
meson build
|
||||||
|
ninja -C build
|
||||||
|
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
|
||||||
|
|
||||||
|
Jeśli już korzystasz z i3, skopiuj swoją konfigurację i3 do katalogu `~/.config/sway/config` i
|
||||||
|
zadziała od ręki. W przeciwnym razie skopiuj przykładowy plik konfiguracyjny do folderu
|
||||||
|
`~/.config/sway/config`; zazwyczaj znajduje się w `/etc/sway/config`.
|
||||||
|
Wykonaj polecenie `man 5 sway` aby uzyskać informacje dotyczące konfiguracji.
|
||||||
|
|
||||||
|
## Uruchamianie
|
||||||
|
|
||||||
|
Wykonaj polecenie `sway` z poziomu TTY. Niektóre menedżery wyświetlania mogą umożliwiać rozruch z ich
|
||||||
|
poziomu, ale nie jest to wspierane przez sway (w gdm podobno działa to całkiem nieźle).
|
||||||
|
|
@ -112,7 +112,6 @@ sway_cmd cmd_client_placeholder;
|
||||||
sway_cmd cmd_client_background;
|
sway_cmd cmd_client_background;
|
||||||
sway_cmd cmd_commands;
|
sway_cmd cmd_commands;
|
||||||
sway_cmd cmd_create_output;
|
sway_cmd cmd_create_output;
|
||||||
sway_cmd cmd_debuglog;
|
|
||||||
sway_cmd cmd_default_border;
|
sway_cmd cmd_default_border;
|
||||||
sway_cmd cmd_default_floating_border;
|
sway_cmd cmd_default_floating_border;
|
||||||
sway_cmd cmd_default_orientation;
|
sway_cmd cmd_default_orientation;
|
||||||
|
|
|
||||||
|
|
@ -586,6 +586,8 @@ struct output_config *store_output_config(struct output_config *oc);
|
||||||
|
|
||||||
void apply_output_config_to_outputs(struct output_config *oc);
|
void apply_output_config_to_outputs(struct output_config *oc);
|
||||||
|
|
||||||
|
void reset_outputs(void);
|
||||||
|
|
||||||
void free_output_config(struct output_config *oc);
|
void free_output_config(struct output_config *oc);
|
||||||
|
|
||||||
int workspace_output_cmp_workspace(const void *a, const void *b);
|
int workspace_output_cmp_workspace(const void *a, const void *b);
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
|
||||||
* This chooses a cursor icon and sends a motion event to the surface.
|
* This chooses a cursor icon and sends a motion event to the surface.
|
||||||
*/
|
*/
|
||||||
void cursor_rebase(struct sway_cursor *cursor);
|
void cursor_rebase(struct sway_cursor *cursor);
|
||||||
|
void cursor_rebase_all(void);
|
||||||
|
|
||||||
void cursor_handle_activity(struct sway_cursor *cursor);
|
void cursor_handle_activity(struct sway_cursor *cursor);
|
||||||
void cursor_unhide(struct sway_cursor *cursor);
|
void cursor_unhide(struct sway_cursor *cursor);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ struct sway_output {
|
||||||
struct sway_node node;
|
struct sway_node node;
|
||||||
struct wlr_output *wlr_output;
|
struct wlr_output *wlr_output;
|
||||||
struct sway_server *server;
|
struct sway_server *server;
|
||||||
|
struct wl_list link;
|
||||||
|
|
||||||
struct wl_list layers[4]; // sway_layer_surface::link
|
struct wl_list layers[4]; // sway_layer_surface::link
|
||||||
struct wlr_box usable_area;
|
struct wlr_box usable_area;
|
||||||
|
|
@ -36,6 +37,8 @@ struct sway_output {
|
||||||
|
|
||||||
struct sway_output_state current;
|
struct sway_output_state current;
|
||||||
|
|
||||||
|
struct wl_client *swaybg_client;
|
||||||
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener mode;
|
struct wl_listener mode;
|
||||||
struct wl_listener transform;
|
struct wl_listener transform;
|
||||||
|
|
@ -43,10 +46,7 @@ struct sway_output {
|
||||||
struct wl_listener present;
|
struct wl_listener present;
|
||||||
struct wl_listener damage_destroy;
|
struct wl_listener damage_destroy;
|
||||||
struct wl_listener damage_frame;
|
struct wl_listener damage_frame;
|
||||||
|
struct wl_listener swaybg_client_destroy;
|
||||||
struct wl_list link;
|
|
||||||
|
|
||||||
pid_t bg_pid;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,13 @@ struct sway_workspace *workspace_by_number(const char* name);
|
||||||
|
|
||||||
struct sway_workspace *workspace_by_name(const char*);
|
struct sway_workspace *workspace_by_name(const char*);
|
||||||
|
|
||||||
struct sway_workspace *workspace_output_next(struct sway_workspace *current);
|
struct sway_workspace *workspace_output_next(
|
||||||
|
struct sway_workspace *current, bool create);
|
||||||
|
|
||||||
struct sway_workspace *workspace_next(struct sway_workspace *current);
|
struct sway_workspace *workspace_next(struct sway_workspace *current);
|
||||||
|
|
||||||
struct sway_workspace *workspace_output_prev(struct sway_workspace *current);
|
struct sway_workspace *workspace_output_prev(
|
||||||
|
struct sway_workspace *current, bool create);
|
||||||
|
|
||||||
struct sway_workspace *workspace_prev(struct sway_workspace *current);
|
struct sway_workspace *workspace_prev(struct sway_workspace *current);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ struct swaybar {
|
||||||
#if HAVE_TRAY
|
#if HAVE_TRAY
|
||||||
struct swaybar_tray *tray;
|
struct swaybar_tray *tray;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool running;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct swaybar_output {
|
struct swaybar_output {
|
||||||
|
|
|
||||||
17
meson.build
17
meson.build
|
|
@ -60,7 +60,11 @@ rt = cc.find_library('rt')
|
||||||
git = find_program('git', required: false)
|
git = find_program('git', required: false)
|
||||||
|
|
||||||
# Try first to find wlroots as a subproject, then as a system dependency
|
# Try first to find wlroots as a subproject, then as a system dependency
|
||||||
wlroots_proj = subproject('wlroots', required: false)
|
wlroots_proj = subproject(
|
||||||
|
'wlroots',
|
||||||
|
default_options: ['rootston=false', 'examples=false'],
|
||||||
|
required: false,
|
||||||
|
)
|
||||||
if wlroots_proj.found()
|
if wlroots_proj.found()
|
||||||
wlroots = wlroots_proj.get_variable('wlroots')
|
wlroots = wlroots_proj.get_variable('wlroots')
|
||||||
wlroots_conf = wlroots_proj.get_variable('conf_data')
|
wlroots_conf = wlroots_proj.get_variable('conf_data')
|
||||||
|
|
@ -128,12 +132,13 @@ endif
|
||||||
|
|
||||||
add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c')
|
add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c')
|
||||||
|
|
||||||
|
version = '"@0@"'.format(meson.project_version())
|
||||||
if git.found()
|
if git.found()
|
||||||
git_commit_hash = run_command([git.path(), 'describe', '--always', '--tags']).stdout().strip()
|
git_commit_hash = run_command([git.path(), 'describe', '--always', '--tags'])
|
||||||
git_branch = run_command([git.path(), 'rev-parse', '--abbrev-ref', 'HEAD']).stdout().strip()
|
git_branch = run_command([git.path(), 'rev-parse', '--abbrev-ref', 'HEAD'])
|
||||||
version = '"@0@ (" __DATE__ ", branch \'@1@\')"'.format(git_commit_hash, git_branch)
|
if git_commit_hash.returncode() == 0 and git_branch.returncode() == 0
|
||||||
else
|
version = '"@0@ (" __DATE__ ", branch \'@1@\')"'.format(git_commit_hash.stdout().strip(), git_branch.stdout().strip())
|
||||||
version = '"@0@"'.format(meson.project_version())
|
endif
|
||||||
endif
|
endif
|
||||||
add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c')
|
add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
|
||||||
if (strcasecmp("toggle", mode) == 0 && !config->reading) {
|
if (strcasecmp("toggle", mode) == 0 && !config->reading) {
|
||||||
if (strcasecmp("dock", bar->mode) == 0) {
|
if (strcasecmp("dock", bar->mode) == 0) {
|
||||||
bar->mode = strdup("hide");
|
bar->mode = strdup("hide");
|
||||||
} else if (strcasecmp("hide", bar->mode) == 0) {
|
} else{
|
||||||
bar->mode = strdup("dock");
|
bar->mode = strdup("dock");
|
||||||
}
|
}
|
||||||
} else if (strcasecmp("dock", mode) == 0) {
|
} else if (strcasecmp("dock", mode) == 0) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <libevdev/libevdev.h>
|
#include <libevdev/libevdev.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
|
||||||
#include <xkbcommon/xkbcommon-names.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <xkbcommon/xkbcommon-names.h>
|
||||||
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/input/cursor.h"
|
#include "sway/input/cursor.h"
|
||||||
|
|
@ -330,7 +331,20 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) {
|
||||||
void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
|
void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
|
||||||
sway_log(SWAY_DEBUG, "running command for binding: %s", binding->command);
|
sway_log(SWAY_DEBUG, "running command for binding: %s", binding->command);
|
||||||
|
|
||||||
list_t *res_list = execute_command(binding->command, seat, NULL);
|
struct sway_container *con = NULL;
|
||||||
|
if (binding->type == BINDING_MOUSESYM
|
||||||
|
|| binding->type == BINDING_MOUSECODE) {
|
||||||
|
struct wlr_surface *surface = NULL;
|
||||||
|
double sx, sy;
|
||||||
|
struct sway_node *node = node_at_coords(seat,
|
||||||
|
seat->cursor->cursor->x, seat->cursor->cursor->y,
|
||||||
|
&surface, &sx, &sy);
|
||||||
|
if (node && node->type == N_CONTAINER) {
|
||||||
|
con = node->sway_container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_t *res_list = execute_command(binding->command, seat, con);
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (int i = 0; i < res_list->length; ++i) {
|
for (int i = 0; i < res_list->length; ++i) {
|
||||||
struct cmd_results *results = res_list->items[i];
|
struct cmd_results *results = res_list->items[i];
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ static struct sway_node *get_node_in_output_direction(
|
||||||
struct sway_output *output, enum wlr_direction dir) {
|
struct sway_output *output, enum wlr_direction dir) {
|
||||||
struct sway_seat *seat = config->handler_context.seat;
|
struct sway_seat *seat = config->handler_context.seat;
|
||||||
struct sway_workspace *ws = output_get_active_workspace(output);
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||||
|
if (!sway_assert(ws, "Expected output to have a workspace")) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (ws->fullscreen) {
|
if (ws->fullscreen) {
|
||||||
return seat_get_focus_inactive(seat, &ws->fullscreen->node);
|
return seat_get_focus_inactive(seat, &ws->fullscreen->node);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,10 +111,8 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
|
||||||
"Unable to change layout of floating windows");
|
"Unable to change layout of floating windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Typically we change the layout of the current container, but if the
|
// Operate on parent container, like i3.
|
||||||
// current container is a view (it usually is) then we'll change the layout
|
if (container) {
|
||||||
// of the parent instead, as it doesn't make sense for views to have layout.
|
|
||||||
if (container && container->view) {
|
|
||||||
container = container->parent;
|
container = container->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,9 @@ static bool container_move_in_direction(struct sway_container *container,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
struct sway_workspace *ws = output_get_active_workspace(new_output);
|
struct sway_workspace *ws = output_get_active_workspace(new_output);
|
||||||
|
if (!sway_assert(ws, "Expected output to have a workspace")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
container_move_to_workspace(container, ws);
|
container_move_to_workspace(container, ws);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -360,6 +363,9 @@ static bool container_move_in_direction(struct sway_container *container,
|
||||||
output_get_in_direction(container->workspace->output, move_dir);
|
output_get_in_direction(container->workspace->output, move_dir);
|
||||||
if (output) {
|
if (output) {
|
||||||
struct sway_workspace *ws = output_get_active_workspace(output);
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||||
|
if (!sway_assert(ws, "Expected output to have a workspace")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
container_move_to_workspace_from_direction(container, ws, move_dir);
|
container_move_to_workspace_from_direction(container, ws, move_dir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -516,7 +522,6 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
|
||||||
|
|
||||||
// move container
|
// move container
|
||||||
if (container->scratchpad) {
|
if (container->scratchpad) {
|
||||||
root_scratchpad_remove_container(container);
|
|
||||||
root_scratchpad_show(container);
|
root_scratchpad_show(container);
|
||||||
}
|
}
|
||||||
switch (destination->type) {
|
switch (destination->type) {
|
||||||
|
|
@ -526,6 +531,10 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
|
||||||
case N_OUTPUT: {
|
case N_OUTPUT: {
|
||||||
struct sway_output *output = destination->sway_output;
|
struct sway_output *output = destination->sway_output;
|
||||||
struct sway_workspace *ws = output_get_active_workspace(output);
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||||
|
if (!sway_assert(ws, "Expected output to have a workspace")) {
|
||||||
|
return cmd_results_new(CMD_FAILURE,
|
||||||
|
"Expected output to have a workspace");
|
||||||
|
}
|
||||||
container_move_to_workspace(container, ws);
|
container_move_to_workspace(container, ws);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -539,6 +548,10 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
|
||||||
// restore focus on destination output back to its last active workspace
|
// restore focus on destination output back to its last active workspace
|
||||||
struct sway_workspace *new_workspace =
|
struct sway_workspace *new_workspace =
|
||||||
output_get_active_workspace(new_output);
|
output_get_active_workspace(new_output);
|
||||||
|
if (!sway_assert(new_workspace, "Expected output to have a workspace")) {
|
||||||
|
return cmd_results_new(CMD_FAILURE,
|
||||||
|
"Expected output to have a workspace");
|
||||||
|
}
|
||||||
if (new_output_last_ws && new_output_last_ws != new_workspace) {
|
if (new_output_last_ws && new_output_last_ws != new_workspace) {
|
||||||
struct sway_node *new_output_last_focus =
|
struct sway_node *new_output_last_focus =
|
||||||
seat_get_focus_inactive(seat, &new_output_last_ws->node);
|
seat_get_focus_inactive(seat, &new_output_last_ws->node);
|
||||||
|
|
@ -586,6 +599,9 @@ static void workspace_move_to_output(struct sway_workspace *workspace,
|
||||||
workspace_detach(workspace);
|
workspace_detach(workspace);
|
||||||
struct sway_workspace *new_output_old_ws =
|
struct sway_workspace *new_output_old_ws =
|
||||||
output_get_active_workspace(output);
|
output_get_active_workspace(output);
|
||||||
|
if (!sway_assert(new_output_old_ws, "Expected output to have a workspace")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
output_add_workspace(output, workspace);
|
output_add_workspace(output, workspace);
|
||||||
|
|
||||||
|
|
@ -838,11 +854,11 @@ static struct cmd_results *cmd_move_to_scratchpad(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (con->scratchpad) {
|
if (!con->scratchpad) {
|
||||||
return cmd_results_new(CMD_INVALID,
|
root_scratchpad_add_container(con);
|
||||||
"Container is already in the scratchpad");
|
} else if (con->workspace) {
|
||||||
|
root_scratchpad_hide(con);
|
||||||
}
|
}
|
||||||
root_scratchpad_add_container(con);
|
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,5 +50,5 @@ struct cmd_results *cmd_seat(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
config->handler_context.seat_config = NULL;
|
config->handler_context.seat_config = NULL;
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return res ? res : cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor,
|
||||||
|
|
||||||
static const char expected_syntax[] = "Expected 'cursor <move> <x> <y>' or "
|
static const char expected_syntax[] = "Expected 'cursor <move> <x> <y>' or "
|
||||||
"'cursor <set> <x> <y>' or "
|
"'cursor <set> <x> <y>' or "
|
||||||
"'curor <press|release> <button[1-9]|event-name-or-code>'";
|
"'cursor <press|release> <button[1-9]|event-name-or-code>'";
|
||||||
|
|
||||||
static struct cmd_results *handle_command(struct sway_cursor *cursor,
|
static struct cmd_results *handle_command(struct sway_cursor *cursor,
|
||||||
int argc, char **argv) {
|
int argc, char **argv) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "sway/tree/view.h"
|
#include "sway/tree/view.h"
|
||||||
#include "sway/tree/workspace.h"
|
#include "sway/tree/workspace.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
struct cmd_results *cmd_sticky(int argc, char **argv) {
|
struct cmd_results *cmd_sticky(int argc, char **argv) {
|
||||||
|
|
@ -29,6 +30,11 @@ struct cmd_results *cmd_sticky(int argc, char **argv) {
|
||||||
// move container to active workspace
|
// move container to active workspace
|
||||||
struct sway_workspace *active_workspace =
|
struct sway_workspace *active_workspace =
|
||||||
output_get_active_workspace(container->workspace->output);
|
output_get_active_workspace(container->workspace->output);
|
||||||
|
if (!sway_assert(active_workspace,
|
||||||
|
"Expected output to have a workspace")) {
|
||||||
|
return cmd_results_new(CMD_FAILURE,
|
||||||
|
"Expected output to have a workspace");
|
||||||
|
}
|
||||||
if (container->workspace != active_workspace) {
|
if (container->workspace != active_workspace) {
|
||||||
struct sway_workspace *old_workspace = container->workspace;
|
struct sway_workspace *old_workspace = container->workspace;
|
||||||
container_detach(container);
|
container_detach(container);
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,10 @@ static void container_swap(struct sway_container *con1,
|
||||||
output_get_active_workspace(con1->workspace->output);
|
output_get_active_workspace(con1->workspace->output);
|
||||||
struct sway_workspace *vis2 =
|
struct sway_workspace *vis2 =
|
||||||
output_get_active_workspace(con2->workspace->output);
|
output_get_active_workspace(con2->workspace->output);
|
||||||
|
if (!sway_assert(vis1 && vis2, "con1 or con2 are on an output without a"
|
||||||
|
"workspace. This should not happen")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char *stored_prev_name = NULL;
|
char *stored_prev_name = NULL;
|
||||||
if (seat->prev_workspace_name) {
|
if (seat->prev_workspace_name) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,12 @@ struct cmd_results *cmd_titlebar_border_thickness(int argc, char **argv) {
|
||||||
|
|
||||||
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];
|
||||||
arrange_workspace(output_get_active_workspace(output));
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||||
|
if (!sway_assert(ws, "Expected output to have a workspace")) {
|
||||||
|
return cmd_results_new(CMD_FAILURE,
|
||||||
|
"Expected output to have a workspace");
|
||||||
|
}
|
||||||
|
arrange_workspace(ws);
|
||||||
output_damage_whole(output);
|
output_damage_whole(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,9 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
|
||||||
++argv;
|
++argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool create = argc > 1 && strcasecmp(argv[1], "--create") == 0;
|
||||||
|
struct sway_seat *seat = config->handler_context.seat;
|
||||||
|
struct sway_workspace *current = seat_get_focused_workspace(seat);
|
||||||
struct sway_workspace *ws = NULL;
|
struct sway_workspace *ws = NULL;
|
||||||
if (strcasecmp(argv[0], "number") == 0) {
|
if (strcasecmp(argv[0], "number") == 0) {
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
|
@ -199,12 +201,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(argv[0], "next") == 0 ||
|
} else if (strcasecmp(argv[0], "next") == 0 ||
|
||||||
strcasecmp(argv[0], "prev") == 0 ||
|
strcasecmp(argv[0], "prev") == 0 ||
|
||||||
strcasecmp(argv[0], "next_on_output") == 0 ||
|
|
||||||
strcasecmp(argv[0], "prev_on_output") == 0 ||
|
|
||||||
strcasecmp(argv[0], "current") == 0) {
|
strcasecmp(argv[0], "current") == 0) {
|
||||||
ws = workspace_by_name(argv[0]);
|
ws = workspace_by_name(argv[0]);
|
||||||
|
} else if (strcasecmp(argv[0], "next_on_output") == 0) {
|
||||||
|
ws = workspace_output_next(current, create);
|
||||||
|
} else if (strcasecmp(argv[0], "prev_on_output") == 0) {
|
||||||
|
ws = workspace_output_prev(current, create);
|
||||||
} else if (strcasecmp(argv[0], "back_and_forth") == 0) {
|
} else if (strcasecmp(argv[0], "back_and_forth") == 0) {
|
||||||
struct sway_seat *seat = config->handler_context.seat;
|
|
||||||
if (!seat->prev_workspace_name) {
|
if (!seat->prev_workspace_name) {
|
||||||
return cmd_results_new(CMD_INVALID,
|
return cmd_results_new(CMD_INVALID,
|
||||||
"There is no previous workspace");
|
"There is no previous workspace");
|
||||||
|
|
@ -220,7 +223,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
workspace_switch(ws, no_auto_back_and_forth);
|
workspace_switch(ws, no_auto_back_and_forth);
|
||||||
seat_consider_warp_to_focus(config->handler_context.seat);
|
seat_consider_warp_to_focus(seat);
|
||||||
}
|
}
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ void free_config(struct sway_config *config) {
|
||||||
}
|
}
|
||||||
list_free(config->no_focus);
|
list_free(config->no_focus);
|
||||||
list_free(config->active_bar_modifiers);
|
list_free(config->active_bar_modifiers);
|
||||||
list_free(config->config_chain);
|
list_free_items_and_destroy(config->config_chain);
|
||||||
list_free(config->command_policies);
|
list_free(config->command_policies);
|
||||||
list_free(config->feature_policies);
|
list_free(config->feature_policies);
|
||||||
list_free(config->ipc_policies);
|
list_free(config->ipc_policies);
|
||||||
|
|
@ -471,9 +471,8 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_active) {
|
if (is_active) {
|
||||||
for (int i = 0; i < config->output_configs->length; i++) {
|
reset_outputs();
|
||||||
apply_output_config_to_outputs(config->output_configs->items[i]);
|
|
||||||
}
|
|
||||||
config->reloading = false;
|
config->reloading = false;
|
||||||
if (config->swaynag_config_errors.pid > 0) {
|
if (config->swaynag_config_errors.pid > 0) {
|
||||||
swaynag_show(&config->swaynag_config_errors);
|
swaynag_show(&config->swaynag_config_errors);
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ void free_bar_config(struct bar_config *bar) {
|
||||||
free(bar->position);
|
free(bar->position);
|
||||||
free(bar->hidden_state);
|
free(bar->hidden_state);
|
||||||
free(bar->status_command);
|
free(bar->status_command);
|
||||||
|
free(bar->swaybar_command);
|
||||||
free(bar->font);
|
free(bar->font);
|
||||||
free(bar->separator_symbol);
|
free(bar->separator_symbol);
|
||||||
for (int i = 0; i < bar->bindings->length; i++) {
|
for (int i = 0; i < bar->bindings->length; i++) {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
|
#include <wlr/types/wlr_output.h>
|
||||||
|
#include "log.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/output.h"
|
#include "sway/output.h"
|
||||||
#include "sway/tree/root.h"
|
#include "sway/tree/root.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
int output_name_cmp(const void *item, const void *data) {
|
int output_name_cmp(const void *item, const void *data) {
|
||||||
const struct output_config *output = item;
|
const struct output_config *output = item;
|
||||||
|
|
@ -165,14 +166,89 @@ static bool set_mode(struct wlr_output *output, int width, int height,
|
||||||
return wlr_output_set_mode(output, best);
|
return wlr_output_set_mode(output, best);
|
||||||
}
|
}
|
||||||
|
|
||||||
void terminate_swaybg(pid_t pid) {
|
static void handle_swaybg_client_destroy(struct wl_listener *listener,
|
||||||
int ret = kill(pid, SIGTERM);
|
void *data) {
|
||||||
if (ret != 0) {
|
struct sway_output *output =
|
||||||
sway_log(SWAY_ERROR, "Unable to terminate swaybg [pid: %d]", pid);
|
wl_container_of(listener, output, swaybg_client_destroy);
|
||||||
} else {
|
wl_list_remove(&output->swaybg_client_destroy.link);
|
||||||
int status;
|
wl_list_init(&output->swaybg_client_destroy.link);
|
||||||
waitpid(pid, &status, 0);
|
output->swaybg_client = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool set_cloexec(int fd, bool cloexec) {
|
||||||
|
int flags = fcntl(fd, F_GETFD);
|
||||||
|
if (flags == -1) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "fcntl failed");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
if (cloexec) {
|
||||||
|
flags = flags | FD_CLOEXEC;
|
||||||
|
} else {
|
||||||
|
flags = flags & ~FD_CLOEXEC;
|
||||||
|
}
|
||||||
|
if (fcntl(fd, F_SETFD, flags) == -1) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "fcntl failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool spawn_swaybg(struct sway_output *output, char *const cmd[]) {
|
||||||
|
int sockets[2];
|
||||||
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) != 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "socketpair failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!set_cloexec(sockets[0], true) || !set_cloexec(sockets[1], true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->swaybg_client = wl_client_create(server.wl_display, sockets[0]);
|
||||||
|
if (output->swaybg_client == NULL) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "wl_client_create failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->swaybg_client_destroy.notify = handle_swaybg_client_destroy;
|
||||||
|
wl_client_add_destroy_listener(output->swaybg_client,
|
||||||
|
&output->swaybg_client_destroy);
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "fork failed");
|
||||||
|
return false;
|
||||||
|
} else if (pid == 0) {
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "fork failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else if (pid == 0) {
|
||||||
|
if (!set_cloexec(sockets[1], false)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char wayland_socket_str[16];
|
||||||
|
snprintf(wayland_socket_str, sizeof(wayland_socket_str),
|
||||||
|
"%d", sockets[1]);
|
||||||
|
setenv("WAYLAND_SOCKET", wayland_socket_str, true);
|
||||||
|
|
||||||
|
execvp(cmd[0], cmd);
|
||||||
|
sway_log_errno(SWAY_ERROR, "execvp failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close(sockets[1]) != 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "close failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (waitpid(pid, NULL, 0) < 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "waitpid failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
|
|
@ -199,6 +275,11 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oc && oc->dpms_state == DPMS_ON) {
|
||||||
|
sway_log(SWAY_DEBUG, "Turning on screen");
|
||||||
|
wlr_output_enable(wlr_output, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool modeset_success;
|
bool modeset_success;
|
||||||
if (oc && oc->width > 0 && oc->height > 0) {
|
if (oc && oc->width > 0 && oc->height > 0) {
|
||||||
sway_log(SWAY_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width,
|
sway_log(SWAY_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width,
|
||||||
|
|
@ -238,8 +319,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
wlr_output_layout_add_auto(root->output_layout, wlr_output);
|
wlr_output_layout_add_auto(root->output_layout, wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->bg_pid != 0) {
|
if (output->swaybg_client != NULL) {
|
||||||
terminate_swaybg(output->bg_pid);
|
wl_client_destroy(output->swaybg_client);
|
||||||
}
|
}
|
||||||
if (oc && oc->background && config->swaybg_command) {
|
if (oc && oc->background && config->swaybg_command) {
|
||||||
sway_log(SWAY_DEBUG, "Setting background for output %s to %s",
|
sway_log(SWAY_DEBUG, "Setting background for output %s to %s",
|
||||||
|
|
@ -253,29 +334,14 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
oc->background_fallback ? oc->background_fallback : NULL,
|
oc->background_fallback ? oc->background_fallback : NULL,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
if (!spawn_swaybg(output, cmd)) {
|
||||||
output->bg_pid = fork();
|
return false;
|
||||||
if (output->bg_pid < 0) {
|
|
||||||
sway_log_errno(SWAY_ERROR, "fork failed");
|
|
||||||
} else if (output->bg_pid == 0) {
|
|
||||||
execvp(cmd[0], cmd);
|
|
||||||
sway_log_errno(SWAY_ERROR, "Failed to execute swaybg");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oc) {
|
if (oc && oc->dpms_state == DPMS_OFF) {
|
||||||
switch (oc->dpms_state) {
|
sway_log(SWAY_DEBUG, "Turning off screen");
|
||||||
case DPMS_ON:
|
wlr_output_enable(wlr_output, false);
|
||||||
sway_log(SWAY_DEBUG, "Turning on screen");
|
|
||||||
wlr_output_enable(wlr_output, true);
|
|
||||||
break;
|
|
||||||
case DPMS_OFF:
|
|
||||||
sway_log(SWAY_DEBUG, "Turning off screen");
|
|
||||||
wlr_output_enable(wlr_output, false);
|
|
||||||
break;
|
|
||||||
case DPMS_IGNORE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -294,6 +360,7 @@ static void default_output_config(struct output_config *oc,
|
||||||
oc->x = oc->y = -1;
|
oc->x = oc->y = -1;
|
||||||
oc->scale = 1;
|
oc->scale = 1;
|
||||||
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
oc->dpms_state = DPMS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct output_config *get_output_config(char *identifier,
|
static struct output_config *get_output_config(char *identifier,
|
||||||
|
|
@ -395,6 +462,17 @@ void apply_output_config_to_outputs(struct output_config *oc) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_outputs(void) {
|
||||||
|
struct output_config *oc = NULL;
|
||||||
|
int i = list_seq_find(config->output_configs, output_name_cmp, "*");
|
||||||
|
if (i >= 0) {
|
||||||
|
oc = config->output_configs->items[i];
|
||||||
|
} else {
|
||||||
|
oc = store_output_config(new_output_config("*"));
|
||||||
|
}
|
||||||
|
apply_output_config_to_outputs(oc);
|
||||||
|
}
|
||||||
|
|
||||||
void free_output_config(struct output_config *oc) {
|
void free_output_config(struct output_config *oc) {
|
||||||
if (!oc) {
|
if (!oc) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||||
#include <wlr/types/wlr_output_damage.h>
|
#include <wlr/types/wlr_output_damage.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
#include "log.h"
|
||||||
#include "sway/desktop/transaction.h"
|
#include "sway/desktop/transaction.h"
|
||||||
|
#include "sway/input/cursor.h"
|
||||||
#include "sway/input/input-manager.h"
|
#include "sway/input/input-manager.h"
|
||||||
#include "sway/input/seat.h"
|
#include "sway/input/seat.h"
|
||||||
#include "sway/layers.h"
|
#include "sway/layers.h"
|
||||||
|
|
@ -14,7 +16,6 @@
|
||||||
#include "sway/server.h"
|
#include "sway/server.h"
|
||||||
#include "sway/tree/arrange.h"
|
#include "sway/tree/arrange.h"
|
||||||
#include "sway/tree/workspace.h"
|
#include "sway/tree/workspace.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
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,
|
||||||
|
|
@ -302,6 +303,8 @@ static void unmap(struct sway_layer_surface *sway_layer) {
|
||||||
if (seat->focused_layer == sway_layer->layer_surface) {
|
if (seat->focused_layer == sway_layer->layer_surface) {
|
||||||
seat_set_focus_layer(seat, NULL);
|
seat_set_focus_layer(seat, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor_rebase_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_destroy(struct wl_listener *listener, void *data) {
|
static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -321,7 +324,6 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = sway_layer->layer_surface->output->data;
|
struct sway_output *output = sway_layer->layer_surface->output->data;
|
||||||
if (output != NULL) {
|
if (output != NULL) {
|
||||||
arrange_layers(output);
|
arrange_layers(output);
|
||||||
arrange_output(output);
|
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
}
|
}
|
||||||
wl_list_remove(&sway_layer->output_destroy.link);
|
wl_list_remove(&sway_layer->output_destroy.link);
|
||||||
|
|
@ -339,6 +341,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
// TODO: send enter to subsurfaces and popups
|
// TODO: send enter to subsurfaces and popups
|
||||||
wlr_surface_send_enter(sway_layer->layer_surface->surface,
|
wlr_surface_send_enter(sway_layer->layer_surface->surface,
|
||||||
sway_layer->layer_surface->output);
|
sway_layer->layer_surface->output);
|
||||||
|
cursor_rebase_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_unmap(struct wl_listener *listener, void *data) {
|
static void handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,9 @@ static void output_for_each_surface(struct sway_output *output,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_workspace *workspace = output_get_active_workspace(output);
|
struct sway_workspace *workspace = output_get_active_workspace(output);
|
||||||
|
if (!workspace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
struct sway_container *fullscreen_con = root->fullscreen_global;
|
struct sway_container *fullscreen_con = root->fullscreen_global;
|
||||||
if (fullscreen_con && container_is_scratchpad_hidden(fullscreen_con)) {
|
if (fullscreen_con && container_is_scratchpad_hidden(fullscreen_con)) {
|
||||||
fullscreen_con = NULL;
|
fullscreen_con = NULL;
|
||||||
|
|
@ -320,6 +323,9 @@ struct sway_workspace *output_get_active_workspace(struct sway_output *output) {
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
struct sway_node *focus = seat_get_active_tiling_child(seat, &output->node);
|
struct sway_node *focus = seat_get_active_tiling_child(seat, &output->node);
|
||||||
if (!focus) {
|
if (!focus) {
|
||||||
|
if (!output->workspaces->length) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return output->workspaces->items[0];
|
return output->workspaces->items[0];
|
||||||
}
|
}
|
||||||
return focus->sway_workspace;
|
return focus->sway_workspace;
|
||||||
|
|
@ -506,6 +512,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&output->present.link);
|
wl_list_remove(&output->present.link);
|
||||||
wl_list_remove(&output->damage_destroy.link);
|
wl_list_remove(&output->damage_destroy.link);
|
||||||
wl_list_remove(&output->damage_frame.link);
|
wl_list_remove(&output->damage_frame.link);
|
||||||
|
wl_list_remove(&output->swaybg_client_destroy.link);
|
||||||
|
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
}
|
}
|
||||||
|
|
@ -612,6 +619,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
||||||
output->damage_frame.notify = damage_handle_frame;
|
output->damage_frame.notify = damage_handle_frame;
|
||||||
wl_signal_add(&output->damage->events.destroy, &output->damage_destroy);
|
wl_signal_add(&output->damage->events.destroy, &output->damage_destroy);
|
||||||
output->damage_destroy.notify = damage_handle_destroy;
|
output->damage_destroy.notify = damage_handle_destroy;
|
||||||
|
wl_list_init(&output->swaybg_client_destroy.link);
|
||||||
|
|
||||||
struct output_config *oc = output_find_config(output);
|
struct output_config *oc = output_find_config(output);
|
||||||
if (!oc || oc->enabled) {
|
if (!oc || oc->enabled) {
|
||||||
|
|
|
||||||
|
|
@ -314,14 +314,7 @@ static void transaction_apply(struct sway_transaction *transaction) {
|
||||||
node->instruction = NULL;
|
node->instruction = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root->outputs->length) {
|
cursor_rebase_all();
|
||||||
struct sway_seat *seat;
|
|
||||||
wl_list_for_each(seat, &server.input->seats, link) {
|
|
||||||
if (!seat_doing_seatop(seat)) {
|
|
||||||
cursor_rebase(seat->cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transaction_commit(struct sway_transaction *transaction);
|
static void transaction_commit(struct sway_transaction *transaction);
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,9 @@ struct sway_node *node_at_coords(
|
||||||
|
|
||||||
// find the focused workspace on the output for this seat
|
// find the focused workspace on the output for this seat
|
||||||
struct sway_workspace *ws = output_get_active_workspace(output);
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||||
|
if (!ws) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*surface = layer_surface_at(output,
|
if ((*surface = layer_surface_at(output,
|
||||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
||||||
|
|
@ -283,6 +286,19 @@ void cursor_rebase(struct sway_cursor *cursor) {
|
||||||
cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy);
|
cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cursor_rebase_all(void) {
|
||||||
|
if (!root->outputs->length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_seat *seat;
|
||||||
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
if (!seat_doing_seatop(seat)) {
|
||||||
|
cursor_rebase(seat->cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int hide_notify(void *data) {
|
static int hide_notify(void *data) {
|
||||||
struct sway_cursor *cursor = data;
|
struct sway_cursor *cursor = data;
|
||||||
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
@ -408,15 +424,16 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
wlr_relative_pointer_manager_v1_send_relative_motion(
|
wlr_relative_pointer_manager_v1_send_relative_motion(
|
||||||
server.relative_pointer_manager,
|
server.relative_pointer_manager,
|
||||||
cursor->seat->wlr_seat, event->time_msec, dx, dy,
|
cursor->seat->wlr_seat, (uint64_t)event->time_msec * 1000,
|
||||||
dx_unaccel, dy_unaccel);
|
dx, dy, dx_unaccel, dy_unaccel);
|
||||||
|
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
|
struct sway_node *node = NULL;
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
struct sway_node *node = node_at_coords(cursor->seat,
|
|
||||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
||||||
|
|
||||||
if (cursor->active_constraint) {
|
if (cursor->active_constraint) {
|
||||||
|
node = node_at_coords(cursor->seat,
|
||||||
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||||
|
|
||||||
if (cursor->active_constraint->surface != surface) {
|
if (cursor->active_constraint->surface != surface) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -432,8 +449,13 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_cursor_move(cursor->cursor, event->device, dx, dy);
|
wlr_cursor_move(cursor->cursor, event->device, dx, dy);
|
||||||
|
|
||||||
|
// Recalculate pointer location after layout checks
|
||||||
|
node = node_at_coords(cursor->seat,
|
||||||
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||||
|
|
||||||
cursor_send_pointer_motion(cursor, event->time_msec, node, surface,
|
cursor_send_pointer_motion(cursor, event->time_msec, node, surface,
|
||||||
sx + dx, sy + dy);
|
sx, sy);
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -530,10 +552,11 @@ static void state_add_button(struct sway_cursor *cursor, uint32_t button) {
|
||||||
static struct sway_binding* get_active_mouse_binding(
|
static struct sway_binding* get_active_mouse_binding(
|
||||||
const struct sway_cursor *cursor, list_t *bindings, uint32_t modifiers,
|
const struct sway_cursor *cursor, list_t *bindings, uint32_t modifiers,
|
||||||
bool release, bool on_titlebar, bool on_border, bool on_content,
|
bool release, bool on_titlebar, bool on_border, bool on_content,
|
||||||
const char *identifier) {
|
bool on_workspace, const char *identifier) {
|
||||||
uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) |
|
uint32_t click_region =
|
||||||
(on_border ? BINDING_BORDER : 0) |
|
((on_titlebar || on_workspace) ? BINDING_TITLEBAR : 0) |
|
||||||
(on_content ? BINDING_CONTENTS : 0);
|
((on_border || on_workspace) ? BINDING_BORDER : 0) |
|
||||||
|
((on_content || on_workspace) ? BINDING_CONTENTS : 0);
|
||||||
|
|
||||||
struct sway_binding *current = NULL;
|
struct sway_binding *current = NULL;
|
||||||
for (int i = 0; i < bindings->length; ++i) {
|
for (int i = 0; i < bindings->length; ++i) {
|
||||||
|
|
@ -542,6 +565,8 @@ static struct sway_binding* get_active_mouse_binding(
|
||||||
cursor->pressed_button_count != (size_t)binding->keys->length ||
|
cursor->pressed_button_count != (size_t)binding->keys->length ||
|
||||||
release != (binding->flags & BINDING_RELEASE) ||
|
release != (binding->flags & BINDING_RELEASE) ||
|
||||||
!(click_region & binding->flags) ||
|
!(click_region & binding->flags) ||
|
||||||
|
(on_workspace &&
|
||||||
|
(click_region & binding->flags) != click_region) ||
|
||||||
(strcmp(binding->input, identifier) != 0 &&
|
(strcmp(binding->input, identifier) != 0 &&
|
||||||
strcmp(binding->input, "*") != 0)) {
|
strcmp(binding->input, "*") != 0)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -607,6 +632,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
|
||||||
find_resize_edge(cont, cursor) : WLR_EDGE_NONE;
|
find_resize_edge(cont, cursor) : WLR_EDGE_NONE;
|
||||||
bool on_border = edge != WLR_EDGE_NONE;
|
bool on_border = edge != WLR_EDGE_NONE;
|
||||||
bool on_contents = cont && !on_border && surface;
|
bool on_contents = cont && !on_border && surface;
|
||||||
|
bool on_workspace = node && node->type == N_WORKSPACE;
|
||||||
bool on_titlebar = cont && !on_border && !surface;
|
bool on_titlebar = cont && !on_border && !surface;
|
||||||
|
|
||||||
// Handle mouse bindings
|
// Handle mouse bindings
|
||||||
|
|
@ -620,11 +646,13 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
|
||||||
state_add_button(cursor, button);
|
state_add_button(cursor, button);
|
||||||
binding = get_active_mouse_binding(cursor,
|
binding = get_active_mouse_binding(cursor,
|
||||||
config->current_mode->mouse_bindings, modifiers, false,
|
config->current_mode->mouse_bindings, modifiers, false,
|
||||||
on_titlebar, on_border, on_contents, device_identifier);
|
on_titlebar, on_border, on_contents, on_workspace,
|
||||||
|
device_identifier);
|
||||||
} else {
|
} else {
|
||||||
binding = get_active_mouse_binding(cursor,
|
binding = get_active_mouse_binding(cursor,
|
||||||
config->current_mode->mouse_bindings, modifiers, true,
|
config->current_mode->mouse_bindings, modifiers, true,
|
||||||
on_titlebar, on_border, on_contents, device_identifier);
|
on_titlebar, on_border, on_contents, on_workspace,
|
||||||
|
device_identifier);
|
||||||
state_erase_button(cursor, button);
|
state_erase_button(cursor, button);
|
||||||
}
|
}
|
||||||
free(device_identifier);
|
free(device_identifier);
|
||||||
|
|
@ -814,6 +842,7 @@ void dispatch_cursor_axis(struct sway_cursor *cursor,
|
||||||
bool on_titlebar_border = cont && on_border &&
|
bool on_titlebar_border = cont && on_border &&
|
||||||
cursor->cursor->y < cont->content_y;
|
cursor->cursor->y < cont->content_y;
|
||||||
bool on_contents = cont && !on_border && surface;
|
bool on_contents = cont && !on_border && surface;
|
||||||
|
bool on_workspace = node && node->type == N_WORKSPACE;
|
||||||
float scroll_factor =
|
float scroll_factor =
|
||||||
(ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor;
|
(ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor;
|
||||||
|
|
||||||
|
|
@ -832,7 +861,7 @@ void dispatch_cursor_axis(struct sway_cursor *cursor,
|
||||||
state_add_button(cursor, button);
|
state_add_button(cursor, button);
|
||||||
binding = get_active_mouse_binding(cursor,
|
binding = get_active_mouse_binding(cursor,
|
||||||
config->current_mode->mouse_bindings, modifiers, false,
|
config->current_mode->mouse_bindings, modifiers, false,
|
||||||
on_titlebar, on_border, on_contents, dev_id);
|
on_titlebar, on_border, on_contents, on_workspace, dev_id);
|
||||||
if (binding) {
|
if (binding) {
|
||||||
seat_execute_command(seat, binding);
|
seat_execute_command(seat, binding);
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
@ -873,7 +902,7 @@ void dispatch_cursor_axis(struct sway_cursor *cursor,
|
||||||
// Handle mouse bindings - x11 mouse buttons 4-7 - release event
|
// Handle mouse bindings - x11 mouse buttons 4-7 - release event
|
||||||
binding = get_active_mouse_binding(cursor,
|
binding = get_active_mouse_binding(cursor,
|
||||||
config->current_mode->mouse_bindings, modifiers, true,
|
config->current_mode->mouse_bindings, modifiers, true,
|
||||||
on_titlebar, on_border, on_contents, dev_id);
|
on_titlebar, on_border, on_contents, on_workspace, dev_id);
|
||||||
state_erase_button(cursor, button);
|
state_erase_button(cursor, button);
|
||||||
if (binding) {
|
if (binding) {
|
||||||
seat_execute_command(seat, binding);
|
seat_execute_command(seat, binding);
|
||||||
|
|
|
||||||
|
|
@ -549,13 +549,17 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
||||||
wlr_keyboard_led_update(wlr_device->keyboard, leds);
|
wlr_keyboard_led_update(wlr_device->keyboard, leds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_config && input_config->repeat_delay != INT_MIN
|
int repeat_rate = 25;
|
||||||
&& input_config->repeat_rate != INT_MIN) {
|
if (input_config && input_config->repeat_rate != INT_MIN) {
|
||||||
wlr_keyboard_set_repeat_info(wlr_device->keyboard,
|
repeat_rate = input_config->repeat_rate;
|
||||||
input_config->repeat_rate, input_config->repeat_delay);
|
|
||||||
} else {
|
|
||||||
wlr_keyboard_set_repeat_info(wlr_device->keyboard, 25, 600);
|
|
||||||
}
|
}
|
||||||
|
int repeat_delay = 600;
|
||||||
|
if (input_config && input_config->repeat_delay != INT_MIN) {
|
||||||
|
repeat_delay = input_config->repeat_delay;
|
||||||
|
}
|
||||||
|
wlr_keyboard_set_repeat_info(wlr_device->keyboard, repeat_rate,
|
||||||
|
repeat_delay);
|
||||||
|
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
|
struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
|
||||||
wlr_seat_set_keyboard(seat, wlr_device);
|
wlr_seat_set_keyboard(seat, wlr_device);
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,7 @@ static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&icon->link);
|
wl_list_remove(&icon->link);
|
||||||
wl_list_remove(&icon->surface_commit.link);
|
wl_list_remove(&icon->surface_commit.link);
|
||||||
wl_list_remove(&icon->unmap.link);
|
wl_list_remove(&icon->unmap.link);
|
||||||
|
wl_list_remove(&icon->map.link);
|
||||||
wl_list_remove(&icon->destroy.link);
|
wl_list_remove(&icon->destroy.link);
|
||||||
free(icon);
|
free(icon);
|
||||||
}
|
}
|
||||||
|
|
@ -725,6 +726,10 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) {
|
||||||
|
|
||||||
void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
|
void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
|
||||||
if (seat->focused_layer) {
|
if (seat->focused_layer) {
|
||||||
|
struct wlr_layer_surface_v1 *layer = seat->focused_layer;
|
||||||
|
seat_set_focus_layer(seat, NULL);
|
||||||
|
seat_set_focus(seat, node);
|
||||||
|
seat_set_focus_layer(seat, layer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,9 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
||||||
}
|
}
|
||||||
if (edge) {
|
if (edge) {
|
||||||
e->target_node = node_get_parent(&con->node);
|
e->target_node = node_get_parent(&con->node);
|
||||||
|
if (e->target_node == &e->con->node) {
|
||||||
|
e->target_node = node_get_parent(e->target_node);
|
||||||
|
}
|
||||||
e->target_edge = edge;
|
e->target_edge = edge;
|
||||||
node_get_box(e->target_node, &e->drop_box);
|
node_get_box(e->target_node, &e->drop_box);
|
||||||
resize_box(&e->drop_box, edge, DROP_LAYOUT_BORDER);
|
resize_box(&e->drop_box, edge, DROP_LAYOUT_BORDER);
|
||||||
|
|
@ -161,7 +164,8 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
||||||
|
|
||||||
// Use the hovered view - but we must be over the actual surface
|
// Use the hovered view - but we must be over the actual surface
|
||||||
con = node->sway_container;
|
con = node->sway_container;
|
||||||
if (!con->view->surface || node == &e->con->node) {
|
if (!con->view->surface || node == &e->con->node
|
||||||
|
|| node_has_ancestor(node, &e->con->node)) {
|
||||||
e->target_node = NULL;
|
e->target_node = NULL;
|
||||||
e->target_edge = WLR_EDGE_NONE;
|
e->target_edge = WLR_EDGE_NONE;
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,9 @@ static void ipc_json_describe_output(struct sway_output *output,
|
||||||
ipc_json_output_transform_description(wlr_output->transform)));
|
ipc_json_output_transform_description(wlr_output->transform)));
|
||||||
|
|
||||||
struct sway_workspace *ws = output_get_active_workspace(output);
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||||
|
if (!sway_assert(ws, "Expected output to have a workspace")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
json_object_object_add(object, "current_workspace",
|
json_object_object_add(object, "current_workspace",
|
||||||
json_object_new_string(ws->name));
|
json_object_new_string(ws->name));
|
||||||
|
|
||||||
|
|
@ -344,6 +347,9 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
||||||
json_object_object_add(object, "app_id",
|
json_object_object_add(object, "app_id",
|
||||||
app_id ? json_object_new_string(app_id) : NULL);
|
app_id ? json_object_new_string(app_id) : NULL);
|
||||||
|
|
||||||
|
bool visible = view_is_visible(c->view);
|
||||||
|
json_object_object_add(object, "visible", json_object_new_boolean(visible));
|
||||||
|
|
||||||
json_object *marks = json_object_new_array();
|
json_object *marks = json_object_new_array();
|
||||||
list_t *con_marks = c->marks;
|
list_t *con_marks = c->marks;
|
||||||
for (int i = 0; i < con_marks->length; ++i) {
|
for (int i = 0; i < con_marks->length; ++i) {
|
||||||
|
|
@ -597,7 +603,7 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
|
||||||
const char *layout =
|
const char *layout =
|
||||||
xkb_keymap_layout_get_name(keymap, layout_idx);
|
xkb_keymap_layout_get_name(keymap, layout_idx);
|
||||||
json_object_object_add(object, "xkb_active_layout_name",
|
json_object_object_add(object, "xkb_active_layout_name",
|
||||||
json_object_new_string(layout));
|
layout ? json_object_new_string(layout) : NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
sway/main.c
10
sway/main.c
|
|
@ -126,6 +126,7 @@ void run_as_ipc_client(char *command, char *socket_path) {
|
||||||
uint32_t len = strlen(command);
|
uint32_t len = strlen(command);
|
||||||
char *resp = ipc_single_command(socketfd, IPC_COMMAND, command, &len);
|
char *resp = ipc_single_command(socketfd, IPC_COMMAND, command, &len);
|
||||||
printf("%s\n", resp);
|
printf("%s\n", resp);
|
||||||
|
free(resp);
|
||||||
close(socketfd);
|
close(socketfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,6 +300,14 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since wayland requires XDG_RUNTIME_DIR to be set, abort with just the
|
||||||
|
// clear error message (when not running as an IPC client).
|
||||||
|
if (!getenv("XDG_RUNTIME_DIR") && optind == argc) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"XDG_RUNTIME_DIR is not set in the environment. Aborting.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// As the 'callback' function for wlr_log is equivalent to that for
|
// As the 'callback' function for wlr_log is equivalent to that for
|
||||||
// sway, we do not need to override it.
|
// sway, we do not need to override it.
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|
@ -339,6 +348,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
char *command = join_args(argv + optind, argc - optind);
|
char *command = join_args(argv + optind, argc - optind);
|
||||||
run_as_ipc_client(command, socket_path);
|
run_as_ipc_client(command, socket_path);
|
||||||
|
free(command);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,14 @@
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_data_control_v1.h>
|
#include <wlr/types/wlr_data_control_v1.h>
|
||||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||||
#include <wlr/types/wlr_gamma_control.h>
|
|
||||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||||
|
#include <wlr/types/wlr_gamma_control.h>
|
||||||
#include <wlr/types/wlr_gtk_primary_selection.h>
|
#include <wlr/types/wlr_gtk_primary_selection.h>
|
||||||
#include <wlr/types/wlr_idle.h>
|
#include <wlr/types/wlr_idle.h>
|
||||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||||
#include <wlr/types/wlr_relative_pointer_v1.h>
|
|
||||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||||
|
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||||
|
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||||
#include <wlr/types/wlr_screencopy_v1.h>
|
#include <wlr/types/wlr_screencopy_v1.h>
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
|
|
@ -122,6 +123,7 @@ bool server_init(struct sway_server *server) {
|
||||||
wlr_export_dmabuf_manager_v1_create(server->wl_display);
|
wlr_export_dmabuf_manager_v1_create(server->wl_display);
|
||||||
wlr_screencopy_manager_v1_create(server->wl_display);
|
wlr_screencopy_manager_v1_create(server->wl_display);
|
||||||
wlr_data_control_manager_v1_create(server->wl_display);
|
wlr_data_control_manager_v1_create(server->wl_display);
|
||||||
|
wlr_primary_selection_v1_device_manager_create(server->wl_display);
|
||||||
|
|
||||||
server->socket = wl_display_add_socket_auto(server->wl_display);
|
server->socket = wl_display_add_socket_auto(server->wl_display);
|
||||||
if (!server->socket) {
|
if (!server->socket) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@ sway-input - input configuration file and commands
|
||||||
|
|
||||||
Sway allows for configuration of devices within the sway configuration file.
|
Sway allows for configuration of devices within the sway configuration file.
|
||||||
To obtain a list of available device identifiers, run *swaymsg -t get_inputs*.
|
To obtain a list of available device identifiers, run *swaymsg -t get_inputs*.
|
||||||
|
Settings can also be applied to all input devices by using the wildcard, _\*_,
|
||||||
|
in place of _\<identifier\>_ in the commands below.
|
||||||
|
|
||||||
|
Tip: If the configuration settings do not appear to be taking effect, you could
|
||||||
|
try using _\*_ instead of _\<identifier\>_. If it works with the wildcard, try
|
||||||
|
using a different identifier from *swaymsg -t get_inputs* until you find the
|
||||||
|
correct input device.
|
||||||
|
|
||||||
# INPUT COMMANDS
|
# INPUT COMMANDS
|
||||||
|
|
||||||
|
|
@ -144,7 +151,13 @@ configured. While sway is running, _-_ (hyphen) can be used as an alias for the
|
||||||
current seat. Each seat has an independent keyboard focus and a separate cursor
|
current seat. Each seat has an independent keyboard focus and a separate cursor
|
||||||
that is controlled by the pointer devices of the seat. This is useful for
|
that is controlled by the pointer devices of the seat. This is useful for
|
||||||
multiple people using the desktop at the same time with their own devices (each
|
multiple people using the desktop at the same time with their own devices (each
|
||||||
sitting in their own "seat").
|
sitting in their own "seat"). The wildcard character, _\*_, can also be used in
|
||||||
|
place of _\<identifier\>_ to change settings for all seats.
|
||||||
|
|
||||||
|
Tip: If the configuration settings do not appear to be taking effect, you could
|
||||||
|
try using _\*_ instead of _\<identifier\>_. If it works with the wildcard, try
|
||||||
|
using a different identifier from *swaymsg -t get_seats* until you find the
|
||||||
|
correct seat.
|
||||||
|
|
||||||
*seat* <name> attach <input_identifier>
|
*seat* <name> attach <input_identifier>
|
||||||
Attach an input device to this seat by its input identifier. A special
|
Attach an input device to this seat by its input identifier. A special
|
||||||
|
|
|
||||||
|
|
@ -293,12 +293,13 @@ runtime.
|
||||||
overwrite a binding, swaynag will give you a warning. To silence this, use
|
overwrite a binding, swaynag will give you a warning. To silence this, use
|
||||||
the _--no-warn_ flag.
|
the _--no-warn_ flag.
|
||||||
|
|
||||||
Mouse buttons can either be specified in the form _button[1-9]_ or by using
|
Mouse bindings operate on the container under the cursor instead of the
|
||||||
the name of the event code (ex _BTN\_LEFT_ or _BTN\_RIGHT_). For the former
|
container that has focus. Mouse buttons can either be specified in the form
|
||||||
option, the buttons will be mapped to their values in X11 (1=left, 2=middle,
|
_button[1-9]_ or by using the name of the event code (ex _BTN\_LEFT_ or
|
||||||
3=right, 4=scroll up, 5=scroll down, 6=scroll left, 7=scroll right, 8=back,
|
_BTN\_RIGHT_). For the former option, the buttons will be mapped to their
|
||||||
9=forward). For the latter option, you can find the event names using
|
values in X11 (1=left, 2=middle, 3=right, 4=scroll up, 5=scroll down,
|
||||||
_libinput debug-events_.
|
6=scroll left, 7=scroll right, 8=back, 9=forward). For the latter option,
|
||||||
|
you can find the event names using _libinput debug-events_.
|
||||||
|
|
||||||
_--whole-window_, _--border_, and _--exclude-titlebar_ are mouse-only options
|
_--whole-window_, _--border_, and _--exclude-titlebar_ are mouse-only options
|
||||||
which affect the region in which the mouse bindings can be triggered. By
|
which affect the region in which the mouse bindings can be triggered. By
|
||||||
|
|
@ -309,9 +310,9 @@ runtime.
|
||||||
conjunction with any other option to specify that the titlebar should be
|
conjunction with any other option to specify that the titlebar should be
|
||||||
excluded from the region of consideration.
|
excluded from the region of consideration.
|
||||||
|
|
||||||
There is currently, however, no way to execute a mouse binding over a layer
|
If _--whole-window_ is given, the command can be triggered when the cursor
|
||||||
surface (which includes the background of an empty workspace). This behaviour
|
is over an empty workspace. Using a mouse binding over a layer surface's
|
||||||
is carried over from i3.
|
exclusive region is not currently possible.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```
|
||||||
|
|
@ -413,10 +414,6 @@ The default colors are:
|
||||||
: #0c0c0c
|
: #0c0c0c
|
||||||
|
|
||||||
|
|
||||||
*debuglog* on|off|toggle
|
|
||||||
Enables, disables or toggles debug logging. _toggle_ cannot be used in the
|
|
||||||
configuration file.
|
|
||||||
|
|
||||||
*default_border* normal|none|pixel [<n>]
|
*default_border* normal|none|pixel [<n>]
|
||||||
Set default border style for new tiled windows.
|
Set default border style for new tiled windows.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,10 +251,12 @@ static struct sway_container *container_at_stacked(struct sway_node *parent,
|
||||||
|
|
||||||
// Title bars
|
// Title bars
|
||||||
int title_height = container_titlebar_height();
|
int title_height = container_titlebar_height();
|
||||||
int child_index = (ly - box.y) / title_height;
|
if (title_height > 0) {
|
||||||
if (child_index < children->length) {
|
int child_index = (ly - box.y) / title_height;
|
||||||
struct sway_container *child = children->items[child_index];
|
if (child_index < children->length) {
|
||||||
return child;
|
struct sway_container *child = children->items[child_index];
|
||||||
|
return child;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Surfaces
|
// Surfaces
|
||||||
|
|
@ -829,7 +831,7 @@ void container_floating_move_to(struct sway_container *con,
|
||||||
}
|
}
|
||||||
struct sway_workspace *new_workspace =
|
struct sway_workspace *new_workspace =
|
||||||
output_get_active_workspace(new_output);
|
output_get_active_workspace(new_output);
|
||||||
if (old_workspace != new_workspace) {
|
if (new_workspace && old_workspace != new_workspace) {
|
||||||
container_detach(con);
|
container_detach(con);
|
||||||
workspace_add_floating(new_workspace, con);
|
workspace_add_floating(new_workspace, con);
|
||||||
arrange_workspace(old_workspace);
|
arrange_workspace(old_workspace);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
#include "sway/layers.h"
|
#include "sway/layers.h"
|
||||||
#include "sway/output.h"
|
#include "sway/output.h"
|
||||||
#include "sway/tree/arrange.h"
|
#include "sway/tree/arrange.h"
|
||||||
#include "sway/tree/output.h"
|
|
||||||
#include "sway/tree/workspace.h"
|
#include "sway/tree/workspace.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
@ -144,6 +143,9 @@ void output_enable(struct sway_output *output, struct output_config *oc) {
|
||||||
static void evacuate_sticky(struct sway_workspace *old_ws,
|
static void evacuate_sticky(struct sway_workspace *old_ws,
|
||||||
struct sway_output *new_output) {
|
struct sway_output *new_output) {
|
||||||
struct sway_workspace *new_ws = output_get_active_workspace(new_output);
|
struct sway_workspace *new_ws = output_get_active_workspace(new_output);
|
||||||
|
if (!sway_assert(new_ws, "New output does not have a workspace")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (old_ws->floating->length) {
|
while (old_ws->floating->length) {
|
||||||
struct sway_container *sticky = old_ws->floating->items[0];
|
struct sway_container *sticky = old_ws->floating->items[0];
|
||||||
container_detach(sticky);
|
container_detach(sticky);
|
||||||
|
|
@ -190,10 +192,19 @@ static void output_evacuate(struct sway_output *output) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sway_workspace *new_output_ws =
|
||||||
|
output_get_active_workspace(new_output);
|
||||||
|
|
||||||
workspace_output_add_priority(workspace, new_output);
|
workspace_output_add_priority(workspace, new_output);
|
||||||
output_add_workspace(new_output, workspace);
|
output_add_workspace(new_output, workspace);
|
||||||
output_sort_workspaces(new_output);
|
output_sort_workspaces(new_output);
|
||||||
ipc_event_workspace(NULL, workspace, "move");
|
ipc_event_workspace(NULL, workspace, "move");
|
||||||
|
|
||||||
|
// If there is an old workspace (the noop output may not have one),
|
||||||
|
// check to see if it is empty and should be destroyed.
|
||||||
|
if (new_output_ws) {
|
||||||
|
workspace_consider_destroy(new_output_ws);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,9 +245,8 @@ void output_disable(struct sway_output *output) {
|
||||||
|
|
||||||
root_for_each_container(untrack_output, output);
|
root_for_each_container(untrack_output, output);
|
||||||
|
|
||||||
if (output->bg_pid) {
|
if (output->swaybg_client != NULL) {
|
||||||
terminate_swaybg(output->bg_pid);
|
wl_client_destroy(output->swaybg_client);
|
||||||
output->bg_pid = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = list_find(root->outputs, output);
|
int index = list_find(root->outputs, output);
|
||||||
|
|
|
||||||
|
|
@ -664,6 +664,13 @@ void view_unmap(struct sway_view *view) {
|
||||||
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->cursor->image_surface = NULL;
|
seat->cursor->image_surface = NULL;
|
||||||
|
if (seat->cursor->active_constraint) {
|
||||||
|
struct wlr_surface *constrain_surface =
|
||||||
|
seat->cursor->active_constraint->surface;
|
||||||
|
if (view_from_wlr_surface(constrain_surface) == view) {
|
||||||
|
sway_cursor_constrain(seat->cursor, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
seat_consider_warp_to_focus(seat);
|
seat_consider_warp_to_focus(seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -701,6 +708,9 @@ static void subsurface_get_root_coords(struct sway_view_child *child,
|
||||||
while (surface && wlr_surface_is_subsurface(surface)) {
|
while (surface && wlr_surface_is_subsurface(surface)) {
|
||||||
struct wlr_subsurface *subsurface =
|
struct wlr_subsurface *subsurface =
|
||||||
wlr_subsurface_from_wlr_surface(surface);
|
wlr_subsurface_from_wlr_surface(surface);
|
||||||
|
if (subsurface == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
*root_sx += subsurface->current.x;
|
*root_sx += subsurface->current.x;
|
||||||
*root_sy += subsurface->current.y;
|
*root_sy += subsurface->current.y;
|
||||||
surface = subsurface->parent;
|
surface = subsurface->parent;
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,16 @@ struct sway_output *workspace_get_initial_output(const char *name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise put it on the focused output
|
// Otherwise try to put it on the focused output
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
struct sway_workspace *focus = seat_get_focused_workspace(seat);
|
struct sway_node *focus = seat_get_focus_inactive(seat, &root->node);
|
||||||
return focus->output;
|
if (focus && focus->type == N_WORKSPACE) {
|
||||||
|
return focus->sway_workspace->output;
|
||||||
|
} else if (focus && focus->type == N_CONTAINER) {
|
||||||
|
return focus->sway_container->workspace->output;
|
||||||
|
}
|
||||||
|
// Fallback to the first output or noop output for headless
|
||||||
|
return root->outputs->length ? root->outputs->items[0] : root->noop_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prevent_invalid_outer_gaps(struct sway_workspace *ws) {
|
static void prevent_invalid_outer_gaps(struct sway_workspace *ws) {
|
||||||
|
|
@ -224,8 +230,10 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
|
||||||
// not a command about workspaces
|
// not a command about workspaces
|
||||||
if (strcmp(_target, "next") == 0 ||
|
if (strcmp(_target, "next") == 0 ||
|
||||||
strcmp(_target, "prev") == 0 ||
|
strcmp(_target, "prev") == 0 ||
|
||||||
strcmp(_target, "next_on_output") == 0 ||
|
strncmp(_target, "next_on_output",
|
||||||
strcmp(_target, "prev_on_output") == 0 ||
|
strlen("next_on_output")) == 0 ||
|
||||||
|
strncmp(_target, "prev_on_output",
|
||||||
|
strlen("next_on_output")) == 0 ||
|
||||||
strcmp(_target, "number") == 0 ||
|
strcmp(_target, "number") == 0 ||
|
||||||
strcmp(_target, "back_and_forth") == 0 ||
|
strcmp(_target, "back_and_forth") == 0 ||
|
||||||
strcmp(_target, "current") == 0) {
|
strcmp(_target, "current") == 0) {
|
||||||
|
|
@ -328,16 +336,13 @@ char *workspace_next_name(const char *output_name) {
|
||||||
if (target != NULL) {
|
if (target != NULL) {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
// As a fall back, get the current number of active workspaces
|
// As a fall back, use the next available number
|
||||||
// and return that + 1 for the next workspace's name
|
char name[12] = "";
|
||||||
int ws_num = root->outputs->length;
|
unsigned int ws_num = 1;
|
||||||
int l = snprintf(NULL, 0, "%d", ws_num);
|
do {
|
||||||
char *name = malloc(l + 1);
|
snprintf(name, sizeof(name), "%u", ws_num++);
|
||||||
if (!sway_assert(name, "Could not allocate workspace name")) {
|
} while (workspace_by_number(name));
|
||||||
return NULL;
|
return strdup(name);
|
||||||
}
|
|
||||||
sprintf(name, "%d", ws_num++);
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _workspace_by_number(struct sway_workspace *ws, void *data) {
|
static bool _workspace_by_number(struct sway_workspace *ws, void *data) {
|
||||||
|
|
@ -366,11 +371,11 @@ struct sway_workspace *workspace_by_name(const char *name) {
|
||||||
if (strcmp(name, "prev") == 0) {
|
if (strcmp(name, "prev") == 0) {
|
||||||
return workspace_prev(current);
|
return workspace_prev(current);
|
||||||
} else if (strcmp(name, "prev_on_output") == 0) {
|
} else if (strcmp(name, "prev_on_output") == 0) {
|
||||||
return workspace_output_prev(current);
|
return workspace_output_prev(current, false);
|
||||||
} else if (strcmp(name, "next") == 0) {
|
} else if (strcmp(name, "next") == 0) {
|
||||||
return workspace_next(current);
|
return workspace_next(current);
|
||||||
} else if (strcmp(name, "next_on_output") == 0) {
|
} else if (strcmp(name, "next_on_output") == 0) {
|
||||||
return workspace_output_next(current);
|
return workspace_output_next(current, false);
|
||||||
} else if (strcmp(name, "current") == 0) {
|
} else if (strcmp(name, "current") == 0) {
|
||||||
return current;
|
return current;
|
||||||
} else if (strcasecmp(name, "back_and_forth") == 0) {
|
} else if (strcasecmp(name, "back_and_forth") == 0) {
|
||||||
|
|
@ -391,11 +396,18 @@ struct sway_workspace *workspace_by_name(const char *name) {
|
||||||
* otherwise the next one is returned.
|
* otherwise the next one is returned.
|
||||||
*/
|
*/
|
||||||
static struct sway_workspace *workspace_output_prev_next_impl(
|
static struct sway_workspace *workspace_output_prev_next_impl(
|
||||||
struct sway_output *output, int dir) {
|
struct sway_output *output, int dir, bool create) {
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
struct sway_workspace *workspace = seat_get_focused_workspace(seat);
|
struct sway_workspace *workspace = seat_get_focused_workspace(seat);
|
||||||
|
|
||||||
int index = list_find(output->workspaces, workspace);
|
int index = list_find(output->workspaces, workspace);
|
||||||
|
if (!workspace_is_empty(workspace) && create &&
|
||||||
|
(index + dir < 0 || index + dir == output->workspaces->length)) {
|
||||||
|
struct sway_output *output = workspace->output;
|
||||||
|
char *next = workspace_next_name(output->wlr_output->name);
|
||||||
|
workspace_create(output, next);
|
||||||
|
free(next);
|
||||||
|
}
|
||||||
size_t new_index = wrap(index + dir, output->workspaces->length);
|
size_t new_index = wrap(index + dir, output->workspaces->length);
|
||||||
return output->workspaces->items[new_index];
|
return output->workspaces->items[new_index];
|
||||||
}
|
}
|
||||||
|
|
@ -426,16 +438,18 @@ static struct sway_workspace *workspace_prev_next_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_workspace *workspace_output_next(struct sway_workspace *current) {
|
struct sway_workspace *workspace_output_next(
|
||||||
return workspace_output_prev_next_impl(current->output, 1);
|
struct sway_workspace *current, bool create) {
|
||||||
|
return workspace_output_prev_next_impl(current->output, 1, create);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_workspace *workspace_next(struct sway_workspace *current) {
|
struct sway_workspace *workspace_next(struct sway_workspace *current) {
|
||||||
return workspace_prev_next_impl(current, 1);
|
return workspace_prev_next_impl(current, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_workspace *workspace_output_prev(struct sway_workspace *current) {
|
struct sway_workspace *workspace_output_prev(
|
||||||
return workspace_output_prev_next_impl(current->output, -1);
|
struct sway_workspace *current, bool create) {
|
||||||
|
return workspace_output_prev_next_impl(current->output, -1, create);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_workspace *workspace_prev(struct sway_workspace *current) {
|
struct sway_workspace *workspace_prev(struct sway_workspace *current) {
|
||||||
|
|
@ -445,9 +459,15 @@ struct sway_workspace *workspace_prev(struct sway_workspace *current) {
|
||||||
bool workspace_switch(struct sway_workspace *workspace,
|
bool workspace_switch(struct sway_workspace *workspace,
|
||||||
bool no_auto_back_and_forth) {
|
bool no_auto_back_and_forth) {
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
struct sway_workspace *active_ws = seat_get_focused_workspace(seat);
|
struct sway_workspace *active_ws = NULL;
|
||||||
|
struct sway_node *focus = seat_get_focus_inactive(seat, &root->node);
|
||||||
|
if (focus && focus->type == N_WORKSPACE) {
|
||||||
|
active_ws = focus->sway_workspace;
|
||||||
|
} else if (focus && focus->type == N_CONTAINER) {
|
||||||
|
active_ws = focus->sway_container->workspace;
|
||||||
|
}
|
||||||
|
|
||||||
if (!no_auto_back_and_forth && config->auto_back_and_forth
|
if (!no_auto_back_and_forth && config->auto_back_and_forth && active_ws
|
||||||
&& active_ws == workspace && seat->prev_workspace_name) {
|
&& active_ws == workspace && seat->prev_workspace_name) {
|
||||||
struct sway_workspace *new_ws =
|
struct sway_workspace *new_ws =
|
||||||
workspace_by_name(seat->prev_workspace_name);
|
workspace_by_name(seat->prev_workspace_name);
|
||||||
|
|
@ -456,9 +476,9 @@ bool workspace_switch(struct sway_workspace *workspace,
|
||||||
workspace_create(NULL, seat->prev_workspace_name);
|
workspace_create(NULL, seat->prev_workspace_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!seat->prev_workspace_name ||
|
if (active_ws && (!seat->prev_workspace_name ||
|
||||||
(strcmp(seat->prev_workspace_name, active_ws->name)
|
(strcmp(seat->prev_workspace_name, active_ws->name)
|
||||||
&& active_ws != workspace)) {
|
&& active_ws != workspace))) {
|
||||||
free(seat->prev_workspace_name);
|
free(seat->prev_workspace_name);
|
||||||
seat->prev_workspace_name = malloc(strlen(active_ws->name) + 1);
|
seat->prev_workspace_name = malloc(strlen(active_ws->name) + 1);
|
||||||
if (!seat->prev_workspace_name) {
|
if (!seat->prev_workspace_name) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
@ -403,8 +404,7 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) {
|
||||||
static void display_in(int fd, short mask, void *data) {
|
static void display_in(int fd, short mask, void *data) {
|
||||||
struct swaybar *bar = data;
|
struct swaybar *bar = data;
|
||||||
if (wl_display_dispatch(bar->display) == -1) {
|
if (wl_display_dispatch(bar->display) == -1) {
|
||||||
bar_teardown(bar);
|
bar->running = false;
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,7 +439,7 @@ void bar_run(struct swaybar *bar) {
|
||||||
loop_add_fd(bar->eventloop, bar->tray->fd, POLLIN, tray_in, bar->tray->bus);
|
loop_add_fd(bar->eventloop, bar->tray->fd, POLLIN, tray_in, bar->tray->bus);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
while (1) {
|
while (bar->running) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (wl_display_flush(bar->display) == -1 && errno != EAGAIN) {
|
if (wl_display_flush(bar->display) == -1 && errno != EAGAIN) {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,7 @@
|
||||||
static struct swaybar swaybar;
|
static struct swaybar swaybar;
|
||||||
|
|
||||||
void sig_handler(int signal) {
|
void sig_handler(int signal) {
|
||||||
bar_teardown(&swaybar);
|
swaybar.running = false;
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sway_terminate(int code) {
|
|
||||||
bar_teardown(&swaybar);
|
|
||||||
exit(code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
@ -93,8 +87,6 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGTERM, sig_handler);
|
|
||||||
|
|
||||||
if (!bar_setup(&swaybar, socket_path)) {
|
if (!bar_setup(&swaybar, socket_path)) {
|
||||||
free(socket_path);
|
free(socket_path);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -102,6 +94,10 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
free(socket_path);
|
free(socket_path);
|
||||||
|
|
||||||
|
signal(SIGINT, sig_handler);
|
||||||
|
signal(SIGTERM, sig_handler);
|
||||||
|
|
||||||
|
swaybar.running = true;
|
||||||
bar_run(&swaybar);
|
bar_run(&swaybar);
|
||||||
bar_teardown(&swaybar);
|
bar_teardown(&swaybar);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -189,9 +189,9 @@ bool init_host(struct swaybar_host *host, char *protocol,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_bus_slot_set_floating(reg_slot, 1);
|
sd_bus_slot_set_floating(reg_slot, 0);
|
||||||
sd_bus_slot_set_floating(unreg_slot, 1);
|
sd_bus_slot_set_floating(unreg_slot, 0);
|
||||||
sd_bus_slot_set_floating(watcher_slot, 1);
|
sd_bus_slot_set_floating(watcher_slot, 0);
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Registered %s", host->service);
|
sway_log(SWAY_DEBUG, "Registered %s", host->service);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,8 @@ void destroy_sni(struct swaybar_sni *sni) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_surface_destroy(sni->icon);
|
||||||
|
|
||||||
sd_bus_slot_unref(sni->new_icon_slot);
|
sd_bus_slot_unref(sni->new_icon_slot);
|
||||||
sd_bus_slot_unref(sni->new_attention_icon_slot);
|
sd_bus_slot_unref(sni->new_attention_icon_slot);
|
||||||
sd_bus_slot_unref(sni->new_status_slot);
|
sd_bus_slot_unref(sni->new_status_slot);
|
||||||
|
|
@ -308,9 +310,11 @@ void destroy_sni(struct swaybar_sni *sni) {
|
||||||
free(sni->path);
|
free(sni->path);
|
||||||
free(sni->status);
|
free(sni->status);
|
||||||
free(sni->icon_name);
|
free(sni->icon_name);
|
||||||
free(sni->icon_pixmap);
|
list_free_items_and_destroy(sni->icon_pixmap);
|
||||||
free(sni->attention_icon_name);
|
free(sni->attention_icon_name);
|
||||||
|
list_free_items_and_destroy(sni->attention_icon_pixmap);
|
||||||
free(sni->menu);
|
free(sni->menu);
|
||||||
|
free(sni->icon_theme_path);
|
||||||
free(sni);
|
free(sni);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,6 @@ static int cmp_id(const void *item, const void *cmp_to) {
|
||||||
return strcmp(item, cmp_to);
|
return strcmp(item, cmp_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_service(const void *item, const void *cmp_to) {
|
|
||||||
return strncmp(item, cmp_to, strlen(cmp_to));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int handle_lost_service(sd_bus_message *msg,
|
static int handle_lost_service(sd_bus_message *msg,
|
||||||
void *data, sd_bus_error *error) {
|
void *data, sd_bus_error *error) {
|
||||||
char *service, *old_owner, *new_owner;
|
char *service, *old_owner, *new_owner;
|
||||||
|
|
@ -33,18 +29,23 @@ static int handle_lost_service(sd_bus_message *msg,
|
||||||
|
|
||||||
if (!*new_owner) {
|
if (!*new_owner) {
|
||||||
struct swaybar_watcher *watcher = data;
|
struct swaybar_watcher *watcher = data;
|
||||||
int idx = list_seq_find(watcher->items,
|
for (int idx = 0; idx < watcher->items->length; ++idx) {
|
||||||
using_standard_protocol(watcher) ? cmp_id : cmp_service, service);
|
|
||||||
if (idx != -1) {
|
|
||||||
char *id = watcher->items->items[idx];
|
char *id = watcher->items->items[idx];
|
||||||
sway_log(SWAY_DEBUG, "Unregistering Status Notifier Item '%s'", id);
|
int cmp_res = using_standard_protocol(watcher) ?
|
||||||
list_del(watcher->items, idx);
|
cmp_id(id, service) : strncmp(id, service, strlen(service));
|
||||||
sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
|
if (cmp_res == 0) {
|
||||||
"StatusNotifierItemUnregistered", "s", id);
|
sway_log(SWAY_DEBUG, "Unregistering Status Notifier Item '%s'", id);
|
||||||
free(id);
|
list_del(watcher->items, idx--);
|
||||||
|
sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
|
||||||
|
"StatusNotifierItemUnregistered", "s", id);
|
||||||
|
free(id);
|
||||||
|
if (using_standard_protocol(watcher)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = list_seq_find(watcher->hosts, cmp_id, service);
|
int idx = list_seq_find(watcher->hosts, cmp_id, service);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
sway_log(SWAY_DEBUG, "Unregistering Status Notifier Host '%s'", service);
|
sway_log(SWAY_DEBUG, "Unregistering Status Notifier Host '%s'", service);
|
||||||
free(watcher->hosts->items[idx]);
|
free(watcher->hosts->items[idx]);
|
||||||
|
|
@ -185,8 +186,8 @@ struct swaybar_watcher *create_watcher(char *protocol, sd_bus *bus) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_bus_slot_set_floating(signal_slot, 1);
|
sd_bus_slot_set_floating(signal_slot, 0);
|
||||||
sd_bus_slot_set_floating(vtable_slot, 1);
|
sd_bus_slot_set_floating(vtable_slot, 0);
|
||||||
|
|
||||||
watcher->bus = bus;
|
watcher->bus = bus;
|
||||||
watcher->hosts = create_list();
|
watcher->hosts = create_list();
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,8 @@ static void pretty_print_input(json_object *i) {
|
||||||
json_object_get_int(vendor));
|
json_object_get_int(vendor));
|
||||||
|
|
||||||
if (json_object_object_get_ex(i, "xkb_active_layout_name", &kbdlayout)) {
|
if (json_object_object_get_ex(i, "xkb_active_layout_name", &kbdlayout)) {
|
||||||
printf(" Active Keyboard Layout: %s\n",
|
const char *layout = json_object_get_string(kbdlayout);
|
||||||
json_object_get_string(kbdlayout));
|
printf(" Active Keyboard Layout: %s\n", layout ? layout : "(unnamed)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json_object_object_get_ex(i, "libinput_send_events", &events)) {
|
if (json_object_object_get_ex(i, "libinput_send_events", &events)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue