mirror of https://github.com/swaywm/sway.git
Compare commits
133 Commits
Author | SHA1 | Date |
---|---|---|
Manuel Stoeckl | dcdb72757a | |
Simon Ser | 30f5c3a911 | |
Alexander Orzechowski | b463957021 | |
Kenny Levinsen | 2686afb95c | |
Kenny Levinsen | 4c28916d68 | |
Kenny Levinsen | ee5c4f38c9 | |
Kenny Levinsen | 646019cad9 | |
Kenny Levinsen | ffcde7a70c | |
Simon Ser | 087226d997 | |
Simon Ser | f11c5d562e | |
Kenny Levinsen | 1267e47de9 | |
Ferdinand Bachmann | bc258a3be2 | |
Daniel Kahn Gillmor | dcb142bf5e | |
Simon Ser | 9e14651077 | |
Kenny Levinsen | a4ef37752f | |
Kenny Levinsen | 26a9a6b479 | |
Kenny Levinsen | c3fca26d30 | |
Kenny Levinsen | 9becff0ba5 | |
Kenny Levinsen | 56e97b7d60 | |
Kenny Levinsen | 3b419020a3 | |
Kenny Levinsen | 98be797356 | |
Kenny Levinsen | 923f642b70 | |
Kenny Levinsen | 3e03eb3a01 | |
Kenny Levinsen | e2f3ebad8c | |
Ferdinand Bachmann | 125c74338a | |
Andri Yngvason | 5a7477cb8f | |
Simon Ser | dc9f217307 | |
Simon Ser | 9139da6149 | |
Simon Ser | 3bc75221bc | |
Simon Ser | 2b08e79061 | |
Alexander Orzechowski | 2e951163c5 | |
Simon Ser | 23389ebd1f | |
Simon Ser | 3ef5abd405 | |
Simon Ser | 4e6d7612ff | |
Simon Ser | f2a0e81b24 | |
Simon Ser | 59f6292383 | |
Simon Ser | fd9ab9ee06 | |
Ronan Pigott | 5e18ed3cf0 | |
Luofan Chen | 2058209a13 | |
llyyr | 0b84d82b9a | |
llyyr | 2867ef646b | |
Simon Ser | fca8474e9b | |
llyyr | 469411d484 | |
Simon Ser | 829c75b9c9 | |
Simon Ser | fc640d5f6c | |
Simon Ser | 07b0598526 | |
llyyr | d6150b6bb0 | |
Access | 7c11c463a3 | |
Aleksei Bavshin | d19810eba8 | |
Ronan Pigott | f6d22f8e68 | |
Simon Ser | 541e6e260c | |
Simon Ser | ca40663d42 | |
Kirill Primak | 7a2ff7ba81 | |
Alexander Orzechowski | 09c360d503 | |
Alexander Orzechowski | 1846944f04 | |
Alexander Orzechowski | 1dc661af17 | |
Merlin Lex | 1b5515400d | |
Simon Ser | 88b2abf5f2 | |
Simon Ser | 93d391651c | |
Simon Ser | f7a0f06dff | |
Simon Ser | ecfef1348a | |
Violet Purcell | 6b2aa83246 | |
Simon Ser | 88e99fa84f | |
Alexander Orzechowski | ba427a469a | |
Tamino Bauknecht | c8676fad54 | |
Simon Ser | e39b0b816b | |
Kirill Primak | f202bc84d2 | |
Kirill Primak | a4e85332a1 | |
Alexander Orzechowski | e8c421e917 | |
Daniel De Graaf | 2c2625acd3 | |
Simon Ser | 08a06a7b6b | |
Simon Ser | ae33f4eb37 | |
Alexander Orzechowski | 5fc85c5066 | |
Alexander Orzechowski | 7c635b61fe | |
Alexander Orzechowski | bab6b79af2 | |
Alexander Orzechowski | 9da295c11f | |
Alexander Orzechowski | 09e11dabb2 | |
Alexander Orzechowski | 2e53de80bb | |
Alexander Orzechowski | 5f0801b6f2 | |
Alexander Orzechowski | 1e018e72b4 | |
Alexander Orzechowski | 06ad734e70 | |
Alexander Orzechowski | ed2724bd6c | |
Alexander Orzechowski | 6e5fc4c2aa | |
Alexander Orzechowski | b38ed8b479 | |
Alexander Orzechowski | 08c484f46f | |
Alexander Orzechowski | 6d7b1321db | |
Alexander Orzechowski | 188811f808 | |
Alexander Orzechowski | 5b8b505af5 | |
Alexander Orzechowski | 946fc80945 | |
Alexander Orzechowski | 869baff252 | |
Alexander Orzechowski | bac3ab5526 | |
Alexander Orzechowski | 9a57966606 | |
Alexander Orzechowski | 0639bde9fb | |
Alexander Orzechowski | c640c3015f | |
Alexander Orzechowski | 9c17cba0b2 | |
Alexander Orzechowski | 0e1a02bf0a | |
Alexander Orzechowski | 1b09238645 | |
Alexander Orzechowski | 1eb16d1367 | |
Alexander Orzechowski | dbd2fbf430 | |
Alexander Orzechowski | b4d7e84d38 | |
Kirill Primak | 2c69e19fd3 | |
Kirill Primak | 8d1b0cecd9 | |
Kirill Primak | 904d256581 | |
Simon Ser | c5fd8c050f | |
Simon Ser | 7e69a7076f | |
Simon Ser | fa294a9094 | |
Simon Ser | 95265fba59 | |
Billli11 | 0aceff7469 | |
Bill Li | 64d644f0da | |
Simon Ser | 22d0dd8bde | |
Alexander Orzechowski | bbabb9aae8 | |
Simon Ser | c6edbb7e5a | |
Simon Ser | e8a0205607 | |
Simon Ser | 607b8aed0c | |
Simon Ser | 7ad8c80bfe | |
Simon Ser | dbd70faf2e | |
Simon Ser | a6ef12d968 | |
Simon Ser | ff07eab85b | |
Simon Ser | b81c4da494 | |
Tamino Bauknecht | 255ff665c5 | |
Simon Ser | bf2b79b284 | |
mrusme | ae3acf26f8 | |
Alexander Orzechowski | f12023b1a2 | |
Sergei Trofimovich | 2cd73a33c2 | |
apreiml | bc7d15d64d | |
Manuel Stoeckl | e633fe0b40 | |
Manuel Stoeckl | 439122e887 | |
Manuel Stoeckl | 39b9c0d6ba | |
Kirill Primak | 47e6a1164c | |
Simon Ser | 128b6253a9 | |
Simon Ser | fd6d6f1d97 | |
llyyr | a946b1aecf | |
llyyr | 4ad15a4015 |
12
README.de.md
12
README.de.md
|
@ -2,13 +2,13 @@
|
|||
Sway ist ein [i3](https://i3wm.org/)-kompatibler [Wayland](http://wayland.freedesktop.org/)-Compositor. Lies die [FAQ](https://github.com/swaywm/sway/wiki). Tritt dem [IRC Channel](https://web.libera.chat/gamja/?channels=#sway) bei (#sway on irc.libera.chat; Englisch).
|
||||
|
||||
## Signaturen
|
||||
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48](https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48) signiert und auf GitHub veröffentlicht.
|
||||
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48](https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48) signiert und [auf GitHub](https://github.com/swaywm/sway/releases) veröffentlicht.
|
||||
|
||||
## Installation
|
||||
### Mit der Paketverwaltung
|
||||
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Das Paket sollte "sway" heißen. Falls es kein solches Paket gibt, kannst du im [Wiki](https://github.com/swaywm/sway/wiki/Unsupported-packages) (englisch) nach mehr Informationen bezüglich deiner Distribution suchen.
|
||||
|
||||
Falls du sway für deine eigene Distribution als Paket bereitstellen möchtest, solltest du die Entwickler per IRC oder E-Mail (sir@cmpwn.com) kontaktieren.
|
||||
### Über die Paketverwaltung
|
||||
|
||||
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Versuche einfach das Packet "sway" zu installieren.
|
||||
|
||||
### Quellcode selbst kompilieren
|
||||
|
||||
|
@ -23,8 +23,8 @@ sway benötigt die folgenden Pakete:
|
|||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (Optional, wird für das Benachrichtigungsfeld (System Tray) benötigt)
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc)\* (Optional, wird für die Dokumentation (Man Pages) benötigt)
|
||||
* git\*
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (Optional, wird für die Dokumentation (Man Pages) benötigt)\*
|
||||
* git (Optional: Versionsinfo)\*
|
||||
|
||||
_\*Werden nur während des Kompilierens benötigt_
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ Install dependencies:
|
|||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (optional: system tray)
|
||||
* gdk-pixbuf2 (optional: additional image formats for system tray)
|
||||
* [swaybg] (optional: wallpaper)
|
||||
* [scdoc] (optional: man pages) \*
|
||||
* git (optional: version info) \*
|
||||
|
||||
|
@ -89,4 +90,5 @@ sway (gdm is known to work fairly well).
|
|||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||
[swaybg]: https://github.com/swaywm/swaybg/
|
||||
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809
|
||||
#include <assert.h>
|
||||
#include <cairo.h>
|
||||
#include <errno.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "gesture.h"
|
||||
|
||||
#include <math.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200112L
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200112L
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
lib_sway_common = static_library(
|
||||
'sway-common',
|
||||
files(
|
||||
'background-image.c',
|
||||
'cairo.c',
|
||||
'gesture.c',
|
||||
'ipc-client.c',
|
||||
|
@ -14,7 +13,6 @@ lib_sway_common = static_library(
|
|||
),
|
||||
dependencies: [
|
||||
cairo,
|
||||
gdk_pixbuf,
|
||||
pango,
|
||||
pangocairo,
|
||||
wayland_client.partial_dependency(compile_args: true)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef _SWAY_BACKGROUND_IMAGE_H
|
||||
#define _SWAY_BACKGROUND_IMAGE_H
|
||||
#include "cairo_util.h"
|
||||
|
||||
enum background_mode {
|
||||
BACKGROUND_MODE_STRETCH,
|
||||
BACKGROUND_MODE_FILL,
|
||||
BACKGROUND_MODE_FIT,
|
||||
BACKGROUND_MODE_CENTER,
|
||||
BACKGROUND_MODE_TILE,
|
||||
BACKGROUND_MODE_SOLID_COLOR,
|
||||
BACKGROUND_MODE_INVALID,
|
||||
};
|
||||
|
||||
enum background_mode parse_background_mode(const char *mode);
|
||||
cairo_surface_t *load_background_image(const char *path);
|
||||
void render_background_image(cairo_t *cairo, cairo_surface_t *image,
|
||||
enum background_mode mode, int buffer_width, int buffer_height);
|
||||
|
||||
#endif
|
|
@ -291,6 +291,14 @@ struct output_config {
|
|||
char *background_fallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* An output config pre-matched to an output
|
||||
*/
|
||||
struct matched_output_config {
|
||||
struct sway_output *output;
|
||||
struct output_config *config;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores size of gaps for each side
|
||||
*/
|
||||
|
@ -680,20 +688,25 @@ const char *sway_output_scale_filter_to_string(enum scale_filter_mode scale_filt
|
|||
|
||||
struct output_config *new_output_config(const char *name);
|
||||
|
||||
void merge_output_config(struct output_config *dst, struct output_config *src);
|
||||
bool apply_output_configs(struct matched_output_config *configs,
|
||||
size_t configs_len, bool test_only, bool degrade_to_off);
|
||||
|
||||
bool apply_output_config(struct output_config *oc, struct sway_output *output);
|
||||
void apply_all_output_configs(void);
|
||||
|
||||
bool test_output_config(struct output_config *oc, struct sway_output *output);
|
||||
void sort_output_configs_by_priority(struct matched_output_config *configs,
|
||||
size_t configs_len);
|
||||
|
||||
struct output_config *store_output_config(struct output_config *oc);
|
||||
/**
|
||||
* store_output_config stores a new output config. An output may be matched by
|
||||
* three different config types, in order of precedence: Identifier, name and
|
||||
* wildcard. When storing a config type of lower precedence, assume that the
|
||||
* user wants the config to take immediate effect by superseding (clearing) the
|
||||
* same values from higher presedence configuration.
|
||||
*/
|
||||
void store_output_config(struct output_config *oc);
|
||||
|
||||
struct output_config *find_output_config(struct sway_output *output);
|
||||
|
||||
void apply_output_config_to_outputs(struct output_config *oc);
|
||||
|
||||
void reset_outputs(void);
|
||||
|
||||
void free_output_config(struct output_config *oc);
|
||||
|
||||
bool spawn_swaybg(void);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#include <wlr/types/wlr_compositor.h>
|
||||
|
||||
struct sway_container;
|
||||
struct sway_view;
|
||||
|
||||
void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly,
|
||||
bool whole);
|
||||
|
||||
void desktop_damage_whole_container(struct sway_container *con);
|
||||
|
||||
void desktop_damage_box(struct wlr_box *box);
|
||||
|
||||
void desktop_damage_view(struct sway_view *view);
|
|
@ -3,14 +3,18 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include "sway/input/seat.h"
|
||||
|
||||
struct launcher_ctx {
|
||||
pid_t pid;
|
||||
char *fallback_name;
|
||||
struct wlr_xdg_activation_token_v1 *token;
|
||||
struct wl_listener token_destroy;
|
||||
struct sway_seat *seat;
|
||||
struct wl_listener seat_destroy;
|
||||
|
||||
bool activated;
|
||||
bool had_focused_surface;
|
||||
|
||||
struct sway_node *node;
|
||||
struct wl_listener node_destroy;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef _SWAY_TRANSACTION_H
|
||||
#define _SWAY_TRANSACTION_H
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
/**
|
||||
* Transactions enable us to perform atomic layout updates.
|
||||
|
@ -38,8 +40,11 @@ void transaction_commit_dirty_client(void);
|
|||
* Notify the transaction system that a view is ready for the new layout.
|
||||
*
|
||||
* When all views in the transaction are ready, the layout will be applied.
|
||||
*
|
||||
* A success boolean is returned denoting that this part of the transaction is
|
||||
* ready.
|
||||
*/
|
||||
void transaction_notify_view_ready_by_serial(struct sway_view *view,
|
||||
bool transaction_notify_view_ready_by_serial(struct sway_view *view,
|
||||
uint32_t serial);
|
||||
|
||||
/**
|
||||
|
@ -47,8 +52,13 @@ void transaction_notify_view_ready_by_serial(struct sway_view *view,
|
|||
* identifying the instruction by geometry rather than by serial.
|
||||
*
|
||||
* This is used by xwayland views, as they don't have serials.
|
||||
*
|
||||
* A success boolean is returned denoting that this part of the transaction is
|
||||
* ready.
|
||||
*/
|
||||
void transaction_notify_view_ready_by_geometry(struct sway_view *view,
|
||||
bool transaction_notify_view_ready_by_geometry(struct sway_view *view,
|
||||
double x, double y, int width, int height);
|
||||
|
||||
void arrange_popups(struct wlr_scene_tree *popups);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -114,7 +114,7 @@ void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
|||
|
||||
void dispatch_cursor_button(struct sway_cursor *cursor,
|
||||
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
|
||||
enum wlr_button_state state);
|
||||
enum wl_pointer_button_state state);
|
||||
|
||||
void dispatch_cursor_axis(struct sway_cursor *cursor,
|
||||
struct wlr_pointer_axis_event *event);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef _SWAY_INPUT_INPUT_MANAGER_H
|
||||
#define _SWAY_INPUT_INPUT_MANAGER_H
|
||||
#include <libinput.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/types/wlr_transient_seat_v1.h>
|
||||
#include "sway/server.h"
|
||||
#include "sway/config.h"
|
||||
#include "list.h"
|
||||
|
@ -21,11 +21,11 @@ struct sway_input_manager {
|
|||
struct wl_list devices;
|
||||
struct wl_list seats;
|
||||
|
||||
struct wlr_input_inhibit_manager *inhibit;
|
||||
struct wlr_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
|
||||
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
|
||||
struct wlr_pointer_gestures_v1 *pointer_gestures;
|
||||
struct wlr_transient_seat_manager_v1 *transient_seat_manager;
|
||||
|
||||
struct wl_listener new_input;
|
||||
struct wl_listener inhibit_activate;
|
||||
|
@ -33,6 +33,7 @@ struct sway_input_manager {
|
|||
struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor;
|
||||
struct wl_listener virtual_keyboard_new;
|
||||
struct wl_listener virtual_pointer_new;
|
||||
struct wl_listener transient_seat_create;
|
||||
};
|
||||
|
||||
struct sway_input_manager *input_manager_create(struct sway_server *server);
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
bool sway_input_configure_libinput_device(struct sway_input_device *device);
|
||||
|
||||
void sway_input_configure_libinput_device_send_events(
|
||||
struct sway_input_device *device);
|
||||
|
||||
void sway_input_reset_libinput_device(struct sway_input_device *device);
|
||||
|
||||
bool sway_libinput_device_is_builtin(struct sway_input_device *device);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_touch.h>
|
||||
#include <wlr/util/edges.h>
|
||||
|
@ -12,12 +13,11 @@
|
|||
#include "sway/input/text_input.h"
|
||||
|
||||
struct sway_seat;
|
||||
struct render_context;
|
||||
|
||||
struct sway_seatop_impl {
|
||||
void (*button)(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct wlr_input_device *device, uint32_t button,
|
||||
enum wlr_button_state state);
|
||||
enum wl_pointer_button_state state);
|
||||
void (*pointer_motion)(struct sway_seat *seat, uint32_t time_msec);
|
||||
void (*pointer_axis)(struct sway_seat *seat,
|
||||
struct wlr_pointer_axis_event *event);
|
||||
|
@ -52,7 +52,6 @@ struct sway_seatop_impl {
|
|||
uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
|
||||
void (*end)(struct sway_seat *seat);
|
||||
void (*unref)(struct sway_seat *seat, struct sway_container *con);
|
||||
void (*render)(struct sway_seat *seat, struct render_context *ctx);
|
||||
bool allow_set_cursor;
|
||||
};
|
||||
|
||||
|
@ -75,20 +74,6 @@ struct sway_seat_node {
|
|||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct sway_drag_icon {
|
||||
struct sway_seat *seat;
|
||||
struct wlr_drag_icon *wlr_drag_icon;
|
||||
struct wl_list link; // sway_root::drag_icons
|
||||
|
||||
double x, y; // in layout-local coordinates
|
||||
int dx, dy; // offset in surface-local coordinates
|
||||
|
||||
struct wl_listener surface_commit;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct sway_drag {
|
||||
struct sway_seat *seat;
|
||||
struct wlr_drag *wlr_drag;
|
||||
|
@ -99,6 +84,15 @@ struct sway_seat {
|
|||
struct wlr_seat *wlr_seat;
|
||||
struct sway_cursor *cursor;
|
||||
|
||||
// Seat scene tree structure
|
||||
// - scene_tree
|
||||
// - drag icons
|
||||
// - drag icon 1
|
||||
// - drag icon 2
|
||||
// - seatop specific stuff
|
||||
struct wlr_scene_tree *scene_tree;
|
||||
struct wlr_scene_tree *drag_icons;
|
||||
|
||||
bool has_focus;
|
||||
struct wl_list focus_stack; // list of containers in focus order
|
||||
struct sway_workspace *workspace;
|
||||
|
@ -108,9 +102,6 @@ struct sway_seat {
|
|||
// If the exclusive layer is set, views cannot receive keyboard focus
|
||||
bool has_exclusive_layer;
|
||||
|
||||
// If exclusive_client is set, no other clients will receive input events
|
||||
struct wl_client *exclusive_client;
|
||||
|
||||
// Last touch point
|
||||
int32_t touch_id;
|
||||
double touch_x, touch_y;
|
||||
|
@ -133,6 +124,7 @@ struct sway_seat {
|
|||
struct wl_listener start_drag;
|
||||
struct wl_listener request_set_selection;
|
||||
struct wl_listener request_set_primary_selection;
|
||||
struct wl_listener destroy;
|
||||
|
||||
struct wl_list devices; // sway_seat_device::link
|
||||
struct wl_list keyboard_groups; // sway_keyboard_group::link
|
||||
|
@ -201,8 +193,7 @@ void seat_set_focus_surface(struct sway_seat *seat,
|
|||
void seat_set_focus_layer(struct sway_seat *seat,
|
||||
struct wlr_layer_surface_v1 *layer);
|
||||
|
||||
void seat_set_exclusive_client(struct sway_seat *seat,
|
||||
struct wl_client *client);
|
||||
void seat_unfocus_unless_client(struct sway_seat *seat, struct wl_client *client);
|
||||
|
||||
struct sway_node *seat_get_focus(struct sway_seat *seat);
|
||||
|
||||
|
@ -261,7 +252,7 @@ void seat_idle_notify_activity(struct sway_seat *seat,
|
|||
|
||||
bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface);
|
||||
|
||||
void drag_icon_update_position(struct sway_drag_icon *icon);
|
||||
void drag_icons_update_position(struct sway_seat *seat);
|
||||
|
||||
enum wlr_edges find_resize_edge(struct sway_container *cont,
|
||||
struct wlr_surface *surface, struct sway_cursor *cursor);
|
||||
|
@ -296,13 +287,13 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
|
|||
struct sway_workspace *workspace);
|
||||
|
||||
void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
uint32_t button, enum wlr_button_state state);
|
||||
uint32_t button, enum wl_pointer_button_state state);
|
||||
|
||||
void seat_consider_warp_to_focus(struct sway_seat *seat);
|
||||
|
||||
void seatop_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct wlr_input_device *device, uint32_t button,
|
||||
enum wlr_button_state state);
|
||||
enum wl_pointer_button_state state);
|
||||
|
||||
void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec);
|
||||
|
||||
|
@ -361,12 +352,6 @@ void seatop_end(struct sway_seat *seat);
|
|||
*/
|
||||
void seatop_unref(struct sway_seat *seat, struct sway_container *con);
|
||||
|
||||
/**
|
||||
* Instructs a seatop to render anything that it needs to render
|
||||
* (eg. dropzone for move-tiling)
|
||||
*/
|
||||
void seatop_render(struct sway_seat *seat, struct render_context *ctx);
|
||||
|
||||
bool seatop_allows_set_cursor(struct sway_seat *seat);
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,18 +21,21 @@ struct sway_input_method_relay {
|
|||
struct sway_seat *seat;
|
||||
|
||||
struct wl_list text_inputs; // sway_text_input::link
|
||||
struct wl_list input_popups; // sway_input_popup::link
|
||||
struct wlr_input_method_v2 *input_method; // doesn't have to be present
|
||||
|
||||
struct wl_listener text_input_new;
|
||||
|
||||
struct wl_listener input_method_new;
|
||||
struct wl_listener input_method_commit;
|
||||
struct wl_listener input_method_new_popup_surface;
|
||||
struct wl_listener input_method_grab_keyboard;
|
||||
struct wl_listener input_method_destroy;
|
||||
|
||||
struct wl_listener input_method_keyboard_grab_destroy;
|
||||
};
|
||||
|
||||
|
||||
struct sway_text_input {
|
||||
struct sway_input_method_relay *relay;
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _SWAY_INPUT_TEXT_INPUT_POPUP_H
|
||||
#define _SWAY_INPUT_TEXT_INPUT_POPUP_H
|
||||
|
||||
#include "sway/tree/view.h"
|
||||
|
||||
struct sway_input_popup {
|
||||
struct sway_input_method_relay *relay;
|
||||
|
||||
struct wlr_scene_tree *scene_tree;
|
||||
struct sway_popup_desc desc;
|
||||
struct wlr_input_popup_surface_v2 *popup_surface;
|
||||
|
||||
struct wl_list link;
|
||||
|
||||
struct wl_listener popup_destroy;
|
||||
struct wl_listener popup_surface_commit;
|
||||
|
||||
struct wl_listener focused_surface_unmap;
|
||||
};
|
||||
#endif
|
|
@ -3,54 +3,34 @@
|
|||
#include <stdbool.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
||||
enum layer_parent {
|
||||
LAYER_PARENT_LAYER,
|
||||
LAYER_PARENT_POPUP,
|
||||
};
|
||||
#include "sway/tree/view.h"
|
||||
|
||||
struct sway_layer_surface {
|
||||
struct wlr_layer_surface_v1 *layer_surface;
|
||||
struct wl_list link;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener surface_commit;
|
||||
struct wl_listener output_destroy;
|
||||
struct wl_listener node_destroy;
|
||||
struct wl_listener new_popup;
|
||||
struct wl_listener new_subsurface;
|
||||
|
||||
struct wlr_box geo;
|
||||
bool mapped;
|
||||
struct wlr_box extent;
|
||||
enum zwlr_layer_shell_v1_layer layer;
|
||||
|
||||
struct wl_list subsurfaces;
|
||||
struct wlr_scene_tree *popups;
|
||||
struct sway_popup_desc desc;
|
||||
|
||||
struct sway_output *output;
|
||||
struct wlr_scene_layer_surface_v1 *scene;
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_layer_surface_v1 *layer_surface;
|
||||
};
|
||||
|
||||
struct sway_layer_popup {
|
||||
struct wlr_xdg_popup *wlr_popup;
|
||||
enum layer_parent parent_type;
|
||||
union {
|
||||
struct sway_layer_surface *parent_layer;
|
||||
struct sway_layer_popup *parent_popup;
|
||||
};
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wlr_scene_tree *scene;
|
||||
struct sway_layer_surface *toplevel;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener new_popup;
|
||||
};
|
||||
|
||||
struct sway_layer_subsurface {
|
||||
struct wlr_subsurface *wlr_subsurface;
|
||||
struct sway_layer_surface *layer_surface;
|
||||
struct wl_list link;
|
||||
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
};
|
||||
|
||||
|
@ -61,7 +41,4 @@ struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
|||
|
||||
void arrange_layers(struct sway_output *output);
|
||||
|
||||
struct sway_layer_surface *layer_from_wlr_layer_surface_v1(
|
||||
struct wlr_layer_surface_v1 *layer_surface);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_damage_ring.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "config.h"
|
||||
#include "sway/tree/node.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
@ -19,32 +20,46 @@ struct sway_output_state {
|
|||
|
||||
struct sway_output {
|
||||
struct sway_node node;
|
||||
|
||||
struct {
|
||||
struct wlr_scene_tree *shell_background;
|
||||
struct wlr_scene_tree *shell_bottom;
|
||||
struct wlr_scene_tree *tiling;
|
||||
struct wlr_scene_tree *fullscreen;
|
||||
struct wlr_scene_tree *shell_top;
|
||||
struct wlr_scene_tree *shell_overlay;
|
||||
struct wlr_scene_tree *session_lock;
|
||||
} layers;
|
||||
|
||||
// when a container is fullscreen, in case the fullscreen surface is
|
||||
// translucent (can see behind) we must make sure that the background is a
|
||||
// solid color in order to conform to the wayland protocol. This rect
|
||||
// ensures that when looking through a surface, all that will be seen
|
||||
// is black.
|
||||
struct wlr_scene_rect *fullscreen_background;
|
||||
|
||||
struct wlr_output *wlr_output;
|
||||
struct wlr_scene_output *scene_output;
|
||||
struct sway_server *server;
|
||||
struct wl_list link;
|
||||
|
||||
struct wl_list layers[4]; // sway_layer_surface::link
|
||||
struct wlr_box usable_area;
|
||||
|
||||
struct timespec last_frame;
|
||||
struct wlr_damage_ring damage_ring;
|
||||
|
||||
int lx, ly; // layout coords
|
||||
int width, height; // transformed buffer size
|
||||
enum wl_output_subpixel detected_subpixel;
|
||||
enum scale_filter_mode scale_filter;
|
||||
|
||||
bool enabling, enabled;
|
||||
bool enabled;
|
||||
list_t *workspaces;
|
||||
|
||||
struct sway_output_state current;
|
||||
|
||||
struct wl_listener layout_destroy;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener present;
|
||||
struct wl_listener damage;
|
||||
struct wl_listener frame;
|
||||
struct wl_listener needs_frame;
|
||||
struct wl_listener request_state;
|
||||
|
||||
struct {
|
||||
|
@ -64,14 +79,6 @@ struct sway_output_non_desktop {
|
|||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct render_context {
|
||||
struct sway_output *output;
|
||||
struct wlr_renderer *renderer;
|
||||
const pixman_region32_t *output_damage;
|
||||
|
||||
struct wlr_render_pass *pass;
|
||||
};
|
||||
|
||||
struct sway_output *output_create(struct wlr_output *wlr_output);
|
||||
|
||||
void output_destroy(struct sway_output *output);
|
||||
|
@ -90,19 +97,6 @@ typedef void (*sway_surface_iterator_func_t)(struct sway_output *output,
|
|||
struct sway_view *view, struct wlr_surface *surface, struct wlr_box *box,
|
||||
void *user_data);
|
||||
|
||||
void output_damage_whole(struct sway_output *output);
|
||||
|
||||
void output_damage_surface(struct sway_output *output, double ox, double oy,
|
||||
struct wlr_surface *surface, bool whole);
|
||||
|
||||
void output_damage_from_view(struct sway_output *output,
|
||||
struct sway_view *view);
|
||||
|
||||
void output_damage_box(struct sway_output *output, struct wlr_box *box);
|
||||
|
||||
void output_damage_whole_container(struct sway_output *output,
|
||||
struct sway_container *con);
|
||||
|
||||
bool output_match_name_or_id(struct sway_output *output,
|
||||
const char *name_or_id);
|
||||
|
||||
|
@ -118,46 +112,8 @@ void output_enable(struct sway_output *output);
|
|||
|
||||
void output_disable(struct sway_output *output);
|
||||
|
||||
bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
|
||||
|
||||
struct sway_workspace *output_get_active_workspace(struct sway_output *output);
|
||||
|
||||
void output_render(struct render_context *ctx);
|
||||
|
||||
void output_surface_for_each_surface(struct sway_output *output,
|
||||
struct wlr_surface *surface, double ox, double oy,
|
||||
sway_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
void output_view_for_each_surface(struct sway_output *output,
|
||||
struct sway_view *view, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
void output_view_for_each_popup_surface(struct sway_output *output,
|
||||
struct sway_view *view, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
void output_layer_for_each_surface(struct sway_output *output,
|
||||
struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
void output_layer_for_each_toplevel_surface(struct sway_output *output,
|
||||
struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
void output_layer_for_each_popup_surface(struct sway_output *output,
|
||||
struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
void output_unmanaged_for_each_surface(struct sway_output *output,
|
||||
struct wl_list *unmanaged, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
#endif
|
||||
|
||||
void output_drag_icons_for_each_surface(struct sway_output *output,
|
||||
struct wl_list *drag_icons, sway_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
|
||||
void output_for_each_workspace(struct sway_output *output,
|
||||
void (*f)(struct sway_workspace *ws, void *data), void *data);
|
||||
|
||||
|
@ -175,13 +131,6 @@ void output_get_box(struct sway_output *output, struct wlr_box *box);
|
|||
enum sway_container_layout output_get_default_layout(
|
||||
struct sway_output *output);
|
||||
|
||||
void render_rect(struct render_context *ctx, const struct wlr_box *_box,
|
||||
float color[static 4]);
|
||||
|
||||
void premultiply_alpha(float color[4], float opacity);
|
||||
|
||||
void scale_box(struct wlr_box *box, float scale);
|
||||
|
||||
enum wlr_direction opposite_direction(enum wlr_direction d);
|
||||
|
||||
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* Across a wayland compositor, there are multiple shells: It can be
|
||||
* a toplevel, or a layer_shell, or even something more meta like a drag
|
||||
* icon or highlight indicators when dragging windows around.
|
||||
*
|
||||
* This object lets us store values that represent these modes of operation
|
||||
* and keep track of what object is being represented.
|
||||
*/
|
||||
#ifndef _SWAY_SCENE_DESCRIPTOR_H
|
||||
#define _SWAY_SCENE_DESCRIPTOR_H
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
enum sway_scene_descriptor_type {
|
||||
SWAY_SCENE_DESC_BUFFER_TIMER,
|
||||
SWAY_SCENE_DESC_NON_INTERACTIVE,
|
||||
SWAY_SCENE_DESC_CONTAINER,
|
||||
SWAY_SCENE_DESC_VIEW,
|
||||
SWAY_SCENE_DESC_LAYER_SHELL,
|
||||
SWAY_SCENE_DESC_XWAYLAND_UNMANAGED,
|
||||
SWAY_SCENE_DESC_POPUP,
|
||||
SWAY_SCENE_DESC_DRAG_ICON,
|
||||
};
|
||||
|
||||
bool scene_descriptor_assign(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type, void *data);
|
||||
|
||||
void *scene_descriptor_try_get(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type);
|
||||
|
||||
void scene_descriptor_destroy(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type);
|
||||
|
||||
#endif
|
|
@ -2,23 +2,6 @@
|
|||
#define _SWAY_SERVER_H
|
||||
#include <stdbool.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_input_method_v2.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_drm_lease_v1.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||
#include <wlr/types/wlr_presentation_time.h>
|
||||
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_text_input_v3.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include "config.h"
|
||||
#include "list.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
|
@ -28,6 +11,19 @@
|
|||
|
||||
struct sway_transaction;
|
||||
|
||||
struct sway_session_lock {
|
||||
struct wlr_session_lock_v1 *lock;
|
||||
struct wlr_surface *focused;
|
||||
bool abandoned;
|
||||
|
||||
struct wl_list outputs; // struct sway_session_lock_output
|
||||
|
||||
// invalid if the session is abandoned
|
||||
struct wl_listener new_surface;
|
||||
struct wl_listener unlock;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct sway_server {
|
||||
struct wl_display *wl_display;
|
||||
struct wl_event_loop *wl_event_loop;
|
||||
|
@ -41,7 +37,6 @@ struct sway_server {
|
|||
struct wlr_allocator *allocator;
|
||||
|
||||
struct wlr_compositor *compositor;
|
||||
struct wl_listener compositor_new_surface;
|
||||
|
||||
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1;
|
||||
|
||||
|
@ -51,6 +46,7 @@ struct sway_server {
|
|||
|
||||
struct wl_listener new_output;
|
||||
struct wl_listener output_layout_change;
|
||||
struct wl_listener renderer_lost;
|
||||
|
||||
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
||||
struct sway_idle_inhibit_manager_v1 idle_inhibit_manager_v1;
|
||||
|
@ -59,7 +55,7 @@ struct sway_server {
|
|||
struct wl_listener layer_shell_surface;
|
||||
|
||||
struct wlr_xdg_shell *xdg_shell;
|
||||
struct wl_listener xdg_shell_surface;
|
||||
struct wl_listener xdg_shell_toplevel;
|
||||
|
||||
struct wlr_tablet_manager_v2 *tablet_v2;
|
||||
|
||||
|
@ -82,8 +78,6 @@ struct sway_server {
|
|||
struct wlr_drm_lease_v1_manager *drm_lease_manager;
|
||||
struct wl_listener drm_lease_request;
|
||||
|
||||
struct wlr_presentation *presentation;
|
||||
|
||||
struct wlr_pointer_constraints_v1 *pointer_constraints;
|
||||
struct wl_listener pointer_constraint;
|
||||
|
||||
|
@ -95,15 +89,9 @@ struct sway_server {
|
|||
struct wl_listener gamma_control_set_gamma;
|
||||
|
||||
struct {
|
||||
bool locked;
|
||||
struct sway_session_lock *lock;
|
||||
struct wlr_session_lock_manager_v1 *manager;
|
||||
|
||||
struct wlr_session_lock_v1 *lock;
|
||||
struct wlr_surface *focused;
|
||||
struct wl_listener lock_new_surface;
|
||||
struct wl_listener lock_unlock;
|
||||
struct wl_listener lock_destroy;
|
||||
|
||||
struct wl_listener new_lock;
|
||||
struct wl_listener manager_destroy;
|
||||
} session_lock;
|
||||
|
@ -112,6 +100,7 @@ struct sway_server {
|
|||
struct wl_listener output_power_manager_set_mode;
|
||||
struct wlr_input_method_manager_v2 *input_method;
|
||||
struct wlr_text_input_manager_v3 *text_input;
|
||||
struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list;
|
||||
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
||||
struct wlr_content_type_manager_v1 *content_type_manager_v1;
|
||||
struct wlr_data_control_manager_v1 *data_control_manager_v1;
|
||||
|
@ -152,17 +141,13 @@ struct sway_debug {
|
|||
bool noatomic; // Ignore atomic layout updates
|
||||
bool txn_timings; // Log verbose messages about transactions
|
||||
bool txn_wait; // Always wait for the timeout before applying
|
||||
bool noscanout; // Disable direct scan-out
|
||||
|
||||
enum {
|
||||
DAMAGE_DEFAULT, // Default behaviour
|
||||
DAMAGE_HIGHLIGHT, // Highlight regions of the screen being damaged
|
||||
DAMAGE_RERENDER, // Render the full output when any damage occurs
|
||||
} damage;
|
||||
bool legacy_wl_drm; // Enable the legacy wl_drm interface
|
||||
};
|
||||
|
||||
extern struct sway_debug debug;
|
||||
|
||||
extern bool allow_unsupported_gpu;
|
||||
|
||||
bool server_init(struct sway_server *server);
|
||||
void server_fini(struct sway_server *server);
|
||||
bool server_start(struct sway_server *server);
|
||||
|
@ -170,13 +155,16 @@ void server_run(struct sway_server *server);
|
|||
|
||||
void restore_nofile_limit(void);
|
||||
|
||||
void handle_compositor_new_surface(struct wl_listener *listener, void *data);
|
||||
void handle_new_output(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
||||
void handle_layer_shell_surface(struct wl_listener *listener, void *data);
|
||||
void sway_session_lock_init(void);
|
||||
void handle_xdg_shell_surface(struct wl_listener *listener, void *data);
|
||||
void sway_session_lock_add_output(struct sway_session_lock *lock,
|
||||
struct sway_output *output);
|
||||
bool sway_session_lock_has_surface(struct sway_session_lock *lock,
|
||||
struct wlr_surface *surface);
|
||||
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data);
|
||||
#if HAVE_XWAYLAND
|
||||
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
||||
#endif
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef _SWAY_SURFACE_H
|
||||
#define _SWAY_SURFACE_H
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
|
||||
struct sway_surface {
|
||||
struct wlr_surface *wlr_surface;
|
||||
|
||||
struct wl_listener destroy;
|
||||
|
||||
/**
|
||||
* This timer can be used for issuing delayed frame done callbacks (for
|
||||
* example, to improve presentation latency). Its handler is set to a
|
||||
* function that issues a frame done callback to this surface.
|
||||
*/
|
||||
struct wl_event_source *frame_done_timer;
|
||||
};
|
||||
|
||||
void surface_update_outputs(struct wlr_surface *surface);
|
||||
void surface_enter_output(struct wlr_surface *surface,
|
||||
struct sway_output *output);
|
||||
void surface_leave_output(struct wlr_surface *surface,
|
||||
struct sway_output *output);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _SWAY_BUFFER_H
|
||||
#define _SWAY_BUFFER_H
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
struct sway_text_node {
|
||||
int width;
|
||||
int max_width;
|
||||
int height;
|
||||
int baseline;
|
||||
bool pango_markup;
|
||||
float color[4];
|
||||
float background[4];
|
||||
|
||||
struct wlr_scene_node *node;
|
||||
};
|
||||
|
||||
struct sway_text_node *sway_text_node_create(struct wlr_scene_tree *parent,
|
||||
char *text, float color[4], bool pango_markup);
|
||||
|
||||
void sway_text_node_set_color(struct sway_text_node *node, float color[4]);
|
||||
|
||||
void sway_text_node_set_text(struct sway_text_node *node, char *text);
|
||||
|
||||
void sway_text_node_set_max_width(struct sway_text_node *node, int max_width);
|
||||
|
||||
void sway_text_node_set_background(struct sway_text_node *node, float background[4]);
|
||||
|
||||
#endif
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "list.h"
|
||||
#include "sway/tree/node.h"
|
||||
|
||||
|
@ -68,11 +69,39 @@ struct sway_container {
|
|||
struct sway_node node;
|
||||
struct sway_view *view;
|
||||
|
||||
struct wlr_scene_tree *scene_tree;
|
||||
|
||||
struct {
|
||||
struct wlr_scene_tree *tree;
|
||||
|
||||
struct wlr_scene_tree *border;
|
||||
struct wlr_scene_tree *background;
|
||||
|
||||
struct sway_text_node *title_text;
|
||||
struct sway_text_node *marks_text;
|
||||
} title_bar;
|
||||
|
||||
struct {
|
||||
struct wlr_scene_tree *tree;
|
||||
|
||||
struct wlr_scene_rect *top;
|
||||
struct wlr_scene_rect *bottom;
|
||||
struct wlr_scene_rect *left;
|
||||
struct wlr_scene_rect *right;
|
||||
} border;
|
||||
|
||||
struct wlr_scene_tree *content_tree;
|
||||
struct wlr_scene_buffer *output_handler;
|
||||
|
||||
struct wl_listener output_enter;
|
||||
struct wl_listener output_leave;
|
||||
|
||||
struct sway_container_state current;
|
||||
struct sway_container_state pending;
|
||||
|
||||
char *title; // The view's title (unformatted)
|
||||
char *formatted_title; // The title displayed in the title bar
|
||||
int title_width;
|
||||
|
||||
enum sway_container_layout prev_split_layout;
|
||||
|
||||
|
@ -100,14 +129,6 @@ struct sway_container {
|
|||
double child_total_width;
|
||||
double child_total_height;
|
||||
|
||||
// In most cases this is the same as the content x and y, but if the view
|
||||
// refuses to resize to the content dimensions then it can be smaller.
|
||||
// These are in layout coordinates.
|
||||
double surface_x, surface_y;
|
||||
|
||||
// Outputs currently being intersected
|
||||
list_t *outputs; // struct sway_output
|
||||
|
||||
// Indicates that the container is a scratchpad container.
|
||||
// Both hidden and visible scratchpad containers have scratchpad=true.
|
||||
// Hidden scratchpad containers have a NULL parent.
|
||||
|
@ -120,18 +141,7 @@ struct sway_container {
|
|||
|
||||
float alpha;
|
||||
|
||||
struct wlr_texture *title_focused;
|
||||
struct wlr_texture *title_focused_inactive;
|
||||
struct wlr_texture *title_focused_tab_title;
|
||||
struct wlr_texture *title_unfocused;
|
||||
struct wlr_texture *title_urgent;
|
||||
|
||||
list_t *marks; // char *
|
||||
struct wlr_texture *marks_focused;
|
||||
struct wlr_texture *marks_focused_inactive;
|
||||
struct wlr_texture *marks_focused_tab_title;
|
||||
struct wlr_texture *marks_unfocused;
|
||||
struct wlr_texture *marks_urgent;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
|
@ -151,19 +161,6 @@ void container_begin_destroy(struct sway_container *con);
|
|||
struct sway_container *container_find_child(struct sway_container *container,
|
||||
bool (*test)(struct sway_container *view, void *data), void *data);
|
||||
|
||||
/**
|
||||
* Find a container at the given coordinates. Returns the surface and
|
||||
* surface-local coordinates of the given layout coordinates if the container
|
||||
* is a view and the view contains a surface at those coordinates.
|
||||
*/
|
||||
struct sway_container *container_at(struct sway_workspace *workspace,
|
||||
double lx, double ly, struct wlr_surface **surface,
|
||||
double *sx, double *sy);
|
||||
|
||||
struct sway_container *tiling_container_at(
|
||||
struct sway_node *parent, double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy);
|
||||
|
||||
void container_for_each_child(struct sway_container *container,
|
||||
void (*f)(struct sway_container *container, void *data), void *data);
|
||||
|
||||
|
@ -180,13 +177,13 @@ bool container_has_ancestor(struct sway_container *container,
|
|||
|
||||
void container_update_textures_recursive(struct sway_container *con);
|
||||
|
||||
void container_damage_whole(struct sway_container *container);
|
||||
|
||||
void container_reap_empty(struct sway_container *con);
|
||||
|
||||
struct sway_container *container_flatten(struct sway_container *container);
|
||||
|
||||
void container_update_title_textures(struct sway_container *container);
|
||||
void container_update_title_bar(struct sway_container *container);
|
||||
|
||||
void container_update_marks(struct sway_container *container);
|
||||
|
||||
size_t container_build_representation(enum sway_container_layout layout,
|
||||
list_t *children, char *buffer);
|
||||
|
@ -222,11 +219,6 @@ void container_set_geometry_from_content(struct sway_container *con);
|
|||
*/
|
||||
bool container_is_floating(struct sway_container *container);
|
||||
|
||||
/**
|
||||
* Same as above, but for current container state.
|
||||
*/
|
||||
bool container_is_current_floating(struct sway_container *container);
|
||||
|
||||
/**
|
||||
* Get a container's box in layout coordinates.
|
||||
*/
|
||||
|
@ -289,26 +281,12 @@ bool container_is_floating_or_child(struct sway_container *container);
|
|||
*/
|
||||
bool container_is_fullscreen_or_child(struct sway_container *container);
|
||||
|
||||
/**
|
||||
* Return the output which will be used for scale purposes.
|
||||
* This is the most recently entered output.
|
||||
* If the container is not on any output, return NULL.
|
||||
*/
|
||||
struct sway_output *container_get_effective_output(struct sway_container *con);
|
||||
|
||||
void container_discover_outputs(struct sway_container *con);
|
||||
|
||||
enum sway_container_layout container_parent_layout(struct sway_container *con);
|
||||
|
||||
enum sway_container_layout container_current_parent_layout(
|
||||
struct sway_container *con);
|
||||
|
||||
list_t *container_get_siblings(struct sway_container *container);
|
||||
|
||||
int container_sibling_index(struct sway_container *child);
|
||||
|
||||
list_t *container_get_current_siblings(struct sway_container *container);
|
||||
|
||||
void container_handle_fullscreen_reparent(struct sway_container *con);
|
||||
|
||||
void container_add_child(struct sway_container *parent,
|
||||
|
@ -356,8 +334,6 @@ bool container_has_mark(struct sway_container *container, char *mark);
|
|||
|
||||
void container_add_mark(struct sway_container *container, char *mark);
|
||||
|
||||
void container_update_marks_textures(struct sway_container *container);
|
||||
|
||||
void container_raise_floating(struct sway_container *con);
|
||||
|
||||
bool container_is_scratchpad_hidden(struct sway_container *con);
|
||||
|
@ -381,4 +357,10 @@ bool container_is_sticky_or_child(struct sway_container *con);
|
|||
*/
|
||||
int container_squash(struct sway_container *con);
|
||||
|
||||
void container_arrange_title_bar(struct sway_container *con);
|
||||
|
||||
void container_update(struct sway_container *con);
|
||||
|
||||
void container_update_itself_and_parents(struct sway_container *con);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _SWAY_NODE_H
|
||||
#include <wayland-server-core.h>
|
||||
#include <stdbool.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "list.h"
|
||||
|
||||
#define MIN_SANE_W 100
|
||||
|
@ -75,4 +76,15 @@ list_t *node_get_children(struct sway_node *node);
|
|||
|
||||
bool node_has_ancestor(struct sway_node *node, struct sway_node *ancestor);
|
||||
|
||||
// when destroying a sway tree, it's not known which order the tree will be
|
||||
// destroyed. To prevent freeing of scene_nodes recursing up the tree,
|
||||
// let's use this helper function to disown them to the staging node.
|
||||
void scene_node_disown_children(struct wlr_scene_tree *tree);
|
||||
|
||||
// a helper function used to allocate tree nodes. If an allocation failure
|
||||
// occurs a flag is flipped that can be checked later to destroy a parent
|
||||
// of this scene node preventing memory leaks.
|
||||
struct wlr_scene_tree *alloc_scene_tree(struct wlr_scene_tree *parent,
|
||||
bool *failed);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wayland-util.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/node.h"
|
||||
|
@ -16,10 +17,44 @@ struct sway_root {
|
|||
struct wlr_output_layout *output_layout;
|
||||
|
||||
struct wl_listener output_layout_change;
|
||||
|
||||
// scene node layout:
|
||||
// - root
|
||||
// - staging
|
||||
// - layer shell stuff
|
||||
// - tiling
|
||||
// - floating
|
||||
// - fullscreen stuff
|
||||
// - seat stuff
|
||||
// - ext_session_lock
|
||||
struct wlr_scene *root_scene;
|
||||
|
||||
// since wlr_scene nodes can't be orphaned and must always
|
||||
// have a parent, use this staging scene_tree so that a
|
||||
// node always have a valid parent. Nothing in this
|
||||
// staging node will be visible.
|
||||
struct wlr_scene_tree *staging;
|
||||
|
||||
// tree containing all layers the compositor will render. Cursor handling
|
||||
// will end up iterating this tree.
|
||||
struct wlr_scene_tree *layer_tree;
|
||||
|
||||
struct {
|
||||
struct wlr_scene_tree *shell_background;
|
||||
struct wlr_scene_tree *shell_bottom;
|
||||
struct wlr_scene_tree *tiling;
|
||||
struct wlr_scene_tree *floating;
|
||||
struct wlr_scene_tree *shell_top;
|
||||
struct wlr_scene_tree *fullscreen;
|
||||
struct wlr_scene_tree *fullscreen_global;
|
||||
#if HAVE_XWAYLAND
|
||||
struct wl_list xwayland_unmanaged; // sway_xwayland_unmanaged::link
|
||||
struct wlr_scene_tree *unmanaged;
|
||||
#endif
|
||||
struct wl_list drag_icons; // sway_drag_icon::link
|
||||
struct wlr_scene_tree *shell_overlay;
|
||||
struct wlr_scene_tree *popup;
|
||||
struct wlr_scene_tree *seat;
|
||||
struct wlr_scene_tree *session_lock;
|
||||
} layers;
|
||||
|
||||
// Includes disabled outputs
|
||||
struct wl_list all_outputs; // sway_output::link
|
||||
|
@ -41,7 +76,7 @@ struct sway_root {
|
|||
} events;
|
||||
};
|
||||
|
||||
struct sway_root *root_create(void);
|
||||
struct sway_root *root_create(struct wl_display *display);
|
||||
|
||||
void root_destroy(struct sway_root *root);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _SWAY_VIEW_H
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "sway/config.h"
|
||||
#if HAVE_XWAYLAND
|
||||
#include <wlr/xwayland.h>
|
||||
|
@ -45,10 +46,6 @@ struct sway_view_impl {
|
|||
void (*set_fullscreen)(struct sway_view *view, bool fullscreen);
|
||||
void (*set_resizing)(struct sway_view *view, bool resizing);
|
||||
bool (*wants_floating)(struct sway_view *view);
|
||||
void (*for_each_surface)(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
void (*for_each_popup_surface)(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
bool (*is_transient_for)(struct sway_view *child,
|
||||
struct sway_view *ancestor);
|
||||
void (*close)(struct sway_view *view);
|
||||
|
@ -56,19 +53,14 @@ struct sway_view_impl {
|
|||
void (*destroy)(struct sway_view *view);
|
||||
};
|
||||
|
||||
struct sway_saved_buffer {
|
||||
struct wlr_client_buffer *buffer;
|
||||
int x, y;
|
||||
int width, height;
|
||||
enum wl_output_transform transform;
|
||||
struct wlr_fbox source_box;
|
||||
struct wl_list link; // sway_view::saved_buffers
|
||||
};
|
||||
|
||||
struct sway_view {
|
||||
enum sway_view_type type;
|
||||
const struct sway_view_impl *impl;
|
||||
|
||||
struct wlr_scene_tree *scene_tree;
|
||||
struct wlr_scene_tree *content_tree;
|
||||
struct wlr_scene_tree *saved_surface_tree;
|
||||
|
||||
struct sway_container *container; // NULL if unmapped and transactions finished
|
||||
struct wlr_surface *surface; // NULL for unmapped views
|
||||
struct sway_xdg_decoration *xdg_decoration;
|
||||
|
@ -88,15 +80,11 @@ struct sway_view {
|
|||
bool allow_request_urgent;
|
||||
struct wl_event_source *urgent_timer;
|
||||
|
||||
struct wl_list saved_buffers; // sway_saved_buffer::link
|
||||
|
||||
// The geometry for whatever the client is committing, regardless of
|
||||
// transaction state. Updated on every commit.
|
||||
struct wlr_box geometry;
|
||||
|
||||
// The "old" geometry during a transaction. Used to damage the old location
|
||||
// when a transaction is applied.
|
||||
struct wlr_box saved_geometry;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *ext_foreign_toplevel;
|
||||
|
||||
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
|
||||
struct wl_listener foreign_activate_request;
|
||||
|
@ -119,8 +107,6 @@ struct sway_view {
|
|||
struct wl_signal unmap;
|
||||
} events;
|
||||
|
||||
struct wl_listener surface_new_subsurface;
|
||||
|
||||
int max_render_time; // In milliseconds
|
||||
|
||||
enum seat_config_shortcuts_inhibit shortcuts_inhibit;
|
||||
|
@ -145,6 +131,8 @@ struct sway_xdg_shell_view {
|
|||
struct sway_xwayland_view {
|
||||
struct sway_view view;
|
||||
|
||||
struct wlr_scene_tree *surface_tree;
|
||||
|
||||
struct wl_listener commit;
|
||||
struct wl_listener request_move;
|
||||
struct wl_listener request_resize;
|
||||
|
@ -166,18 +154,18 @@ struct sway_xwayland_view {
|
|||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener override_redirect;
|
||||
|
||||
struct wl_listener surface_tree_destroy;
|
||||
};
|
||||
|
||||
struct sway_xwayland_unmanaged {
|
||||
struct wlr_xwayland_surface *wlr_xwayland_surface;
|
||||
struct wl_list link;
|
||||
|
||||
int lx, ly;
|
||||
struct wlr_scene_surface *surface_scene;
|
||||
|
||||
struct wl_listener request_activate;
|
||||
struct wl_listener request_configure;
|
||||
struct wl_listener request_fullscreen;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener set_geometry;
|
||||
struct wl_listener associate;
|
||||
struct wl_listener dissociate;
|
||||
|
@ -187,46 +175,24 @@ struct sway_xwayland_unmanaged {
|
|||
struct wl_listener override_redirect;
|
||||
};
|
||||
#endif
|
||||
struct sway_view_child;
|
||||
|
||||
struct sway_view_child_impl {
|
||||
void (*get_view_coords)(struct sway_view_child *child, int *sx, int *sy);
|
||||
void (*destroy)(struct sway_view_child *child);
|
||||
};
|
||||
|
||||
/**
|
||||
* A view child is a surface in the view tree, such as a subsurface or a popup.
|
||||
*/
|
||||
struct sway_view_child {
|
||||
const struct sway_view_child_impl *impl;
|
||||
struct wl_list link;
|
||||
|
||||
struct sway_popup_desc {
|
||||
struct wlr_scene_node *relative;
|
||||
struct sway_view *view;
|
||||
struct sway_view_child *parent;
|
||||
struct wl_list children; // sway_view_child::link
|
||||
struct wlr_surface *surface;
|
||||
bool mapped;
|
||||
|
||||
struct wl_listener surface_commit;
|
||||
struct wl_listener surface_new_subsurface;
|
||||
struct wl_listener surface_map;
|
||||
struct wl_listener surface_unmap;
|
||||
struct wl_listener surface_destroy;
|
||||
struct wl_listener view_unmap;
|
||||
};
|
||||
|
||||
struct sway_subsurface {
|
||||
struct sway_view_child child;
|
||||
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct sway_xdg_popup {
|
||||
struct sway_view_child child;
|
||||
struct sway_view *view;
|
||||
|
||||
struct wlr_scene_tree *scene_tree;
|
||||
struct wlr_scene_tree *xdg_surface_tree;
|
||||
struct wlr_xdg_popup *wlr_xdg_popup;
|
||||
|
||||
struct sway_popup_desc desc;
|
||||
|
||||
struct wl_listener surface_commit;
|
||||
struct wl_listener new_popup;
|
||||
struct wl_listener reposition;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
|
@ -277,6 +243,11 @@ void view_set_activated(struct sway_view *view, bool activated);
|
|||
*/
|
||||
void view_request_activate(struct sway_view *view, struct sway_seat *seat);
|
||||
|
||||
/*
|
||||
* Called when the view requests urgent state
|
||||
*/
|
||||
void view_request_urgent(struct sway_view *view);
|
||||
|
||||
/**
|
||||
* If possible, instructs the client to change their decoration mode.
|
||||
*/
|
||||
|
@ -294,23 +265,9 @@ void view_close(struct sway_view *view);
|
|||
|
||||
void view_close_popups(struct sway_view *view);
|
||||
|
||||
void view_damage_from(struct sway_view *view);
|
||||
|
||||
/**
|
||||
* Iterate all surfaces of a view (toplevels + popups).
|
||||
*/
|
||||
void view_for_each_surface(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
/**
|
||||
* Iterate all popup surfaces of a view.
|
||||
*/
|
||||
void view_for_each_popup_surface(struct sway_view *view,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
// view implementation
|
||||
|
||||
void view_init(struct sway_view *view, enum sway_view_type type,
|
||||
bool view_init(struct sway_view *view, enum sway_view_type type,
|
||||
const struct sway_view_impl *impl);
|
||||
|
||||
void view_destroy(struct sway_view *view);
|
||||
|
@ -332,14 +289,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||
void view_unmap(struct sway_view *view);
|
||||
|
||||
void view_update_size(struct sway_view *view);
|
||||
void view_center_surface(struct sway_view *view);
|
||||
|
||||
void view_child_init(struct sway_view_child *child,
|
||||
const struct sway_view_child_impl *impl, struct sway_view *view,
|
||||
struct wlr_surface *surface);
|
||||
|
||||
void view_child_destroy(struct sway_view_child *child);
|
||||
|
||||
void view_center_and_clip_surface(struct sway_view *view);
|
||||
|
||||
struct sway_view *view_from_wlr_xdg_surface(
|
||||
struct wlr_xdg_surface *xdg_surface);
|
||||
|
@ -349,6 +299,8 @@ struct sway_view *view_from_wlr_xwayland_surface(
|
|||
#endif
|
||||
struct sway_view *view_from_wlr_surface(struct wlr_surface *surface);
|
||||
|
||||
void view_update_app_id(struct sway_view *view);
|
||||
|
||||
/**
|
||||
* Re-read the view's title property and update any relevant title bars.
|
||||
* The force argument makes it recreate the title bars even if the title hasn't
|
||||
|
@ -380,4 +332,6 @@ bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor);
|
|||
|
||||
void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx);
|
||||
|
||||
void view_send_frame_done(struct sway_view *view);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _SWAY_WORKSPACE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/node.h"
|
||||
|
@ -23,6 +24,12 @@ struct sway_workspace_state {
|
|||
|
||||
struct sway_workspace {
|
||||
struct sway_node node;
|
||||
|
||||
struct {
|
||||
struct wlr_scene_tree *tiling;
|
||||
struct wlr_scene_tree *fullscreen;
|
||||
} layers;
|
||||
|
||||
struct sway_container *fullscreen;
|
||||
|
||||
char *name;
|
||||
|
|
|
@ -16,4 +16,6 @@ struct sway_xdg_decoration {
|
|||
struct sway_xdg_decoration *xdg_decoration_from_surface(
|
||||
struct wlr_surface *surface);
|
||||
|
||||
void set_xdg_decoration_mode(struct sway_xdg_decoration *deco);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _SWAYBAR_IMAGE_H
|
||||
#define _SWAYBAR_IMAGE_H
|
||||
#include <cairo.h>
|
||||
|
||||
cairo_surface_t *load_image(const char *path);
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'sway',
|
||||
'c',
|
||||
version: '1.9-dev',
|
||||
version: '1.10-dev',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.60.0',
|
||||
default_options: [
|
||||
|
@ -14,6 +14,7 @@ project(
|
|||
add_project_arguments(
|
||||
[
|
||||
'-DWLR_USE_UNSTABLE',
|
||||
'-D_POSIX_C_SOURCE=200809L',
|
||||
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-unused-result',
|
||||
|
@ -37,7 +38,7 @@ if is_freebsd
|
|||
endif
|
||||
|
||||
# Execute the wlroots subproject, if any
|
||||
wlroots_version = ['>=0.17.0', '<0.18.0']
|
||||
wlroots_version = ['>=0.18.0', '<0.19.0']
|
||||
subproject(
|
||||
'wlroots',
|
||||
default_options: ['examples=false'],
|
||||
|
@ -77,8 +78,7 @@ pixman = dependency('pixman-1')
|
|||
libevdev = dependency('libevdev')
|
||||
libinput = wlroots_features['libinput_backend'] ? dependency('libinput', version: '>=1.21.0') : null_dep
|
||||
xcb = dependency('xcb', required: get_option('xwayland'))
|
||||
drm_full = dependency('libdrm') # only needed for drm_fourcc.h
|
||||
drm = drm_full.partial_dependency(compile_args: true, includes: true)
|
||||
drm = dependency('libdrm')
|
||||
libudev = wlroots_features['libinput_backend'] ? dependency('libudev') : null_dep
|
||||
math = cc.find_library('m')
|
||||
rt = cc.find_library('rt')
|
||||
|
|
|
@ -6,6 +6,6 @@ option('swaybar', type: 'boolean', value: true, description: 'Enable support for
|
|||
option('swaynag', type: 'boolean', value: true, description: 'Enable support for swaynag')
|
||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||
option('tray', type: 'feature', value: 'auto', description: 'Enable support for swaybar tray')
|
||||
option('gdk-pixbuf', type: 'feature', value: 'auto', description: 'Enable support for more image formats in swaybg')
|
||||
option('gdk-pixbuf', type: 'feature', value: 'auto', description: 'Enable support for more image formats in swaybar tray')
|
||||
option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
|
||||
option('sd-bus-provider', type: 'combo', choices: ['auto', 'libsystemd', 'libelogind', 'basu'], value: 'auto', description: 'Provider of the sd-bus library')
|
||||
|
|
|
@ -16,7 +16,6 @@ protocols = [
|
|||
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
'wlr-layer-shell-unstable-v1.xml',
|
||||
'idle.xml',
|
||||
'wlr-input-inhibitor-unstable-v1.xml',
|
||||
'wlr-output-power-management-unstable-v1.xml',
|
||||
]
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_input_inhibit_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2018 Drew DeVault
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_input_inhibit_manager_v1" version="1">
|
||||
<description summary="inhibits input events to other clients">
|
||||
Clients can use this interface to prevent input events from being sent to
|
||||
any surfaces but its own, which is useful for example in lock screen
|
||||
software. It is assumed that access to this interface will be locked down
|
||||
to whitelisted clients by the compositor.
|
||||
</description>
|
||||
|
||||
<request name="get_inhibitor">
|
||||
<description summary="inhibit input to other clients">
|
||||
Activates the input inhibitor. As long as the inhibitor is active, the
|
||||
compositor will not send input events to other clients.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_input_inhibitor_v1"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_inhibited" value="0" summary="an input inhibitor is already in use on the compositor"/>
|
||||
</enum>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_input_inhibitor_v1" version="1">
|
||||
<description summary="inhibits input to other clients">
|
||||
While this resource exists, input to clients other than the owner of the
|
||||
inhibitor resource will not receive input events. The client that owns
|
||||
this resource will receive all input events normally. The compositor will
|
||||
also disable all of its own input processing (such as keyboard shortcuts)
|
||||
while the inhibitor is active.
|
||||
|
||||
The compositor may continue to send input events to selected clients,
|
||||
such as an on-screen keyboard (via the input-method protocol).
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the input inhibitor object">
|
||||
Destroy the inhibitor and allow other clients to receive input.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/sh -eu
|
||||
|
||||
prev=$(git describe --tags --abbrev=0)
|
||||
next=$(meson rewrite kwargs info project / 2>&1 >/dev/null | jq -r '.kwargs["project#/"].version')
|
||||
|
||||
case "$next" in
|
||||
*-dev)
|
||||
echo "This is a development version"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$prev" = "$next" ]; then
|
||||
echo "Version not bumped in meson.build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git diff-index --quiet HEAD -- meson.build; then
|
||||
echo "meson.build not committed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shortlog="$(git shortlog --no-merges "$prev..")"
|
||||
(echo "sway $next"; echo ""; echo "$shortlog") | git tag "$next" -ase -F -
|
||||
|
||||
prefix=sway-$next
|
||||
archive=$prefix.tar.gz
|
||||
git archive --prefix="$prefix/" -o "$archive" "$next"
|
||||
gpg --output "$archive".sig --detach-sig "$archive"
|
||||
|
||||
gh release create "sway $next" -t "$next" -n "" -d "$archive" "$archive.sig"
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -82,7 +81,6 @@ static const struct cmd_handler handlers[] = {
|
|||
{ "no_focus", cmd_no_focus },
|
||||
{ "output", cmd_output },
|
||||
{ "popup_during_fullscreen", cmd_popup_during_fullscreen },
|
||||
{ "primary_selection", cmd_primary_selection },
|
||||
{ "seat", cmd_seat },
|
||||
{ "set", cmd_set },
|
||||
{ "show_marks", cmd_show_marks },
|
||||
|
@ -105,6 +103,7 @@ static const struct cmd_handler handlers[] = {
|
|||
static const struct cmd_handler config_handlers[] = {
|
||||
{ "default_orientation", cmd_default_orientation },
|
||||
{ "include", cmd_include },
|
||||
{ "primary_selection", cmd_primary_selection },
|
||||
{ "swaybg_command", cmd_swaybg_command },
|
||||
{ "swaynag_command", cmd_swaynag_command },
|
||||
{ "workspace_layout", cmd_workspace_layout },
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <libevdev/libevdev.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
#include "sway/tree/container.h"
|
||||
#include "util.h"
|
||||
|
||||
static void rebuild_textures_iterator(struct sway_container *con, void *data) {
|
||||
container_update_marks_textures(con);
|
||||
container_update_title_textures(con);
|
||||
static void container_update_iterator(struct sway_container *con, void *data) {
|
||||
container_update(con);
|
||||
}
|
||||
|
||||
static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
|
||||
|
@ -51,12 +50,7 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
|
|||
memcpy(class, &colors, sizeof(struct border_colors));
|
||||
|
||||
if (config->active) {
|
||||
root_for_each_container(rebuild_textures_iterator, NULL);
|
||||
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
output_damage_whole(output);
|
||||
}
|
||||
root_for_each_container(container_update_iterator, NULL);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
|
||||
#include "gesture.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "util.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <assert.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
@ -59,7 +58,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
|
|||
}
|
||||
|
||||
free(mark);
|
||||
container_update_marks_textures(container);
|
||||
container_update_marks(container);
|
||||
if (container->view) {
|
||||
view_execute_criteria(container->view);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -770,15 +769,6 @@ static struct cmd_results *cmd_move_in_direction(
|
|||
ipc_event_window(container, "move");
|
||||
}
|
||||
|
||||
// Hack to re-focus container
|
||||
seat_set_raw_focus(config->handler_context.seat, &new_ws->node);
|
||||
seat_set_focus_container(config->handler_context.seat, container);
|
||||
|
||||
if (old_ws != new_ws) {
|
||||
ipc_event_workspace(old_ws, new_ws, "focus");
|
||||
workspace_detect_urgent(old_ws);
|
||||
workspace_detect_urgent(new_ws);
|
||||
}
|
||||
container_end_mouse_operation(container);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
|
|
|
@ -37,6 +37,7 @@ struct cmd_results *cmd_opacity(int argc, char **argv) {
|
|||
}
|
||||
|
||||
con->alpha = val;
|
||||
container_damage_whole(con);
|
||||
container_update(con);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
|
@ -103,15 +103,18 @@ struct cmd_results *cmd_output(int argc, char **argv) {
|
|||
|
||||
bool background = output->background;
|
||||
|
||||
output = store_output_config(output);
|
||||
store_output_config(output);
|
||||
|
||||
// If reloading, the output configs will be applied after reading the
|
||||
// entire config and before the deferred commands so that an auto generated
|
||||
// workspace name is not given to re-enabled outputs.
|
||||
if (!config->reloading && !config->validating) {
|
||||
apply_output_config_to_outputs(output);
|
||||
apply_all_output_configs();
|
||||
if (background) {
|
||||
spawn_swaybg();
|
||||
if (!spawn_swaybg()) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Failed to apply background configuration");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -123,7 +122,10 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
src);
|
||||
config_add_swaynag_warning("Unable to access background file '%s'",
|
||||
src);
|
||||
struct cmd_results *result = cmd_results_new(CMD_FAILURE,
|
||||
"unable to access background file '%s'", src);
|
||||
free(src);
|
||||
return result;
|
||||
} else {
|
||||
output->background = src;
|
||||
output->background_option = strdup(mode);
|
||||
|
|
|
@ -29,7 +29,7 @@ struct cmd_results *output_cmd_toggle(int argc, char **argv) {
|
|||
config->handler_context.output_config->enabled = 1;
|
||||
}
|
||||
|
||||
free(oc);
|
||||
free_output_config(oc);
|
||||
config->handler_context.leftovers.argc = argc;
|
||||
config->handler_context.leftovers.argv = argv;
|
||||
return NULL;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <string.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -12,12 +12,14 @@ struct cmd_results *cmd_primary_selection(int argc, char **argv) {
|
|||
|
||||
bool primary_selection = parse_boolean(argv[0], true);
|
||||
|
||||
// config->primary_selection is reset to the previous value on reload in
|
||||
// load_main_config()
|
||||
if (config->reloading && config->primary_selection != primary_selection) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"primary_selection can only be enabled/disabled at launch");
|
||||
}
|
||||
|
||||
config->primary_selection = parse_boolean(argv[0], true);
|
||||
config->primary_selection = primary_selection;
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
@ -9,9 +8,8 @@
|
|||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
||||
static void rebuild_textures_iterator(struct sway_container *con, void *data) {
|
||||
container_update_marks_textures(con);
|
||||
container_update_title_textures(con);
|
||||
static void title_bar_update_iterator(struct sway_container *con, void *data) {
|
||||
container_update_title_bar(con);
|
||||
}
|
||||
|
||||
static void do_reload(void *data) {
|
||||
|
@ -48,7 +46,7 @@ static void do_reload(void *data) {
|
|||
}
|
||||
list_free_items_and_destroy(bar_ids);
|
||||
|
||||
root_for_each_container(rebuild_textures_iterator, NULL);
|
||||
root_for_each_container(title_bar_update_iterator, NULL);
|
||||
|
||||
arrange_root();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <linux/input-event-codes.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
@ -85,12 +84,12 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) {
|
|||
|
||||
static struct cmd_results *press_or_release(struct sway_cursor *cursor,
|
||||
char *action, char *button_str) {
|
||||
enum wlr_button_state state;
|
||||
enum wl_pointer_button_state state;
|
||||
uint32_t button;
|
||||
if (strcasecmp(action, "press") == 0) {
|
||||
state = WLR_BUTTON_PRESSED;
|
||||
state = WL_POINTER_BUTTON_STATE_PRESSED;
|
||||
} else if (strcasecmp(action, "release") == 0) {
|
||||
state = WLR_BUTTON_RELEASED;
|
||||
state = WL_POINTER_BUTTON_STATE_RELEASED;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
|
||||
}
|
||||
|
@ -105,16 +104,16 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor,
|
|||
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN
|
||||
|| button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) {
|
||||
// Dispatch axis event
|
||||
enum wlr_axis_orientation orientation =
|
||||
enum wl_pointer_axis orientation =
|
||||
(button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN)
|
||||
? WLR_AXIS_ORIENTATION_VERTICAL
|
||||
: WLR_AXIS_ORIENTATION_HORIZONTAL;
|
||||
? WL_POINTER_AXIS_VERTICAL_SCROLL
|
||||
: WL_POINTER_AXIS_HORIZONTAL_SCROLL;
|
||||
double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT)
|
||||
? -1 : 1;
|
||||
struct wlr_pointer_axis_event event = {
|
||||
.pointer = NULL,
|
||||
.time_msec = 0,
|
||||
.source = WLR_AXIS_SOURCE_WHEEL,
|
||||
.source = WL_POINTER_AXIS_SOURCE_WHEEL,
|
||||
.orientation = orientation,
|
||||
.delta = delta * 15,
|
||||
.delta_discrete = delta
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
@ -10,8 +9,8 @@
|
|||
#include "stringop.h"
|
||||
#include "util.h"
|
||||
|
||||
static void rebuild_marks_iterator(struct sway_container *con, void *data) {
|
||||
container_update_marks_textures(con);
|
||||
static void title_bar_update_iterator(struct sway_container *con, void *data) {
|
||||
container_update_marks(con);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_show_marks(int argc, char **argv) {
|
||||
|
@ -23,12 +22,7 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) {
|
|||
config->show_marks = parse_boolean(argv[0], config->show_marks);
|
||||
|
||||
if (config->show_marks) {
|
||||
root_for_each_container(rebuild_marks_iterator, NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
output_damage_whole(output);
|
||||
root_for_each_container(title_bar_update_iterator, NULL);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <strings.h>
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/root.h"
|
||||
|
||||
static void arrange_title_bar_iterator(struct sway_container *con, void *data) {
|
||||
container_arrange_title_bar(con);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_title_align(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "title_align", EXPECTED_AT_LEAST, 1))) {
|
||||
|
@ -21,10 +25,7 @@ struct cmd_results *cmd_title_align(int argc, char **argv) {
|
|||
"Expected 'title_align left|center|right'");
|
||||
}
|
||||
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
output_damage_whole(output);
|
||||
}
|
||||
root_for_each_container(arrange_title_bar_iterator, NULL);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
|
|
@ -27,7 +27,6 @@ struct cmd_results *cmd_titlebar_border_thickness(int argc, char **argv) {
|
|||
"Expected output to have a workspace");
|
||||
}
|
||||
arrange_workspace(ws);
|
||||
output_damage_whole(output);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
|
|
|
@ -33,7 +33,6 @@ struct cmd_results *cmd_titlebar_padding(int argc, char **argv) {
|
|||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
arrange_workspace(output_get_active_workspace(output));
|
||||
output_damage_whole(output);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
@ -8,9 +7,13 @@
|
|||
#include "log.h"
|
||||
#include "stringop.h"
|
||||
|
||||
static void remove_all_marks_iterator(struct sway_container *con, void *data) {
|
||||
static void remove_mark(struct sway_container *con) {
|
||||
container_clear_marks(con);
|
||||
container_update_marks_textures(con);
|
||||
container_update_marks(con);
|
||||
}
|
||||
|
||||
static void remove_all_marks_iterator(struct sway_container *con, void *data) {
|
||||
remove_mark(con);
|
||||
}
|
||||
|
||||
// unmark Remove all marks from all views
|
||||
|
@ -38,8 +41,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
|
|||
}
|
||||
} else if (con && !mark) {
|
||||
// Clear all marks from the given container
|
||||
container_clear_marks(con);
|
||||
container_update_marks_textures(con);
|
||||
remove_mark(con);
|
||||
} else if (!con && mark) {
|
||||
// Remove mark from whichever container has it
|
||||
container_find_and_unmark(mark);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -20,6 +20,8 @@ struct cmd_results *cmd_xwayland(int argc, char **argv) {
|
|||
xwayland = XWAYLAND_MODE_DISABLED;
|
||||
}
|
||||
|
||||
// config->xwayland is reset to the previous value on reload in
|
||||
// load_main_config()
|
||||
if (config->reloading && config->xwayland != xwayland) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"xwayland can only be enabled/disabled at launch");
|
||||
|
|
105
sway/config.c
105
sway/config.c
|
@ -1,3 +1,4 @@
|
|||
#undef _POSIX_C_SOURCE
|
||||
#define _XOPEN_SOURCE 700 // for realpath
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -36,19 +37,26 @@
|
|||
struct sway_config *config = NULL;
|
||||
|
||||
static struct xkb_state *keysym_translation_state_create(
|
||||
struct xkb_rule_names rules) {
|
||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV);
|
||||
struct xkb_rule_names rules, uint32_t context_flags) {
|
||||
struct xkb_context *context = xkb_context_new(context_flags | XKB_CONTEXT_NO_SECURE_GETENV);
|
||||
struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names(
|
||||
context,
|
||||
&rules,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
xkb_context_unref(context);
|
||||
if (xkb_keymap == NULL) {
|
||||
sway_log(SWAY_ERROR, "Failed to compile keysym translation XKB keymap");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xkb_state_new(xkb_keymap);
|
||||
}
|
||||
|
||||
static void keysym_translation_state_destroy(
|
||||
struct xkb_state *state) {
|
||||
if (state == NULL) {
|
||||
return;
|
||||
}
|
||||
xkb_keymap_unref(xkb_state_get_keymap(state));
|
||||
xkb_state_unref(state);
|
||||
}
|
||||
|
@ -336,8 +344,14 @@ static void config_defaults(struct sway_config *config) {
|
|||
|
||||
// The keysym to keycode translation
|
||||
struct xkb_rule_names rules = {0};
|
||||
config->keysym_translation_state =
|
||||
keysym_translation_state_create(rules);
|
||||
config->keysym_translation_state = keysym_translation_state_create(rules, 0);
|
||||
if (config->keysym_translation_state == NULL) {
|
||||
config->keysym_translation_state = keysym_translation_state_create(rules,
|
||||
XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
|
||||
}
|
||||
if (config->keysym_translation_state == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return;
|
||||
cleanup:
|
||||
|
@ -352,13 +366,7 @@ static char *config_path(const char *prefix, const char *config_folder) {
|
|||
if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *filename = "config";
|
||||
|
||||
size_t size = 3 + strlen(prefix) + strlen(config_folder) + strlen(filename);
|
||||
char *path = calloc(size, sizeof(char));
|
||||
snprintf(path, size, "%s/%s/%s", prefix, config_folder, filename);
|
||||
return path;
|
||||
return format_str("%s/%s/config", prefix, config_folder);
|
||||
}
|
||||
|
||||
static char *get_config_path(void) {
|
||||
|
@ -368,10 +376,7 @@ static char *get_config_path(void) {
|
|||
|
||||
const char *config_home = getenv("XDG_CONFIG_HOME");
|
||||
if ((config_home == NULL || config_home[0] == '\0') && home != NULL) {
|
||||
size_t size_fallback = 1 + strlen(home) + strlen("/.config");
|
||||
config_home_fallback = calloc(size_fallback, sizeof(char));
|
||||
if (config_home_fallback != NULL)
|
||||
snprintf(config_home_fallback, size_fallback, "%s/.config", home);
|
||||
config_home_fallback = format_str("%s/.config", home);
|
||||
config_home = config_home_fallback;
|
||||
}
|
||||
|
||||
|
@ -475,6 +480,11 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||
old_config->xwayland ? "enabled" : "disabled");
|
||||
config->xwayland = old_config->xwayland;
|
||||
|
||||
// primary_selection can only be enabled/disabled at launch
|
||||
sway_log(SWAY_DEBUG, "primary_selection will remain %s",
|
||||
old_config->primary_selection ? "enabled" : "disabled");
|
||||
config->primary_selection = old_config->primary_selection;
|
||||
|
||||
if (!config->validating) {
|
||||
if (old_config->swaybg_client != NULL) {
|
||||
wl_client_destroy(old_config->swaybg_client);
|
||||
|
@ -494,56 +504,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||
|
||||
config->reading = true;
|
||||
|
||||
// Read security configs
|
||||
// TODO: Security
|
||||
bool success = true;
|
||||
/*
|
||||
DIR *dir = opendir(SYSCONFDIR "/sway/security.d");
|
||||
if (!dir) {
|
||||
sway_log(SWAY_ERROR,
|
||||
"%s does not exist, sway will have no security configuration"
|
||||
" and will probably be broken", SYSCONFDIR "/sway/security.d");
|
||||
} else {
|
||||
list_t *secconfigs = create_list();
|
||||
char *base = SYSCONFDIR "/sway/security.d/";
|
||||
struct dirent *ent = readdir(dir);
|
||||
struct stat s;
|
||||
while (ent != NULL) {
|
||||
char *_path = malloc(strlen(ent->d_name) + strlen(base) + 1);
|
||||
strcpy(_path, base);
|
||||
strcat(_path, ent->d_name);
|
||||
lstat(_path, &s);
|
||||
if (S_ISREG(s.st_mode) && ent->d_name[0] != '.') {
|
||||
list_add(secconfigs, _path);
|
||||
}
|
||||
else {
|
||||
free(_path);
|
||||
}
|
||||
ent = readdir(dir);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
list_qsort(secconfigs, qstrcmp);
|
||||
for (int i = 0; i < secconfigs->length; ++i) {
|
||||
char *_path = secconfigs->items[i];
|
||||
if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 ||
|
||||
(((s.st_mode & 0777) != 0644) &&
|
||||
(s.st_mode & 0777) != 0444)) {
|
||||
sway_log(SWAY_ERROR,
|
||||
"Refusing to load %s - it must be owned by root "
|
||||
"and mode 644 or 444", _path);
|
||||
success = false;
|
||||
} else {
|
||||
success = success && load_config(_path, config);
|
||||
}
|
||||
}
|
||||
|
||||
list_free_items_and_destroy(secconfigs);
|
||||
}
|
||||
*/
|
||||
|
||||
success = success && load_config(path, config,
|
||||
&config->swaynag_config_errors);
|
||||
bool success = load_config(path, config, &config->swaynag_config_errors);
|
||||
|
||||
if (validating) {
|
||||
free_config(config);
|
||||
|
@ -571,7 +532,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||
}
|
||||
sway_switch_retrigger_bindings_for_all();
|
||||
|
||||
reset_outputs();
|
||||
apply_all_output_configs();
|
||||
spawn_swaybg();
|
||||
|
||||
config->reloading = false;
|
||||
|
@ -975,7 +936,7 @@ char *do_var_replacement(char *str) {
|
|||
int offset = find - str;
|
||||
strncpy(newptr, str, offset);
|
||||
newptr += offset;
|
||||
strncpy(newptr, var->value, vvlen);
|
||||
memcpy(newptr, var->value, vvlen);
|
||||
newptr += vvlen;
|
||||
strcpy(newptr, find + vnlen);
|
||||
free(str);
|
||||
|
@ -1037,8 +998,12 @@ void translate_keysyms(struct input_config *input_config) {
|
|||
|
||||
struct xkb_rule_names rules = {0};
|
||||
input_config_fill_rule_names(input_config, &rules);
|
||||
config->keysym_translation_state =
|
||||
keysym_translation_state_create(rules);
|
||||
config->keysym_translation_state = keysym_translation_state_create(rules, 0);
|
||||
if (config->keysym_translation_state == NULL) {
|
||||
sway_log(SWAY_ERROR, "Failed to create keysym translation XKB state "
|
||||
"for device '%s'", input_config->identifier);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < config->modes->length; ++i) {
|
||||
struct sway_mode *mode = config->modes->items[i];
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <assert.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -10,6 +9,7 @@
|
|||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_swapchain_manager.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/output.h"
|
||||
|
@ -79,7 +79,72 @@ struct output_config *new_output_config(const char *name) {
|
|||
return oc;
|
||||
}
|
||||
|
||||
void merge_output_config(struct output_config *dst, struct output_config *src) {
|
||||
// supersede_output_config clears all fields in dst that were set in src
|
||||
static void supersede_output_config(struct output_config *dst, struct output_config *src) {
|
||||
if (src->enabled != -1) {
|
||||
dst->enabled = -1;
|
||||
}
|
||||
if (src->width != -1) {
|
||||
dst->width = -1;
|
||||
}
|
||||
if (src->height != -1) {
|
||||
dst->height = -1;
|
||||
}
|
||||
if (src->x != -1) {
|
||||
dst->x = -1;
|
||||
}
|
||||
if (src->y != -1) {
|
||||
dst->y = -1;
|
||||
}
|
||||
if (src->scale != -1) {
|
||||
dst->scale = -1;
|
||||
}
|
||||
if (src->scale_filter != SCALE_FILTER_DEFAULT) {
|
||||
dst->scale_filter = SCALE_FILTER_DEFAULT;
|
||||
}
|
||||
if (src->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN) {
|
||||
dst->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
|
||||
}
|
||||
if (src->refresh_rate != -1) {
|
||||
dst->refresh_rate = -1;
|
||||
}
|
||||
if (src->custom_mode != -1) {
|
||||
dst->custom_mode = -1;
|
||||
}
|
||||
if (src->drm_mode.type != (uint32_t) -1) {
|
||||
dst->drm_mode.type = -1;
|
||||
}
|
||||
if (src->transform != -1) {
|
||||
dst->transform = -1;
|
||||
}
|
||||
if (src->max_render_time != -1) {
|
||||
dst->max_render_time = -1;
|
||||
}
|
||||
if (src->adaptive_sync != -1) {
|
||||
dst->adaptive_sync = -1;
|
||||
}
|
||||
if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
dst->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
|
||||
}
|
||||
if (src->background) {
|
||||
free(dst->background);
|
||||
dst->background = NULL;
|
||||
}
|
||||
if (src->background_option) {
|
||||
free(dst->background_option);
|
||||
dst->background_option = NULL;
|
||||
}
|
||||
if (src->background_fallback) {
|
||||
free(dst->background_fallback);
|
||||
dst->background_fallback = NULL;
|
||||
}
|
||||
if (src->power != -1) {
|
||||
dst->power = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// merge_output_config sets all fields in dst that were set in src
|
||||
static void merge_output_config(struct output_config *dst, struct output_config *src) {
|
||||
if (src->enabled != -1) {
|
||||
dst->enabled = src->enabled;
|
||||
}
|
||||
|
@ -142,94 +207,42 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
|
|||
}
|
||||
}
|
||||
|
||||
static void merge_wildcard_on_all(struct output_config *wildcard) {
|
||||
for (int i = 0; i < config->output_configs->length; i++) {
|
||||
struct output_config *oc = config->output_configs->items[i];
|
||||
if (strcmp(wildcard->name, oc->name) != 0) {
|
||||
sway_log(SWAY_DEBUG, "Merging output * config on %s", oc->name);
|
||||
merge_output_config(oc, wildcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void merge_id_on_name(struct output_config *oc) {
|
||||
struct sway_output *output = all_output_by_name_or_id(oc->name);
|
||||
if (output == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *name = output->wlr_output->name;
|
||||
char id[128];
|
||||
output_get_identifier(id, sizeof(id), output);
|
||||
|
||||
char *id_on_name = format_str("%s on %s", id, name);
|
||||
if (!id_on_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
|
||||
if (i >= 0) {
|
||||
sway_log(SWAY_DEBUG, "Merging on top of existing id on name config");
|
||||
merge_output_config(config->output_configs->items[i], oc);
|
||||
} else {
|
||||
// If both a name and identifier config, exist generate an id on name
|
||||
int ni = list_seq_find(config->output_configs, output_name_cmp, name);
|
||||
int ii = list_seq_find(config->output_configs, output_name_cmp, id);
|
||||
if ((ni >= 0 && ii >= 0) || (ni >= 0 && strcmp(oc->name, id) == 0)
|
||||
|| (ii >= 0 && strcmp(oc->name, name) == 0)) {
|
||||
struct output_config *ion_oc = new_output_config(id_on_name);
|
||||
if (ni >= 0) {
|
||||
merge_output_config(ion_oc, config->output_configs->items[ni]);
|
||||
}
|
||||
if (ii >= 0) {
|
||||
merge_output_config(ion_oc, config->output_configs->items[ii]);
|
||||
}
|
||||
merge_output_config(ion_oc, oc);
|
||||
list_add(config->output_configs, ion_oc);
|
||||
sway_log(SWAY_DEBUG, "Generated id on name output config \"%s\""
|
||||
" (enabled: %d) (%dx%d@%fHz position %d,%d scale %f "
|
||||
"transform %d) (bg %s %s) (power %d) (max render time: %d)",
|
||||
ion_oc->name, ion_oc->enabled, ion_oc->width, ion_oc->height,
|
||||
ion_oc->refresh_rate, ion_oc->x, ion_oc->y, ion_oc->scale,
|
||||
ion_oc->transform, ion_oc->background,
|
||||
ion_oc->background_option, ion_oc->power,
|
||||
ion_oc->max_render_time);
|
||||
}
|
||||
}
|
||||
free(id_on_name);
|
||||
}
|
||||
|
||||
struct output_config *store_output_config(struct output_config *oc) {
|
||||
void store_output_config(struct output_config *oc) {
|
||||
bool merged = false;
|
||||
bool wildcard = strcmp(oc->name, "*") == 0;
|
||||
if (wildcard) {
|
||||
merge_wildcard_on_all(oc);
|
||||
} else {
|
||||
merge_id_on_name(oc);
|
||||
struct sway_output *output = wildcard ? NULL : all_output_by_name_or_id(oc->name);
|
||||
|
||||
char id[128];
|
||||
if (output) {
|
||||
output_get_identifier(id, sizeof(id), output);
|
||||
}
|
||||
|
||||
int i = list_seq_find(config->output_configs, output_name_cmp, oc->name);
|
||||
if (i >= 0) {
|
||||
sway_log(SWAY_DEBUG, "Merging on top of existing output config");
|
||||
struct output_config *current = config->output_configs->items[i];
|
||||
merge_output_config(current, oc);
|
||||
free_output_config(oc);
|
||||
oc = current;
|
||||
} else if (!wildcard) {
|
||||
sway_log(SWAY_DEBUG, "Adding non-wildcard output config");
|
||||
i = list_seq_find(config->output_configs, output_name_cmp, "*");
|
||||
if (i >= 0) {
|
||||
sway_log(SWAY_DEBUG, "Merging on top of output * config");
|
||||
struct output_config *current = new_output_config(oc->name);
|
||||
merge_output_config(current, config->output_configs->items[i]);
|
||||
merge_output_config(current, oc);
|
||||
free_output_config(oc);
|
||||
oc = current;
|
||||
for (int i = 0; i < config->output_configs->length; i++) {
|
||||
struct output_config *old = config->output_configs->items[i];
|
||||
|
||||
// If the old config matches the new config's name, regardless of
|
||||
// whether it was name or identifier, merge on top of the existing
|
||||
// config. If the new config is a wildcard, this also merges on top of
|
||||
// old wildcard configs.
|
||||
if (strcmp(old->name, oc->name) == 0) {
|
||||
merge_output_config(old, oc);
|
||||
merged = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the new config is a wildcard config we supersede all non-wildcard
|
||||
// configs. Old wildcard configs have already been handled above.
|
||||
if (wildcard) {
|
||||
supersede_output_config(old, oc);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the new config matches an output's name, and the old config
|
||||
// matches on that output's identifier, supersede it.
|
||||
if (output && strcmp(old->name, id) == 0 &&
|
||||
strcmp(oc->name, output->wlr_output->name) == 0) {
|
||||
supersede_output_config(old, oc);
|
||||
}
|
||||
list_add(config->output_configs, oc);
|
||||
} else {
|
||||
// New wildcard config. Just add it
|
||||
sway_log(SWAY_DEBUG, "Adding output * config");
|
||||
list_add(config->output_configs, oc);
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
||||
|
@ -240,7 +253,13 @@ struct output_config *store_output_config(struct output_config *oc) {
|
|||
oc->transform, oc->background, oc->background_option, oc->power,
|
||||
oc->max_render_time);
|
||||
|
||||
return oc;
|
||||
// If the configuration was not merged into an existing configuration, add
|
||||
// it to the list. Otherwise we're done with it and can free it.
|
||||
if (!merged) {
|
||||
list_add(config->output_configs, oc);
|
||||
} else {
|
||||
free_output_config(oc);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_mode(struct wlr_output *output, struct wlr_output_state *pending,
|
||||
|
@ -367,22 +386,18 @@ static int compute_default_scale(struct wlr_output *output,
|
|||
return 2;
|
||||
}
|
||||
|
||||
/* Lists of formats to try, in order, when a specific render bit depth has
|
||||
* been asked for. The second to last format in each list should always
|
||||
* be XRGB8888, as a reliable backup in case the others are not available;
|
||||
* the last should be DRM_FORMAT_INVALID, to indicate the end of the list. */
|
||||
static const uint32_t *bit_depth_preferences[] = {
|
||||
[RENDER_BIT_DEPTH_8] = (const uint32_t []){
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_INVALID,
|
||||
},
|
||||
[RENDER_BIT_DEPTH_10] = (const uint32_t []){
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_INVALID,
|
||||
},
|
||||
};
|
||||
static bool render_format_is_10bit(uint32_t render_format) {
|
||||
return render_format == DRM_FORMAT_XRGB2101010 ||
|
||||
render_format == DRM_FORMAT_XBGR2101010;
|
||||
}
|
||||
|
||||
static bool render_format_is_bgr(uint32_t fmt) {
|
||||
return fmt == DRM_FORMAT_XBGR2101010 || fmt == DRM_FORMAT_XBGR8888;
|
||||
}
|
||||
|
||||
static bool output_config_is_disabling(struct output_config *oc) {
|
||||
return oc && (!oc->enabled || oc->power == 0);
|
||||
}
|
||||
|
||||
static void queue_output_config(struct output_config *oc,
|
||||
struct sway_output *output, struct wlr_output_state *pending) {
|
||||
|
@ -392,7 +407,7 @@ static void queue_output_config(struct output_config *oc,
|
|||
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
if (oc && (!oc->enabled || oc->power == 0)) {
|
||||
if (output_config_is_disabling(oc)) {
|
||||
sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name);
|
||||
wlr_output_state_set_enabled(pending, false);
|
||||
return;
|
||||
|
@ -415,22 +430,6 @@ static void queue_output_config(struct output_config *oc,
|
|||
struct wlr_output_mode *preferred_mode =
|
||||
wlr_output_preferred_mode(wlr_output);
|
||||
wlr_output_state_set_mode(pending, preferred_mode);
|
||||
|
||||
if (!wlr_output_test_state(wlr_output, pending)) {
|
||||
sway_log(SWAY_DEBUG, "Preferred mode rejected, "
|
||||
"falling back to another mode");
|
||||
struct wlr_output_mode *mode;
|
||||
wl_list_for_each(mode, &wlr_output->modes, link) {
|
||||
if (mode == preferred_mode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wlr_output_state_set_mode(pending, mode);
|
||||
if (wlr_output_test_state(wlr_output, pending)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) {
|
||||
|
@ -481,54 +480,27 @@ static void queue_output_config(struct output_config *oc,
|
|||
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
|
||||
oc->adaptive_sync);
|
||||
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
||||
if (oc->adaptive_sync == 1 && !wlr_output_test_state(wlr_output, pending)) {
|
||||
sway_log(SWAY_DEBUG, "Adaptive sync failed, ignoring");
|
||||
wlr_output_state_set_adaptive_sync_enabled(pending, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
const uint32_t *fmts = bit_depth_preferences[oc->render_bit_depth];
|
||||
assert(fmts);
|
||||
|
||||
for (size_t i = 0; fmts[i] != DRM_FORMAT_INVALID; i++) {
|
||||
wlr_output_state_set_render_format(pending, fmts[i]);
|
||||
if (wlr_output_test_state(wlr_output, pending)) {
|
||||
break;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Preferred output format 0x%08x "
|
||||
"failed to work, falling back to next in "
|
||||
"list, 0x%08x", fmts[i], fmts[i + 1]);
|
||||
if (oc->render_bit_depth == RENDER_BIT_DEPTH_10 &&
|
||||
render_format_is_10bit(output->wlr_output->render_format)) {
|
||||
// 10-bit was set successfully before, try to save some tests by reusing the format
|
||||
wlr_output_state_set_render_format(pending, output->wlr_output->render_format);
|
||||
} else if (oc->render_bit_depth == RENDER_BIT_DEPTH_10) {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB2101010);
|
||||
} else {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||
static bool finalize_output_config(struct output_config *oc, struct sway_output *output) {
|
||||
if (output == root->fallback_output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
// Flag to prevent the output mode event handler from calling us
|
||||
output->enabling = (!oc || oc->enabled);
|
||||
|
||||
struct wlr_output_state pending = {0};
|
||||
queue_output_config(oc, output, &pending);
|
||||
|
||||
sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
|
||||
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
||||
// Failed to commit output changes, maybe the output is missing a CRTC.
|
||||
// Leave the output disabled for now and try again when the output gets
|
||||
// the mode we asked for.
|
||||
sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name);
|
||||
output->enabling = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
output->enabling = false;
|
||||
|
||||
if (oc && !oc->enabled) {
|
||||
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
|
||||
if (output->enabled) {
|
||||
|
@ -538,10 +510,6 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (config->reloading) {
|
||||
output_damage_whole(output);
|
||||
}
|
||||
|
||||
if (oc) {
|
||||
enum scale_filter_mode scale_filter_old = output->scale_filter;
|
||||
switch (oc->scale_filter) {
|
||||
|
@ -558,6 +526,7 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
if (scale_filter_old != output->scale_filter) {
|
||||
sway_log(SWAY_DEBUG, "Set %s scale_filter to %s", oc->name,
|
||||
sway_output_scale_filter_to_string(output->scale_filter));
|
||||
wlr_damage_ring_add_whole(&output->scene_output->damage_ring);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -587,25 +556,9 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
output->max_render_time = oc->max_render_time;
|
||||
}
|
||||
|
||||
// Reconfigure all devices, since input config may have been applied before
|
||||
// this output came online, and some config items (like map_to_output) are
|
||||
// dependent on an output being present.
|
||||
input_manager_configure_all_input_mappings();
|
||||
// Reconfigure the cursor images, since the scale may have changed.
|
||||
input_manager_configure_xcursor();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_output_config(struct output_config *oc, struct sway_output *output) {
|
||||
if (output == root->fallback_output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_output_state pending = {0};
|
||||
queue_output_config(oc, output, &pending);
|
||||
return wlr_output_test_state(output->wlr_output, &pending);
|
||||
}
|
||||
|
||||
static void default_output_config(struct output_config *oc,
|
||||
struct wlr_output *wlr_output) {
|
||||
oc->enabled = 1;
|
||||
|
@ -625,140 +578,415 @@ static void default_output_config(struct output_config *oc,
|
|||
oc->max_render_time = 0;
|
||||
}
|
||||
|
||||
static struct output_config *get_output_config(char *identifier,
|
||||
struct sway_output *sway_output) {
|
||||
// find_output_config returns a merged output_config containing all stored
|
||||
// configuration that applies to the specified output.
|
||||
struct output_config *find_output_config(struct sway_output *sway_output) {
|
||||
const char *name = sway_output->wlr_output->name;
|
||||
struct output_config *oc = NULL;
|
||||
|
||||
struct output_config *oc_id_on_name = NULL;
|
||||
struct output_config *oc_name = NULL;
|
||||
struct output_config *oc_id = NULL;
|
||||
|
||||
char *id_on_name = format_str("%s on %s", identifier, name);
|
||||
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
|
||||
if (i >= 0) {
|
||||
oc_id_on_name = config->output_configs->items[i];
|
||||
} else {
|
||||
i = list_seq_find(config->output_configs, output_name_cmp, name);
|
||||
if (i >= 0) {
|
||||
oc_name = config->output_configs->items[i];
|
||||
}
|
||||
|
||||
i = list_seq_find(config->output_configs, output_name_cmp, identifier);
|
||||
if (i >= 0) {
|
||||
oc_id = config->output_configs->items[i];
|
||||
}
|
||||
}
|
||||
|
||||
struct output_config *result = new_output_config("temp");
|
||||
struct output_config *result = new_output_config(name);
|
||||
if (config->reloading) {
|
||||
default_output_config(result, sway_output->wlr_output);
|
||||
}
|
||||
if (oc_id_on_name) {
|
||||
// Already have an identifier on name config, use that
|
||||
free(result->name);
|
||||
result->name = strdup(id_on_name);
|
||||
merge_output_config(result, oc_id_on_name);
|
||||
} else if (oc_name && oc_id) {
|
||||
// Generate a config named `<identifier> on <name>` which contains a
|
||||
// merged copy of the identifier on name. This will make sure that both
|
||||
// identifier and name configs are respected, with identifier getting
|
||||
// priority
|
||||
struct output_config *temp = new_output_config(id_on_name);
|
||||
merge_output_config(temp, oc_name);
|
||||
merge_output_config(temp, oc_id);
|
||||
list_add(config->output_configs, temp);
|
||||
|
||||
free(result->name);
|
||||
result->name = strdup(id_on_name);
|
||||
merge_output_config(result, temp);
|
||||
char id[128];
|
||||
output_get_identifier(id, sizeof(id), sway_output);
|
||||
|
||||
sway_log(SWAY_DEBUG, "Generated output config \"%s\" (enabled: %d)"
|
||||
" (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)"
|
||||
" (power %d) (max render time: %d)", result->name, result->enabled,
|
||||
result->width, result->height, result->refresh_rate,
|
||||
result->x, result->y, result->scale, result->transform,
|
||||
result->background, result->background_option, result->power,
|
||||
result->max_render_time);
|
||||
} else if (oc_name) {
|
||||
// No identifier config, just return a copy of the name config
|
||||
free(result->name);
|
||||
result->name = strdup(name);
|
||||
merge_output_config(result, oc_name);
|
||||
} else if (oc_id) {
|
||||
// No name config, just return a copy of the identifier config
|
||||
free(result->name);
|
||||
result->name = strdup(identifier);
|
||||
merge_output_config(result, oc_id);
|
||||
} else {
|
||||
i = list_seq_find(config->output_configs, output_name_cmp, "*");
|
||||
if (i >= 0) {
|
||||
// No name or identifier config, but there is a wildcard config
|
||||
free(result->name);
|
||||
result->name = strdup("*");
|
||||
merge_output_config(result, config->output_configs->items[i]);
|
||||
} else if (!config->reloading) {
|
||||
// No name, identifier, or wildcard config. Since we are not
|
||||
// reloading with defaults, the output config will be empty, so
|
||||
// just return NULL
|
||||
free_output_config(result);
|
||||
result = NULL;
|
||||
}
|
||||
int i;
|
||||
bool match = false;
|
||||
if ((i = list_seq_find(config->output_configs, output_name_cmp, "*")) >= 0) {
|
||||
match = true;
|
||||
oc = config->output_configs->items[i];
|
||||
merge_output_config(result, oc);
|
||||
}
|
||||
if ((i = list_seq_find(config->output_configs, output_name_cmp, name)) >= 0) {
|
||||
match = true;
|
||||
oc = config->output_configs->items[i];
|
||||
merge_output_config(result, oc);
|
||||
}
|
||||
if ((i = list_seq_find(config->output_configs, output_name_cmp, id)) >= 0) {
|
||||
match = true;
|
||||
oc = config->output_configs->items[i];
|
||||
merge_output_config(result, oc);
|
||||
}
|
||||
|
||||
if (!match && !config->reloading) {
|
||||
// No name, identifier, or wildcard config. Since we are not
|
||||
// reloading with defaults, the output config will be empty, so
|
||||
// just return NULL
|
||||
free_output_config(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(id_on_name);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct output_config *find_output_config(struct sway_output *output) {
|
||||
char id[128];
|
||||
output_get_identifier(id, sizeof(id), output);
|
||||
return get_output_config(id, output);
|
||||
static bool config_has_auto_mode(struct output_config *oc) {
|
||||
if (!oc) {
|
||||
return true;
|
||||
}
|
||||
if (oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t)-1) {
|
||||
return true;
|
||||
} else if (oc->width > 0 && oc->height > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void apply_output_config_to_outputs(struct output_config *oc) {
|
||||
// Try to find the output container and apply configuration now. If
|
||||
// this is during startup then there will be no container and config
|
||||
// will be applied during normal "new output" event from wlroots.
|
||||
bool wildcard = strcmp(oc->name, "*") == 0;
|
||||
struct sway_output *sway_output, *tmp;
|
||||
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
|
||||
if (output_match_name_or_id(sway_output, oc->name)) {
|
||||
char id[128];
|
||||
output_get_identifier(id, sizeof(id), sway_output);
|
||||
struct output_config *current = get_output_config(id, sway_output);
|
||||
if (!current) {
|
||||
// No stored output config matched, apply oc directly
|
||||
sway_log(SWAY_DEBUG, "Applying oc directly");
|
||||
current = new_output_config(oc->name);
|
||||
merge_output_config(current, oc);
|
||||
}
|
||||
apply_output_config(current, sway_output);
|
||||
free_output_config(current);
|
||||
struct search_context {
|
||||
struct wlr_output_swapchain_manager *swapchain_mgr;
|
||||
struct wlr_backend_output_state *states;
|
||||
struct matched_output_config *configs;
|
||||
size_t configs_len;
|
||||
bool degrade_to_off;
|
||||
};
|
||||
|
||||
if (!wildcard) {
|
||||
// Stop looking if the output config isn't applicable to all
|
||||
// outputs
|
||||
break;
|
||||
}
|
||||
static void dump_output_state(struct wlr_output *wlr_output, struct wlr_output_state *state) {
|
||||
sway_log(SWAY_DEBUG, "Output state for %s", wlr_output->name);
|
||||
if (state->committed & WLR_OUTPUT_STATE_ENABLED) {
|
||||
sway_log(SWAY_DEBUG, " enabled: %s", state->enabled ? "yes" : "no");
|
||||
}
|
||||
if (state->committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
|
||||
sway_log(SWAY_DEBUG, " render_format: %d", state->render_format);
|
||||
}
|
||||
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||
if (state->mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM) {
|
||||
sway_log(SWAY_DEBUG, " custom mode: %dx%d@%dmHz",
|
||||
state->custom_mode.width, state->custom_mode.height, state->custom_mode.refresh);
|
||||
} else {
|
||||
sway_log(SWAY_DEBUG, " mode: %dx%d@%dmHz%s",
|
||||
state->mode->width, state->mode->height, state->mode->refresh,
|
||||
state->mode->preferred ? " (preferred)" : "");
|
||||
}
|
||||
}
|
||||
if (state->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) {
|
||||
sway_log(SWAY_DEBUG, " adaptive_sync: %s",
|
||||
state->adaptive_sync_enabled ? "enabled": "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
static bool search_valid_config(struct search_context *ctx, size_t output_idx);
|
||||
|
||||
static void reset_output_state(struct wlr_output_state *state) {
|
||||
wlr_output_state_finish(state);
|
||||
wlr_output_state_init(state);
|
||||
state->committed = 0;
|
||||
}
|
||||
|
||||
static void clear_later_output_states(struct wlr_backend_output_state *states,
|
||||
size_t configs_len, size_t output_idx) {
|
||||
|
||||
// Clear and disable all output states after this one to avoid conflict
|
||||
// with previous tests.
|
||||
for (size_t idx = output_idx+1; idx < configs_len; idx++) {
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
|
||||
reset_output_state(state);
|
||||
wlr_output_state_set_enabled(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
static bool search_finish(struct search_context *ctx, size_t output_idx) {
|
||||
struct wlr_backend_output_state *backend_state = &ctx->states[output_idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
struct wlr_output *wlr_output = backend_state->output;
|
||||
|
||||
clear_later_output_states(ctx->states, ctx->configs_len, output_idx);
|
||||
dump_output_state(wlr_output, state);
|
||||
return wlr_output_swapchain_manager_prepare(ctx->swapchain_mgr, ctx->states, ctx->configs_len) &&
|
||||
search_valid_config(ctx, output_idx+1);
|
||||
}
|
||||
|
||||
static bool search_adaptive_sync(struct search_context *ctx, size_t output_idx) {
|
||||
struct matched_output_config *cfg = &ctx->configs[output_idx];
|
||||
struct wlr_backend_output_state *backend_state = &ctx->states[output_idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
|
||||
if (cfg->config && cfg->config->adaptive_sync == 1) {
|
||||
wlr_output_state_set_adaptive_sync_enabled(state, true);
|
||||
if (search_finish(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!cfg->config || cfg->config->adaptive_sync != -1) {
|
||||
wlr_output_state_set_adaptive_sync_enabled(state, false);
|
||||
if (search_finish(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If adaptive sync has not been set, or fallback in case we are on a
|
||||
// backend that cannot disable adaptive sync such as the wayland backend.
|
||||
state->committed &= ~WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED;
|
||||
return search_finish(ctx, output_idx);
|
||||
}
|
||||
|
||||
static bool search_mode(struct search_context *ctx, size_t output_idx) {
|
||||
struct matched_output_config *cfg = &ctx->configs[output_idx];
|
||||
struct wlr_backend_output_state *backend_state = &ctx->states[output_idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
struct wlr_output *wlr_output = backend_state->output;
|
||||
|
||||
if (!config_has_auto_mode(cfg->config)) {
|
||||
return search_adaptive_sync(ctx, output_idx);
|
||||
}
|
||||
|
||||
struct wlr_output_mode *preferred_mode = wlr_output_preferred_mode(wlr_output);
|
||||
if (preferred_mode) {
|
||||
wlr_output_state_set_mode(state, preferred_mode);
|
||||
if (search_adaptive_sync(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wl_list_empty(&wlr_output->modes)) {
|
||||
state->committed &= ~WLR_OUTPUT_STATE_MODE;
|
||||
return search_adaptive_sync(ctx, output_idx);
|
||||
}
|
||||
|
||||
struct wlr_output_mode *mode;
|
||||
wl_list_for_each(mode, &backend_state->output->modes, link) {
|
||||
if (mode == preferred_mode) {
|
||||
continue;
|
||||
}
|
||||
wlr_output_state_set_mode(state, mode);
|
||||
if (search_adaptive_sync(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool search_render_format(struct search_context *ctx, size_t output_idx) {
|
||||
struct matched_output_config *cfg = &ctx->configs[output_idx];
|
||||
struct wlr_backend_output_state *backend_state = &ctx->states[output_idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
struct wlr_output *wlr_output = backend_state->output;
|
||||
|
||||
uint32_t fmts[] = {
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_INVALID,
|
||||
};
|
||||
if (render_format_is_bgr(wlr_output->render_format)) {
|
||||
// Start with BGR in the unlikely event that we previously required it.
|
||||
fmts[0] = DRM_FORMAT_XBGR2101010;
|
||||
fmts[1] = DRM_FORMAT_XRGB2101010;
|
||||
}
|
||||
|
||||
const struct wlr_drm_format_set *primary_formats =
|
||||
wlr_output_get_primary_formats(wlr_output, WLR_BUFFER_CAP_DMABUF);
|
||||
bool need_10bit = cfg->config && cfg->config->render_bit_depth == RENDER_BIT_DEPTH_10;
|
||||
for (size_t idx = 0; fmts[idx] != DRM_FORMAT_INVALID; idx++) {
|
||||
if (!need_10bit && render_format_is_10bit(fmts[idx])) {
|
||||
continue;
|
||||
}
|
||||
if (!wlr_drm_format_set_get(primary_formats, fmts[idx])) {
|
||||
// This is not a supported format for this output
|
||||
continue;
|
||||
}
|
||||
wlr_output_state_set_render_format(state, fmts[idx]);
|
||||
if (search_mode(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool search_valid_config(struct search_context *ctx, size_t output_idx) {
|
||||
if (output_idx >= ctx->configs_len) {
|
||||
// We reached the end of the search, all good!
|
||||
return true;
|
||||
}
|
||||
|
||||
struct matched_output_config *cfg = &ctx->configs[output_idx];
|
||||
struct wlr_backend_output_state *backend_state = &ctx->states[output_idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
struct wlr_output *wlr_output = backend_state->output;
|
||||
|
||||
if (!output_config_is_disabling(cfg->config)) {
|
||||
// Search through our possible configurations, doing a depth-first
|
||||
// through render_format, modes, adaptive_sync and the next output's
|
||||
// config.
|
||||
queue_output_config(cfg->config, cfg->output, &backend_state->base);
|
||||
if (search_render_format(ctx, output_idx)) {
|
||||
return true;
|
||||
} else if (!ctx->degrade_to_off) {
|
||||
return false;
|
||||
}
|
||||
// We could not get anything to work, try to disable this output to see
|
||||
// if we can at least make the outputs before us work.
|
||||
sway_log(SWAY_DEBUG, "Unable to find valid config with output %s, disabling",
|
||||
wlr_output->name);
|
||||
reset_output_state(state);
|
||||
}
|
||||
|
||||
wlr_output_state_set_enabled(state, false);
|
||||
return search_finish(ctx, output_idx);
|
||||
}
|
||||
|
||||
static int compare_matched_output_config_priority(const void *a, const void *b) {
|
||||
|
||||
const struct matched_output_config *amc = a;
|
||||
const struct matched_output_config *bmc = b;
|
||||
bool a_disabling = output_config_is_disabling(amc->config);
|
||||
bool b_disabling = output_config_is_disabling(bmc->config);
|
||||
bool a_enabled = amc->output->enabled;
|
||||
bool b_enabled = bmc->output->enabled;
|
||||
|
||||
// We want to give priority to existing enabled outputs. To do so, we want
|
||||
// the configuration order to be:
|
||||
// 1. Existing, enabled outputs
|
||||
// 2. Outputs that need to be enabled
|
||||
// 3. Disabled or disabling outputs
|
||||
if (a_enabled && !a_disabling) {
|
||||
return -1;
|
||||
} else if (b_enabled && !b_disabling) {
|
||||
return 1;
|
||||
} else if (b_disabling && !a_disabling) {
|
||||
return -1;
|
||||
} else if (a_disabling && !b_disabling) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sort_output_configs_by_priority(struct matched_output_config *configs,
|
||||
size_t configs_len) {
|
||||
qsort(configs, configs_len, sizeof(*configs), compare_matched_output_config_priority);
|
||||
}
|
||||
|
||||
bool apply_output_configs(struct matched_output_config *configs,
|
||||
size_t configs_len, bool test_only, bool degrade_to_off) {
|
||||
struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states));
|
||||
if (!states) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Committing %zd outputs", configs_len);
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
|
||||
backend_state->output = cfg->output->wlr_output;
|
||||
wlr_output_state_init(&backend_state->base);
|
||||
|
||||
sway_log(SWAY_DEBUG, "Preparing config for %s",
|
||||
cfg->output->wlr_output->name);
|
||||
queue_output_config(cfg->config, cfg->output, &backend_state->base);
|
||||
}
|
||||
|
||||
struct wlr_output_swapchain_manager swapchain_mgr;
|
||||
wlr_output_swapchain_manager_init(&swapchain_mgr, server.backend);
|
||||
|
||||
bool ok = wlr_output_swapchain_manager_prepare(&swapchain_mgr, states, configs_len);
|
||||
if (!ok) {
|
||||
sway_log(SWAY_ERROR, "Requested backend configuration failed, searching for valid fallbacks");
|
||||
struct search_context ctx = {
|
||||
.swapchain_mgr = &swapchain_mgr,
|
||||
.states = states,
|
||||
.configs = configs,
|
||||
.configs_len = configs_len,
|
||||
.degrade_to_off = degrade_to_off,
|
||||
};
|
||||
if (!search_valid_config(&ctx, 0)) {
|
||||
sway_log(SWAY_ERROR, "Search for valid config failed");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (test_only) {
|
||||
// The swapchain manager already did a test for us
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
|
||||
struct wlr_scene_output_state_options opts = {
|
||||
.swapchain = wlr_output_swapchain_manager_get_swapchain(
|
||||
&swapchain_mgr, backend_state->output),
|
||||
};
|
||||
struct wlr_scene_output *scene_output = cfg->output->scene_output;
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
if (!wlr_scene_output_build_state(scene_output, state, &opts)) {
|
||||
sway_log(SWAY_ERROR, "Building output state for '%s' failed",
|
||||
backend_state->output->name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ok = wlr_backend_commit(server.backend, states, configs_len);
|
||||
if (!ok) {
|
||||
sway_log(SWAY_ERROR, "Backend commit failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Commit of %zd outputs succeeded", configs_len);
|
||||
|
||||
wlr_output_swapchain_manager_apply(&swapchain_mgr);
|
||||
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
||||
cfg->output->wlr_output->name);
|
||||
finalize_output_config(cfg->config, cfg->output);
|
||||
}
|
||||
|
||||
out:
|
||||
wlr_output_swapchain_manager_finish(&swapchain_mgr);
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
wlr_output_state_finish(&backend_state->base);
|
||||
}
|
||||
free(states);
|
||||
|
||||
// Reconfigure all devices, since input config may have been applied before
|
||||
// this output came online, and some config items (like map_to_output) are
|
||||
// dependent on an output being present.
|
||||
input_manager_configure_all_input_mappings();
|
||||
// Reconfigure the cursor images, since the scale may have changed.
|
||||
input_manager_configure_xcursor();
|
||||
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
wlr_seat_pointer_notify_clear_focus(seat->wlr_seat);
|
||||
cursor_rebase(seat->cursor);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
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("*"));
|
||||
void apply_all_output_configs(void) {
|
||||
size_t configs_len = wl_list_length(&root->all_outputs);
|
||||
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
|
||||
if (!configs) {
|
||||
return;
|
||||
}
|
||||
apply_output_config_to_outputs(oc);
|
||||
|
||||
int config_idx = 0;
|
||||
struct sway_output *sway_output;
|
||||
wl_list_for_each(sway_output, &root->all_outputs, link) {
|
||||
if (sway_output == root->fallback_output) {
|
||||
configs_len--;
|
||||
continue;
|
||||
}
|
||||
|
||||
struct matched_output_config *config = &configs[config_idx++];
|
||||
config->output = sway_output;
|
||||
config->config = find_output_config(sway_output);
|
||||
}
|
||||
|
||||
sort_output_configs_by_priority(configs, configs_len);
|
||||
apply_output_configs(configs, configs_len, false, true);
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
free_output_config(cfg->config);
|
||||
}
|
||||
free(configs);
|
||||
}
|
||||
|
||||
void free_output_config(struct output_config *oc) {
|
||||
|
@ -825,7 +1053,9 @@ static bool _spawn_swaybg(char **command) {
|
|||
setenv("WAYLAND_SOCKET", wayland_socket_str, true);
|
||||
|
||||
execvp(command[0], command);
|
||||
sway_log_errno(SWAY_ERROR, "execvp failed");
|
||||
sway_log_errno(SWAY_ERROR, "failed to execute '%s' "
|
||||
"(background configuration probably not applied)",
|
||||
command[0]);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
@ -835,12 +1065,13 @@ static bool _spawn_swaybg(char **command) {
|
|||
sway_log_errno(SWAY_ERROR, "close failed");
|
||||
return false;
|
||||
}
|
||||
if (waitpid(pid, NULL, 0) < 0) {
|
||||
int fork_status = 0;
|
||||
if (waitpid(pid, &fork_status, 0) < 0) {
|
||||
sway_log_errno(SWAY_ERROR, "waitpid failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return WIFEXITED(fork_status) && WEXITSTATUS(fork_status) == EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
bool spawn_swaybg(void) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
#include "sway/tree/container.h"
|
||||
#include "sway/desktop.h"
|
||||
#include "sway/output.h"
|
||||
|
||||
void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly,
|
||||
bool whole) {
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
struct wlr_box output_box;
|
||||
wlr_output_layout_get_box(root->output_layout,
|
||||
output->wlr_output, &output_box);
|
||||
output_damage_surface(output, lx - output_box.x,
|
||||
ly - output_box.y, surface, whole);
|
||||
}
|
||||
}
|
||||
|
||||
void desktop_damage_whole_container(struct sway_container *con) {
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
output_damage_whole_container(output, con);
|
||||
}
|
||||
}
|
||||
|
||||
void desktop_damage_box(struct wlr_box *box) {
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
output_damage_box(output, box);
|
||||
}
|
||||
}
|
||||
|
||||
void desktop_damage_view(struct sway_view *view) {
|
||||
desktop_damage_whole_container(view->container);
|
||||
struct wlr_box box = {
|
||||
.x = view->container->current.content_x - view->geometry.x,
|
||||
.y = view->container->current.content_y - view->geometry.y,
|
||||
.width = view->surface->current.width,
|
||||
.height = view->surface->current.height,
|
||||
};
|
||||
desktop_damage_box(&box);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue