mirror of
https://github.com/swaywm/sway.git
synced 2024-09-20 12:41:26 +02:00
Compare commits
20 Commits
c97a2b0a01
...
5e8a2fc8a7
Author | SHA1 | Date | |
---|---|---|---|
|
5e8a2fc8a7 | ||
|
785a459a55 | ||
|
f957c7e658 | ||
|
d7a76d381b | ||
|
29b3f00e6f | ||
|
0496477f92 | ||
|
a0c0349934 | ||
|
fb5eadc363 | ||
|
c5ba7f23a5 | ||
|
f4a6b0395f | ||
|
14bff7b451 | ||
|
4f9ce4675c | ||
|
fc6b8d6af2 | ||
|
4fe054c6db | ||
|
cfb292cca7 | ||
|
af28ac04a4 | ||
|
6045ad9a02 | ||
|
b83e5aaa54 | ||
|
be840f730e | ||
|
410dab6803 |
11
README.cs.md
11
README.cs.md
@ -1,6 +1,6 @@
|
|||||||
# sway
|
# sway
|
||||||
|
|
||||||
[English][en] - **[Česky][cs]** - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [Svenska][sv] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
[English][en] - [عربي][ar] - **[Česky][cs]** - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [ქართული][ge] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||||
|
|
||||||
sway je s [i3] kompatibilní [Wayland] kompozitor. Přečtěte si [FAQ]. Připojte se na
|
sway je s [i3] kompatibilní [Wayland] kompozitor. Přečtěte si [FAQ]. Připojte se na
|
||||||
[IRC kanál][IRC channel] \(#sway na irc.libera.chat).
|
[IRC kanál][IRC channel] \(#sway na irc.libera.chat).
|
||||||
@ -32,10 +32,11 @@ Nainstalujte závislosti:
|
|||||||
* pango
|
* pango
|
||||||
* cairo
|
* cairo
|
||||||
* gdk-pixbuf2 (volitelné: oznamovací oblast)
|
* gdk-pixbuf2 (volitelné: oznamovací oblast)
|
||||||
|
* [swaybg] (volitelné: tapeta)
|
||||||
* [scdoc] (volitelné: manuálové stránky) \*
|
* [scdoc] (volitelné: manuálové stránky) \*
|
||||||
* git (volitelné: informace o verzi) \*
|
* git (volitelné: informace o verzi) \*
|
||||||
|
|
||||||
_\* Závislost pouze pro sestavení_
|
_\* Závislost pouze pro kompilaci_
|
||||||
|
|
||||||
Spusťte tyto příkazy:
|
Spusťte tyto příkazy:
|
||||||
|
|
||||||
@ -56,12 +57,13 @@ Spusťte `sway` z TTY. Některé správce zobrazení mohou fungovat, ale nejsou
|
|||||||
podporovány sway (je známo, že gdm funguje docela dobře).
|
podporovány sway (je známo, že gdm funguje docela dobře).
|
||||||
|
|
||||||
[en]: https://github.com/swaywm/sway#readme
|
[en]: https://github.com/swaywm/sway#readme
|
||||||
|
[ar]: README.ar.md
|
||||||
[cs]: README.cs.md
|
[cs]: README.cs.md
|
||||||
[de]: README.de.md
|
[de]: README.de.md
|
||||||
[dk]: README.dk.md
|
[dk]: README.dk.md
|
||||||
[es]: README.es.md
|
[es]: README.es.md
|
||||||
[fr]: README.fr.md
|
[fr]: README.fr.md
|
||||||
[sv]: README.sv.md
|
[ge]: README.ge.md
|
||||||
[gr]: README.gr.md
|
[gr]: README.gr.md
|
||||||
[hi]: README.hi.md
|
[hi]: README.hi.md
|
||||||
[hu]: README.hu.md
|
[hu]: README.hu.md
|
||||||
@ -70,10 +72,12 @@ podporovány sway (je známo, že gdm funguje docela dobře).
|
|||||||
[ja]: README.ja.md
|
[ja]: README.ja.md
|
||||||
[ko]: README.ko.md
|
[ko]: README.ko.md
|
||||||
[nl]: README.nl.md
|
[nl]: README.nl.md
|
||||||
|
[no]: README.no.md
|
||||||
[pl]: README.pl.md
|
[pl]: README.pl.md
|
||||||
[pt]: README.pt.md
|
[pt]: README.pt.md
|
||||||
[ro]: README.ro.md
|
[ro]: README.ro.md
|
||||||
[ru]: README.ru.md
|
[ru]: README.ru.md
|
||||||
|
[sv]: README.sv.md
|
||||||
[tr]: README.tr.md
|
[tr]: README.tr.md
|
||||||
[uk]: README.uk.md
|
[uk]: README.uk.md
|
||||||
[zh-CN]: README.zh-CN.md
|
[zh-CN]: README.zh-CN.md
|
||||||
@ -86,4 +90,5 @@ podporovány sway (je známo, že gdm funguje docela dobře).
|
|||||||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||||
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||||
|
[swaybg]: https://github.com/swaywm/swaybg/
|
||||||
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
||||||
|
@ -296,14 +296,6 @@ struct output_config {
|
|||||||
char *background_fallback;
|
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
|
* Stores size of gaps for each side
|
||||||
*/
|
*/
|
||||||
@ -693,13 +685,10 @@ const char *sway_output_scale_filter_to_string(enum scale_filter_mode scale_filt
|
|||||||
|
|
||||||
struct output_config *new_output_config(const char *name);
|
struct output_config *new_output_config(const char *name);
|
||||||
|
|
||||||
bool apply_output_configs(struct matched_output_config *configs,
|
bool apply_output_configs(struct output_config **ocs, size_t ocs_len,
|
||||||
size_t configs_len, bool test_only, bool degrade_to_off);
|
bool test_only, bool degrade_to_off);
|
||||||
|
|
||||||
void apply_all_output_configs(void);
|
void apply_stored_output_configs(void);
|
||||||
|
|
||||||
void sort_output_configs_by_priority(struct matched_output_config *configs,
|
|
||||||
size_t configs_len);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* store_output_config stores a new output config. An output may be matched by
|
* store_output_config stores a new output config. An output may be matched by
|
||||||
|
6
include/sway/lock.h
Normal file
6
include/sway/lock.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _SWAY_LOCK_H
|
||||||
|
#define _SWAY_LOCK_H
|
||||||
|
|
||||||
|
void arrange_locks(void);
|
||||||
|
|
||||||
|
#endif
|
@ -57,7 +57,6 @@ struct sway_output {
|
|||||||
|
|
||||||
struct wl_listener layout_destroy;
|
struct wl_listener layout_destroy;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener commit;
|
|
||||||
struct wl_listener present;
|
struct wl_listener present;
|
||||||
struct wl_listener frame;
|
struct wl_listener frame;
|
||||||
struct wl_listener request_state;
|
struct wl_listener request_state;
|
||||||
@ -135,8 +134,6 @@ enum sway_container_layout output_get_default_layout(
|
|||||||
|
|
||||||
enum wlr_direction opposite_direction(enum wlr_direction d);
|
enum wlr_direction opposite_direction(enum wlr_direction d);
|
||||||
|
|
||||||
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
|
||||||
|
|
||||||
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
||||||
@ -146,4 +143,6 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
|
|||||||
|
|
||||||
struct sway_output_non_desktop *output_non_desktop_create(struct wlr_output *wlr_output);
|
struct sway_output_non_desktop *output_non_desktop_create(struct wlr_output *wlr_output);
|
||||||
|
|
||||||
|
void update_output_manager_config(struct sway_server *server);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,7 +45,6 @@ struct sway_server {
|
|||||||
struct sway_input_manager *input;
|
struct sway_input_manager *input;
|
||||||
|
|
||||||
struct wl_listener new_output;
|
struct wl_listener new_output;
|
||||||
struct wl_listener output_layout_change;
|
|
||||||
struct wl_listener renderer_lost;
|
struct wl_listener renderer_lost;
|
||||||
|
|
||||||
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
||||||
|
@ -103,6 +103,8 @@ struct sway_container {
|
|||||||
char *formatted_title; // The title displayed in the title bar
|
char *formatted_title; // The title displayed in the title bar
|
||||||
int title_width;
|
int title_width;
|
||||||
|
|
||||||
|
char *title_format;
|
||||||
|
|
||||||
enum sway_container_layout prev_split_layout;
|
enum sway_container_layout prev_split_layout;
|
||||||
|
|
||||||
// Whether stickiness has been enabled on this container. Use
|
// Whether stickiness has been enabled on this container. Use
|
||||||
@ -183,6 +185,8 @@ void container_update_title_bar(struct sway_container *container);
|
|||||||
|
|
||||||
void container_update_marks(struct sway_container *container);
|
void container_update_marks(struct sway_container *container);
|
||||||
|
|
||||||
|
size_t parse_title_format(struct sway_container *container, char *buffer);
|
||||||
|
|
||||||
size_t container_build_representation(enum sway_container_layout layout,
|
size_t container_build_representation(enum sway_container_layout layout,
|
||||||
list_t *children, char *buffer);
|
list_t *children, char *buffer);
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ struct sway_root {
|
|||||||
struct sway_node node;
|
struct sway_node node;
|
||||||
struct wlr_output_layout *output_layout;
|
struct wlr_output_layout *output_layout;
|
||||||
|
|
||||||
struct wl_listener output_layout_change;
|
|
||||||
|
|
||||||
// scene node layout:
|
// scene node layout:
|
||||||
// - root
|
// - root
|
||||||
// - staging
|
// - staging
|
||||||
|
@ -80,8 +80,6 @@ struct sway_view {
|
|||||||
// Used when changing a view from tiled to floating.
|
// Used when changing a view from tiled to floating.
|
||||||
int natural_width, natural_height;
|
int natural_width, natural_height;
|
||||||
|
|
||||||
char *title_format;
|
|
||||||
|
|
||||||
bool using_csd;
|
bool using_csd;
|
||||||
|
|
||||||
struct timespec urgent;
|
struct timespec urgent;
|
||||||
|
@ -111,7 +111,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
|
|||||||
// entire config and before the deferred commands so that an auto generated
|
// entire config and before the deferred commands so that an auto generated
|
||||||
// workspace name is not given to re-enabled outputs.
|
// workspace name is not given to re-enabled outputs.
|
||||||
if (!config->reloading && !config->validating) {
|
if (!config->reloading && !config->validating) {
|
||||||
apply_all_output_configs();
|
apply_stored_output_configs();
|
||||||
if (background) {
|
if (background) {
|
||||||
if (!spawn_swaybg()) {
|
if (!spawn_swaybg()) {
|
||||||
return cmd_results_new(CMD_FAILURE,
|
return cmd_results_new(CMD_FAILURE,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
@ -11,16 +12,19 @@ struct cmd_results *cmd_title_format(int argc, char **argv) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
struct sway_container *container = config->handler_context.container;
|
struct sway_container *container = config->handler_context.container;
|
||||||
if (!container || !container->view) {
|
if (!container) {
|
||||||
return cmd_results_new(CMD_INVALID,
|
return cmd_results_new(CMD_INVALID,
|
||||||
"Only views can have a title_format");
|
"Only valid containers can have a title_format");
|
||||||
}
|
}
|
||||||
struct sway_view *view = container->view;
|
|
||||||
char *format = join_args(argv, argc);
|
char *format = join_args(argv, argc);
|
||||||
if (view->title_format) {
|
if (container->title_format) {
|
||||||
free(view->title_format);
|
free(container->title_format);
|
||||||
|
}
|
||||||
|
container->title_format = format;
|
||||||
|
if (container->view) {
|
||||||
|
view_update_title(container->view, true);
|
||||||
|
} else {
|
||||||
|
container_update_representation(container);
|
||||||
}
|
}
|
||||||
view->title_format = format;
|
|
||||||
view_update_title(view, true);
|
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||||||
}
|
}
|
||||||
sway_switch_retrigger_bindings_for_all();
|
sway_switch_retrigger_bindings_for_all();
|
||||||
|
|
||||||
apply_all_output_configs();
|
apply_stored_output_configs();
|
||||||
spawn_swaybg();
|
spawn_swaybg();
|
||||||
|
|
||||||
config->reloading = false;
|
config->reloading = false;
|
||||||
@ -550,28 +550,12 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool load_include_config(const char *path, const char *parent_dir,
|
static bool load_include_config(const char *path, struct sway_config *config,
|
||||||
struct sway_config *config, struct swaynag_instance *swaynag) {
|
struct swaynag_instance *swaynag) {
|
||||||
// save parent config
|
// save parent config
|
||||||
const char *parent_config = config->current_config_path;
|
const char *parent_config = config->current_config_path;
|
||||||
|
|
||||||
char *full_path;
|
char *real_path = realpath(path, NULL);
|
||||||
int len = strlen(path);
|
|
||||||
if (len >= 1 && path[0] != '/') {
|
|
||||||
len = len + strlen(parent_dir) + 2;
|
|
||||||
full_path = malloc(len * sizeof(char));
|
|
||||||
if (!full_path) {
|
|
||||||
sway_log(SWAY_ERROR,
|
|
||||||
"Unable to allocate full path to included config");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
snprintf(full_path, len, "%s/%s", parent_dir, path);
|
|
||||||
} else {
|
|
||||||
full_path = strdup(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *real_path = realpath(full_path, NULL);
|
|
||||||
free(full_path);
|
|
||||||
|
|
||||||
if (real_path == NULL) {
|
if (real_path == NULL) {
|
||||||
sway_log(SWAY_DEBUG, "%s not found.", path);
|
sway_log(SWAY_DEBUG, "%s not found.", path);
|
||||||
@ -623,7 +607,7 @@ void load_include_configs(const char *path, struct sway_config *config,
|
|||||||
char **w = p.we_wordv;
|
char **w = p.we_wordv;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < p.we_wordc; ++i) {
|
for (i = 0; i < p.we_wordc; ++i) {
|
||||||
load_include_config(w[i], parent_dir, config, swaynag);
|
load_include_config(w[i], config, swaynag);
|
||||||
}
|
}
|
||||||
wordfree(&p);
|
wordfree(&p);
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,13 @@
|
|||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
#include <wlr/types/wlr_output_swapchain_manager.h>
|
#include <wlr/types/wlr_output_swapchain_manager.h>
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
#include "sway/desktop/transaction.h"
|
||||||
#include "sway/input/cursor.h"
|
#include "sway/input/cursor.h"
|
||||||
|
#include "sway/layers.h"
|
||||||
|
#include "sway/lock.h"
|
||||||
#include "sway/output.h"
|
#include "sway/output.h"
|
||||||
#include "sway/server.h"
|
#include "sway/server.h"
|
||||||
|
#include "sway/tree/arrange.h"
|
||||||
#include "sway/tree/root.h"
|
#include "sway/tree/root.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -22,13 +26,6 @@
|
|||||||
#include <wlr/backend/drm.h>
|
#include <wlr/backend/drm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int output_name_cmp(const void *item, const void *data) {
|
|
||||||
const struct output_config *output = item;
|
|
||||||
const char *name = data;
|
|
||||||
|
|
||||||
return strcmp(output->name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_get_identifier(char *identifier, size_t len,
|
void output_get_identifier(char *identifier, size_t len,
|
||||||
struct sway_output *output) {
|
struct sway_output *output) {
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
@ -588,69 +585,52 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void default_output_config(struct output_config *oc,
|
// find_output_config_from_list returns a merged output_config containing all
|
||||||
struct wlr_output *wlr_output) {
|
// stored configuration that applies to the specified output.
|
||||||
oc->enabled = 1;
|
static struct output_config *find_output_config_from_list(
|
||||||
oc->power = 1;
|
struct output_config **configs, size_t configs_len,
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
struct sway_output *sway_output) {
|
||||||
if (mode != NULL) {
|
|
||||||
oc->width = mode->width;
|
|
||||||
oc->height = mode->height;
|
|
||||||
oc->refresh_rate = mode->refresh / 1000.f;
|
|
||||||
}
|
|
||||||
oc->x = oc->y = -1;
|
|
||||||
oc->scale = 0; // auto
|
|
||||||
oc->scale_filter = SCALE_FILTER_DEFAULT;
|
|
||||||
struct sway_output *output = wlr_output->data;
|
|
||||||
oc->subpixel = output->detected_subpixel;
|
|
||||||
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
||||||
oc->max_render_time = 0;
|
|
||||||
oc->allow_tearing = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
const char *name = sway_output->wlr_output->name;
|
||||||
struct output_config *oc = NULL;
|
|
||||||
|
|
||||||
struct output_config *result = new_output_config(name);
|
struct output_config *result = new_output_config(name);
|
||||||
if (config->reloading) {
|
if (result == NULL) {
|
||||||
default_output_config(result, sway_output->wlr_output);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set output defaults for the "base" configuration
|
||||||
|
result->enabled = 1;
|
||||||
|
result->power = 1;
|
||||||
|
result->scale = 0; // auto
|
||||||
|
result->subpixel = sway_output->detected_subpixel;
|
||||||
|
result->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
result->max_render_time = 0;
|
||||||
|
result->allow_tearing = 0;
|
||||||
|
|
||||||
char id[128];
|
char id[128];
|
||||||
output_get_identifier(id, sizeof(id), sway_output);
|
output_get_identifier(id, sizeof(id), sway_output);
|
||||||
|
|
||||||
int i;
|
// We take a new config and merge on top, in order, the wildcard config,
|
||||||
bool match = false;
|
// output config by name, and output config by identifier to form the final
|
||||||
if ((i = list_seq_find(config->output_configs, output_name_cmp, "*")) >= 0) {
|
// config. If there are multiple matches, they are merged in order.
|
||||||
match = true;
|
struct output_config *oc = NULL;
|
||||||
oc = config->output_configs->items[i];
|
const char *names[] = {"*", name, id, NULL};
|
||||||
|
for (const char **name = &names[0]; *name; name++) {
|
||||||
|
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||||
|
oc = configs[idx];
|
||||||
|
if (strcmp(oc->name, *name) == 0) {
|
||||||
merge_output_config(result, oc);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct output_config *find_output_config(struct sway_output *sway_output) {
|
||||||
|
return find_output_config_from_list(
|
||||||
|
(struct output_config **)config->output_configs->items,
|
||||||
|
config->output_configs->length, sway_output);
|
||||||
|
}
|
||||||
|
|
||||||
static bool config_has_manual_mode(struct output_config *oc) {
|
static bool config_has_manual_mode(struct output_config *oc) {
|
||||||
if (!oc) {
|
if (!oc) {
|
||||||
return false;
|
return false;
|
||||||
@ -663,6 +643,14 @@ static bool config_has_manual_mode(struct output_config *oc) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An output config pre-matched to an output
|
||||||
|
*/
|
||||||
|
struct matched_output_config {
|
||||||
|
struct sway_output *output;
|
||||||
|
struct output_config *config;
|
||||||
|
};
|
||||||
|
|
||||||
struct search_context {
|
struct search_context {
|
||||||
struct wlr_output_swapchain_manager *swapchain_mgr;
|
struct wlr_output_swapchain_manager *swapchain_mgr;
|
||||||
struct wlr_backend_output_state *states;
|
struct wlr_backend_output_state *states;
|
||||||
@ -796,6 +784,7 @@ static bool search_render_format(struct search_context *ctx, size_t output_idx)
|
|||||||
DRM_FORMAT_XRGB2101010,
|
DRM_FORMAT_XRGB2101010,
|
||||||
DRM_FORMAT_XBGR2101010,
|
DRM_FORMAT_XBGR2101010,
|
||||||
DRM_FORMAT_XRGB8888,
|
DRM_FORMAT_XRGB8888,
|
||||||
|
DRM_FORMAT_ARGB8888,
|
||||||
DRM_FORMAT_INVALID,
|
DRM_FORMAT_INVALID,
|
||||||
};
|
};
|
||||||
if (render_format_is_bgr(wlr_output->render_format)) {
|
if (render_format_is_bgr(wlr_output->render_format)) {
|
||||||
@ -881,12 +870,12 @@ static int compare_matched_output_config_priority(const void *a, const void *b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sort_output_configs_by_priority(struct matched_output_config *configs,
|
static void sort_output_configs_by_priority(
|
||||||
size_t configs_len) {
|
struct matched_output_config *configs, size_t configs_len) {
|
||||||
qsort(configs, configs_len, sizeof(*configs), compare_matched_output_config_priority);
|
qsort(configs, configs_len, sizeof(*configs), compare_matched_output_config_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool apply_output_configs(struct matched_output_config *configs,
|
static bool apply_resolved_output_configs(struct matched_output_config *configs,
|
||||||
size_t configs_len, bool test_only, bool degrade_to_off) {
|
size_t configs_len, bool test_only, bool degrade_to_off) {
|
||||||
struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states));
|
struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states));
|
||||||
if (!states) {
|
if (!states) {
|
||||||
@ -963,8 +952,14 @@ bool apply_output_configs(struct matched_output_config *configs,
|
|||||||
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
||||||
cfg->output->wlr_output->name);
|
cfg->output->wlr_output->name);
|
||||||
finalize_output_config(cfg->config, cfg->output);
|
finalize_output_config(cfg->config, cfg->output);
|
||||||
|
arrange_layers(cfg->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arrange_root();
|
||||||
|
arrange_locks();
|
||||||
|
update_output_manager_config(&server);
|
||||||
|
transaction_commit_dirty();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
wlr_output_swapchain_manager_finish(&swapchain_mgr);
|
wlr_output_swapchain_manager_finish(&swapchain_mgr);
|
||||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||||
@ -989,11 +984,12 @@ out:
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply_all_output_configs(void) {
|
bool apply_output_configs(struct output_config **ocs, size_t ocs_len,
|
||||||
|
bool test_only, bool degrade_to_off) {
|
||||||
size_t configs_len = wl_list_length(&root->all_outputs);
|
size_t configs_len = wl_list_length(&root->all_outputs);
|
||||||
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
|
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
|
||||||
if (!configs) {
|
if (!configs) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_idx = 0;
|
int config_idx = 0;
|
||||||
@ -1006,16 +1002,22 @@ void apply_all_output_configs(void) {
|
|||||||
|
|
||||||
struct matched_output_config *config = &configs[config_idx++];
|
struct matched_output_config *config = &configs[config_idx++];
|
||||||
config->output = sway_output;
|
config->output = sway_output;
|
||||||
config->config = find_output_config(sway_output);
|
config->config = find_output_config_from_list(ocs, ocs_len, sway_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_output_configs_by_priority(configs, configs_len);
|
sort_output_configs_by_priority(configs, configs_len);
|
||||||
apply_output_configs(configs, configs_len, false, true);
|
bool ok = apply_resolved_output_configs(configs, configs_len, test_only, degrade_to_off);
|
||||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||||
struct matched_output_config *cfg = &configs[idx];
|
struct matched_output_config *cfg = &configs[idx];
|
||||||
free_output_config(cfg->config);
|
free_output_config(cfg->config);
|
||||||
}
|
}
|
||||||
free(configs);
|
free(configs);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply_stored_output_configs(void) {
|
||||||
|
apply_output_configs((struct output_config **)config->output_configs->items,
|
||||||
|
config->output_configs->length, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_output_config(struct output_config *oc) {
|
void free_output_config(struct output_config *oc) {
|
||||||
|
@ -356,7 +356,7 @@ static void handle_frame(struct wl_listener *listener, void *user_data) {
|
|||||||
wlr_scene_output_for_each_buffer(output->scene_output, send_frame_done_iterator, &data);
|
wlr_scene_output_for_each_buffer(output->scene_output, send_frame_done_iterator, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_output_manager_config(struct sway_server *server) {
|
void update_output_manager_config(struct sway_server *server) {
|
||||||
struct wlr_output_configuration_v1 *config =
|
struct wlr_output_configuration_v1 *config =
|
||||||
wlr_output_configuration_v1_create();
|
wlr_output_configuration_v1_create();
|
||||||
|
|
||||||
@ -386,10 +386,7 @@ static int timer_modeset_handle(void *data) {
|
|||||||
wl_event_source_remove(server->delayed_modeset);
|
wl_event_source_remove(server->delayed_modeset);
|
||||||
server->delayed_modeset = NULL;
|
server->delayed_modeset = NULL;
|
||||||
|
|
||||||
apply_all_output_configs();
|
apply_stored_output_configs();
|
||||||
transaction_commit_dirty();
|
|
||||||
update_output_manager_config(server);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +411,6 @@ static void begin_destroy(struct sway_output *output) {
|
|||||||
|
|
||||||
wl_list_remove(&output->layout_destroy.link);
|
wl_list_remove(&output->layout_destroy.link);
|
||||||
wl_list_remove(&output->destroy.link);
|
wl_list_remove(&output->destroy.link);
|
||||||
wl_list_remove(&output->commit.link);
|
|
||||||
wl_list_remove(&output->present.link);
|
wl_list_remove(&output->present.link);
|
||||||
wl_list_remove(&output->frame.link);
|
wl_list_remove(&output->frame.link);
|
||||||
wl_list_remove(&output->request_state.link);
|
wl_list_remove(&output->request_state.link);
|
||||||
@ -437,26 +433,6 @@ static void handle_layout_destroy(struct wl_listener *listener, void *data) {
|
|||||||
begin_destroy(output);
|
begin_destroy(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_commit(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_output *output = wl_container_of(listener, output, commit);
|
|
||||||
struct wlr_output_event_commit *event = data;
|
|
||||||
|
|
||||||
if (!output->enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->state->committed & (
|
|
||||||
WLR_OUTPUT_STATE_MODE |
|
|
||||||
WLR_OUTPUT_STATE_TRANSFORM |
|
|
||||||
WLR_OUTPUT_STATE_SCALE)) {
|
|
||||||
arrange_layers(output);
|
|
||||||
arrange_output(output);
|
|
||||||
transaction_commit_dirty();
|
|
||||||
|
|
||||||
update_output_manager_config(output->server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_present(struct wl_listener *listener, void *data) {
|
static void handle_present(struct wl_listener *listener, void *data) {
|
||||||
struct sway_output *output = wl_container_of(listener, output, present);
|
struct sway_output *output = wl_container_of(listener, output, present);
|
||||||
struct wlr_output_event_present *output_event = data;
|
struct wlr_output_event_present *output_event = data;
|
||||||
@ -473,7 +449,20 @@ static void handle_request_state(struct wl_listener *listener, void *data) {
|
|||||||
struct sway_output *output =
|
struct sway_output *output =
|
||||||
wl_container_of(listener, output, request_state);
|
wl_container_of(listener, output, request_state);
|
||||||
const struct wlr_output_event_request_state *event = data;
|
const struct wlr_output_event_request_state *event = data;
|
||||||
|
|
||||||
|
uint32_t committed = event->state->committed;
|
||||||
wlr_output_commit_state(output->wlr_output, event->state);
|
wlr_output_commit_state(output->wlr_output, event->state);
|
||||||
|
|
||||||
|
if (committed & (
|
||||||
|
WLR_OUTPUT_STATE_MODE |
|
||||||
|
WLR_OUTPUT_STATE_TRANSFORM |
|
||||||
|
WLR_OUTPUT_STATE_SCALE)) {
|
||||||
|
arrange_layers(output);
|
||||||
|
arrange_output(output);
|
||||||
|
transaction_commit_dirty();
|
||||||
|
|
||||||
|
update_output_manager_config(output->server);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int last_headless_num = 0;
|
static unsigned int last_headless_num = 0;
|
||||||
@ -537,8 +526,6 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
|||||||
output->layout_destroy.notify = handle_layout_destroy;
|
output->layout_destroy.notify = handle_layout_destroy;
|
||||||
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
||||||
output->destroy.notify = handle_destroy;
|
output->destroy.notify = handle_destroy;
|
||||||
wl_signal_add(&wlr_output->events.commit, &output->commit);
|
|
||||||
output->commit.notify = handle_commit;
|
|
||||||
wl_signal_add(&wlr_output->events.present, &output->present);
|
wl_signal_add(&wlr_output->events.present, &output->present);
|
||||||
output->present.notify = handle_present;
|
output->present.notify = handle_present;
|
||||||
wl_signal_add(&wlr_output->events.frame, &output->frame);
|
wl_signal_add(&wlr_output->events.frame, &output->frame);
|
||||||
@ -556,17 +543,9 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
|||||||
request_modeset(server);
|
request_modeset(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_output_layout_change(struct wl_listener *listener,
|
|
||||||
void *data) {
|
|
||||||
struct sway_server *server =
|
|
||||||
wl_container_of(listener, server, output_layout_change);
|
|
||||||
update_output_manager_config(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct output_config *output_config_for_config_head(
|
static struct output_config *output_config_for_config_head(
|
||||||
struct wlr_output_configuration_head_v1 *config_head,
|
struct wlr_output_configuration_head_v1 *config_head) {
|
||||||
struct sway_output *output) {
|
struct output_config *oc = new_output_config(config_head->state.output->name);
|
||||||
struct output_config *oc = new_output_config(output->wlr_output->name);
|
|
||||||
oc->enabled = config_head->state.enabled;
|
oc->enabled = config_head->state.enabled;
|
||||||
if (!oc->enabled) {
|
if (!oc->enabled) {
|
||||||
return oc;
|
return oc;
|
||||||
@ -592,71 +571,48 @@ static struct output_config *output_config_for_config_head(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void output_manager_apply(struct sway_server *server,
|
static void output_manager_apply(struct sway_server *server,
|
||||||
struct wlr_output_configuration_v1 *config, bool test_only) {
|
struct wlr_output_configuration_v1 *cfg, bool test_only) {
|
||||||
size_t configs_len = wl_list_length(&root->all_outputs);
|
bool ok = false;
|
||||||
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
|
size_t configs_len = config->output_configs->length + wl_list_length(&cfg->heads);
|
||||||
|
struct output_config **configs = calloc(configs_len, sizeof(*configs));
|
||||||
if (!configs) {
|
if (!configs) {
|
||||||
return;
|
goto done;
|
||||||
|
}
|
||||||
|
size_t start_new_configs = config->output_configs->length;
|
||||||
|
for (size_t idx = 0; idx < start_new_configs; idx++) {
|
||||||
|
configs[idx] = config->output_configs->items[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_idx = 0;
|
size_t config_idx = start_new_configs;
|
||||||
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 *cfg = &configs[config_idx++];
|
|
||||||
cfg->output = sway_output;
|
|
||||||
|
|
||||||
struct wlr_output_configuration_head_v1 *config_head;
|
struct wlr_output_configuration_head_v1 *config_head;
|
||||||
wl_list_for_each(config_head, &config->heads, link) {
|
wl_list_for_each(config_head, &cfg->heads, link) {
|
||||||
if (config_head->state.output == sway_output->wlr_output) {
|
// Generate the configuration and store it as a temporary
|
||||||
cfg->config = output_config_for_config_head(config_head, sway_output);
|
// config. We keep a record of it so we can remove it later.
|
||||||
break;
|
struct output_config *oc = output_config_for_config_head(config_head);
|
||||||
}
|
configs[config_idx++] = oc;
|
||||||
}
|
|
||||||
if (!cfg->config) {
|
|
||||||
cfg->config = find_output_config(sway_output);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_output_configs_by_priority(configs, configs_len);
|
// Try to commit without degrade to off enabled. Note that this will fail
|
||||||
bool ok = apply_output_configs(configs, configs_len, test_only, false);
|
// if any output configured for enablement fails to be enabled, even if it
|
||||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
// was not part of the config heads we were asked to configure.
|
||||||
struct matched_output_config *cfg = &configs[idx];
|
ok = apply_output_configs(configs, configs_len, test_only, false);
|
||||||
|
for (size_t idx = start_new_configs; idx < configs_len; idx++) {
|
||||||
// Only store new configs for successful non-test commits. Old configs,
|
struct output_config *cfg = configs[idx];
|
||||||
// test-only and failed commits just get freed.
|
|
||||||
bool store_config = false;
|
|
||||||
if (!test_only && ok) {
|
if (!test_only && ok) {
|
||||||
struct wlr_output_configuration_head_v1 *config_head;
|
store_output_config(cfg);
|
||||||
wl_list_for_each(config_head, &config->heads, link) {
|
|
||||||
if (config_head->state.output == cfg->output->wlr_output) {
|
|
||||||
store_config = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (store_config) {
|
|
||||||
store_output_config(cfg->config);
|
|
||||||
} else {
|
} else {
|
||||||
free_output_config(cfg->config);
|
free_output_config(cfg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(configs);
|
free(configs);
|
||||||
|
|
||||||
|
done:
|
||||||
if (ok) {
|
if (ok) {
|
||||||
wlr_output_configuration_v1_send_succeeded(config);
|
wlr_output_configuration_v1_send_succeeded(cfg);
|
||||||
} else {
|
} else {
|
||||||
wlr_output_configuration_v1_send_failed(config);
|
wlr_output_configuration_v1_send_failed(cfg);
|
||||||
}
|
|
||||||
wlr_output_configuration_v1_destroy(config);
|
|
||||||
|
|
||||||
if (!test_only) {
|
|
||||||
update_output_manager_config(server);
|
|
||||||
}
|
}
|
||||||
|
wlr_output_configuration_v1_destroy(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_output_manager_apply(struct wl_listener *listener, void *data) {
|
void handle_output_manager_apply(struct wl_listener *listener, void *data) {
|
||||||
|
@ -559,7 +559,7 @@ static void arrange_output(struct sway_output *output, int width, int height) {
|
|||||||
for (int i = 0; i < output->current.workspaces->length; i++) {
|
for (int i = 0; i < output->current.workspaces->length; i++) {
|
||||||
struct sway_workspace *child = output->current.workspaces->items[i];
|
struct sway_workspace *child = output->current.workspaces->items[i];
|
||||||
|
|
||||||
bool activated = output->current.active_workspace == child;
|
bool activated = output->current.active_workspace == child && output->wlr_output->enabled;
|
||||||
|
|
||||||
wlr_scene_node_reparent(&child->layers.tiling->node, output->layers.tiling);
|
wlr_scene_node_reparent(&child->layers.tiling->node, output->layers.tiling);
|
||||||
wlr_scene_node_reparent(&child->layers.fullscreen->node, output->layers.fullscreen);
|
wlr_scene_node_reparent(&child->layers.fullscreen->node, output->layers.fullscreen);
|
||||||
|
@ -1028,13 +1028,6 @@ static void sway_keyboard_set_layout(struct sway_keyboard *keyboard,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the seat has no active keyboard, set this one
|
|
||||||
struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
|
|
||||||
struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard;
|
|
||||||
if (current_keyboard == NULL) {
|
|
||||||
wlr_seat_set_keyboard(seat, keyboard->wlr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keymap_changed) {
|
if (keymap_changed) {
|
||||||
ipc_event_input("xkb_keymap",
|
ipc_event_input("xkb_keymap",
|
||||||
keyboard->seat_device->input_device);
|
keyboard->seat_device->input_device);
|
||||||
@ -1078,6 +1071,13 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
|||||||
sway_keyboard_set_layout(keyboard, input_config);
|
sway_keyboard_set_layout(keyboard, input_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the seat has no active keyboard, set this one
|
||||||
|
struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
|
||||||
|
struct wlr_keyboard *current_keyboard = seat->keyboard_state.keyboard;
|
||||||
|
if (current_keyboard == NULL) {
|
||||||
|
wlr_seat_set_keyboard(seat, keyboard->wlr);
|
||||||
|
}
|
||||||
|
|
||||||
wl_list_remove(&keyboard->keyboard_key.link);
|
wl_list_remove(&keyboard->keyboard_key.link);
|
||||||
wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key);
|
wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key);
|
||||||
keyboard->keyboard_key.notify = handle_keyboard_key;
|
keyboard->keyboard_key.notify = handle_keyboard_key;
|
||||||
|
29
sway/lock.c
29
sway/lock.c
@ -8,6 +8,7 @@
|
|||||||
#include "sway/layers.h"
|
#include "sway/layers.h"
|
||||||
#include "sway/output.h"
|
#include "sway/output.h"
|
||||||
#include "sway/server.h"
|
#include "sway/server.h"
|
||||||
|
#include "sway/lock.h"
|
||||||
|
|
||||||
struct sway_session_lock_output {
|
struct sway_session_lock_output {
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
@ -19,7 +20,6 @@ struct sway_session_lock_output {
|
|||||||
struct wl_list link; // sway_session_lock::outputs
|
struct wl_list link; // sway_session_lock::outputs
|
||||||
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener commit;
|
|
||||||
|
|
||||||
struct wlr_session_lock_surface_v1 *surface;
|
struct wlr_session_lock_surface_v1 *surface;
|
||||||
|
|
||||||
@ -89,6 +89,17 @@ static void lock_output_reconfigure(struct sway_session_lock_output *output) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arrange_locks(void) {
|
||||||
|
if (server.session_lock.lock == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_session_lock_output *lock_output;
|
||||||
|
wl_list_for_each(lock_output, &server.session_lock.lock->outputs, link) {
|
||||||
|
lock_output_reconfigure(lock_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_new_surface(struct wl_listener *listener, void *data) {
|
static void handle_new_surface(struct wl_listener *listener, void *data) {
|
||||||
struct sway_session_lock *lock = wl_container_of(listener, lock, new_surface);
|
struct sway_session_lock *lock = wl_container_of(listener, lock, new_surface);
|
||||||
struct wlr_session_lock_surface_v1 *lock_surface = data;
|
struct wlr_session_lock_surface_v1 *lock_surface = data;
|
||||||
@ -125,7 +136,6 @@ static void sway_session_lock_output_destroy(struct sway_session_lock_output *ou
|
|||||||
wl_list_remove(&output->surface_map.link);
|
wl_list_remove(&output->surface_map.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove(&output->commit.link);
|
|
||||||
wl_list_remove(&output->destroy.link);
|
wl_list_remove(&output->destroy.link);
|
||||||
wl_list_remove(&output->link);
|
wl_list_remove(&output->link);
|
||||||
|
|
||||||
@ -138,18 +148,6 @@ static void lock_node_handle_destroy(struct wl_listener *listener, void *data) {
|
|||||||
sway_session_lock_output_destroy(output);
|
sway_session_lock_output_destroy(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lock_output_handle_commit(struct wl_listener *listener, void *data) {
|
|
||||||
struct wlr_output_event_commit *event = data;
|
|
||||||
struct sway_session_lock_output *output =
|
|
||||||
wl_container_of(listener, output, commit);
|
|
||||||
if (event->state->committed & (
|
|
||||||
WLR_OUTPUT_STATE_MODE |
|
|
||||||
WLR_OUTPUT_STATE_SCALE |
|
|
||||||
WLR_OUTPUT_STATE_TRANSFORM)) {
|
|
||||||
lock_output_reconfigure(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sway_session_lock_output *session_lock_output_create(
|
static struct sway_session_lock_output *session_lock_output_create(
|
||||||
struct sway_session_lock *lock, struct sway_output *output) {
|
struct sway_session_lock *lock, struct sway_output *output) {
|
||||||
struct sway_session_lock_output *lock_output = calloc(1, sizeof(*lock_output));
|
struct sway_session_lock_output *lock_output = calloc(1, sizeof(*lock_output));
|
||||||
@ -186,9 +184,6 @@ static struct sway_session_lock_output *session_lock_output_create(
|
|||||||
lock_output->destroy.notify = lock_node_handle_destroy;
|
lock_output->destroy.notify = lock_node_handle_destroy;
|
||||||
wl_signal_add(&tree->node.events.destroy, &lock_output->destroy);
|
wl_signal_add(&tree->node.events.destroy, &lock_output->destroy);
|
||||||
|
|
||||||
lock_output->commit.notify = lock_output_handle_commit;
|
|
||||||
wl_signal_add(&output->wlr_output->events.commit, &lock_output->commit);
|
|
||||||
|
|
||||||
lock_output_reconfigure(lock_output);
|
lock_output_reconfigure(lock_output);
|
||||||
|
|
||||||
wl_list_insert(&lock->outputs, &lock_output->link);
|
wl_list_insert(&lock->outputs, &lock_output->link);
|
||||||
|
@ -277,9 +277,6 @@ bool server_init(struct sway_server *server) {
|
|||||||
|
|
||||||
server->new_output.notify = handle_new_output;
|
server->new_output.notify = handle_new_output;
|
||||||
wl_signal_add(&server->backend->events.new_output, &server->new_output);
|
wl_signal_add(&server->backend->events.new_output, &server->new_output);
|
||||||
server->output_layout_change.notify = handle_output_layout_change;
|
|
||||||
wl_signal_add(&root->output_layout->events.change,
|
|
||||||
&server->output_layout_change);
|
|
||||||
|
|
||||||
server->xdg_output_manager_v1 =
|
server->xdg_output_manager_v1 =
|
||||||
wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout);
|
wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout);
|
||||||
|
@ -314,14 +314,9 @@ void arrange_output(struct sway_output *output) {
|
|||||||
if (config->reloading) {
|
if (config->reloading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct wlr_box output_box;
|
if (!output->wlr_output->enabled) {
|
||||||
wlr_output_layout_get_box(root->output_layout,
|
return;
|
||||||
output->wlr_output, &output_box);
|
}
|
||||||
output->lx = output_box.x;
|
|
||||||
output->ly = output_box.y;
|
|
||||||
output->width = output_box.width;
|
|
||||||
output->height = output_box.height;
|
|
||||||
|
|
||||||
for (int i = 0; i < output->workspaces->length; ++i) {
|
for (int i = 0; i < output->workspaces->length; ++i) {
|
||||||
struct sway_workspace *workspace = output->workspaces->items[i];
|
struct sway_workspace *workspace = output->workspaces->items[i];
|
||||||
arrange_workspace(workspace);
|
arrange_workspace(workspace);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "sway/tree/workspace.h"
|
#include "sway/tree/workspace.h"
|
||||||
#include "sway/xdg_decoration.h"
|
#include "sway/xdg_decoration.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "pango.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "stringop.h"
|
#include "stringop.h"
|
||||||
|
|
||||||
@ -499,6 +500,7 @@ void container_destroy(struct sway_container *con) {
|
|||||||
}
|
}
|
||||||
free(con->title);
|
free(con->title);
|
||||||
free(con->formatted_title);
|
free(con->formatted_title);
|
||||||
|
free(con->title_format);
|
||||||
list_free(con->pending.children);
|
list_free(con->pending.children);
|
||||||
list_free(con->current.children);
|
list_free(con->current.children);
|
||||||
|
|
||||||
@ -645,6 +647,91 @@ bool container_has_ancestor(struct sway_container *descendant,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *escape_pango_markup(const char *buffer) {
|
||||||
|
size_t length = escape_markup_text(buffer, NULL);
|
||||||
|
char *escaped_title = calloc(length + 1, sizeof(char));
|
||||||
|
escape_markup_text(buffer, escaped_title);
|
||||||
|
return escaped_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t append_prop(char *buffer, const char *value) {
|
||||||
|
if (!value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// If using pango_markup in font, we need to escape all markup chars
|
||||||
|
// from values to make sure tags are not inserted by clients
|
||||||
|
if (config->pango_markup) {
|
||||||
|
char *escaped_value = escape_pango_markup(value);
|
||||||
|
lenient_strcat(buffer, escaped_value);
|
||||||
|
size_t len = strlen(escaped_value);
|
||||||
|
free(escaped_value);
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
lenient_strcat(buffer, value);
|
||||||
|
return strlen(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate and return the length of the formatted title.
|
||||||
|
* If buffer is not NULL, also populate the buffer with the formatted title.
|
||||||
|
*/
|
||||||
|
size_t parse_title_format(struct sway_container *container, char *buffer) {
|
||||||
|
if (!container->title_format || strcmp(container->title_format, "%title") == 0) {
|
||||||
|
if (container->view) {
|
||||||
|
return append_prop(buffer, view_get_title(container->view));
|
||||||
|
} else {
|
||||||
|
return container_build_representation(container->pending.layout, container->pending.children, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
char *format = container->title_format;
|
||||||
|
char *next = strchr(format, '%');
|
||||||
|
while (next) {
|
||||||
|
// Copy everything up to the %
|
||||||
|
lenient_strncat(buffer, format, next - format);
|
||||||
|
len += next - format;
|
||||||
|
format = next;
|
||||||
|
|
||||||
|
if (strncmp(next, "%title", 6) == 0) {
|
||||||
|
if (container->view) {
|
||||||
|
len += append_prop(buffer, view_get_title(container->view));
|
||||||
|
} else {
|
||||||
|
len += container_build_representation(container->pending.layout, container->pending.children, buffer);
|
||||||
|
}
|
||||||
|
format += 6;
|
||||||
|
} else if (container->view) {
|
||||||
|
if (strncmp(next, "%app_id", 7) == 0) {
|
||||||
|
len += append_prop(buffer, view_get_app_id(container->view));
|
||||||
|
format += 7;
|
||||||
|
} else if (strncmp(next, "%class", 6) == 0) {
|
||||||
|
len += append_prop(buffer, view_get_class(container->view));
|
||||||
|
format += 6;
|
||||||
|
} else if (strncmp(next, "%instance", 9) == 0) {
|
||||||
|
len += append_prop(buffer, view_get_instance(container->view));
|
||||||
|
format += 9;
|
||||||
|
} else if (strncmp(next, "%shell", 6) == 0) {
|
||||||
|
len += append_prop(buffer, view_get_shell(container->view));
|
||||||
|
format += 6;
|
||||||
|
} else {
|
||||||
|
lenient_strcat(buffer, "%");
|
||||||
|
++format;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lenient_strcat(buffer, "%");
|
||||||
|
++format;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
next = strchr(format, '%');
|
||||||
|
}
|
||||||
|
lenient_strcat(buffer, format);
|
||||||
|
len += strlen(format);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate and return the length of the tree representation.
|
* Calculate and return the length of the tree representation.
|
||||||
* An example tree representation is: V[Terminal, Firefox]
|
* An example tree representation is: V[Terminal, Firefox]
|
||||||
@ -700,16 +787,14 @@ size_t container_build_representation(enum sway_container_layout layout,
|
|||||||
|
|
||||||
void container_update_representation(struct sway_container *con) {
|
void container_update_representation(struct sway_container *con) {
|
||||||
if (!con->view) {
|
if (!con->view) {
|
||||||
size_t len = container_build_representation(con->pending.layout,
|
size_t len = parse_title_format(con, NULL);
|
||||||
con->pending.children, NULL);
|
|
||||||
free(con->formatted_title);
|
free(con->formatted_title);
|
||||||
con->formatted_title = calloc(len + 1, sizeof(char));
|
con->formatted_title = calloc(len + 1, sizeof(char));
|
||||||
if (!sway_assert(con->formatted_title,
|
if (!sway_assert(con->formatted_title,
|
||||||
"Unable to allocate title string")) {
|
"Unable to allocate title string")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
container_build_representation(con->pending.layout, con->pending.children,
|
parse_title_format(con, con->formatted_title);
|
||||||
con->formatted_title);
|
|
||||||
|
|
||||||
if (con->title_bar.title_text) {
|
if (con->title_bar.title_text) {
|
||||||
sway_text_node_set_text(con->title_bar.title_text, con->formatted_title);
|
sway_text_node_set_text(con->title_bar.title_text, con->formatted_title);
|
||||||
|
@ -180,12 +180,7 @@ void output_enable(struct sway_output *output) {
|
|||||||
ws->layout = output_get_default_layout(output);
|
ws->layout = output_get_default_layout(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
input_manager_configure_xcursor();
|
|
||||||
|
|
||||||
wl_signal_emit_mutable(&root->events.new_node, &output->node);
|
wl_signal_emit_mutable(&root->events.new_node, &output->node);
|
||||||
|
|
||||||
arrange_layers(output);
|
|
||||||
arrange_root();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void evacuate_sticky(struct sway_workspace *old_ws,
|
static void evacuate_sticky(struct sway_workspace *old_ws,
|
||||||
@ -300,13 +295,6 @@ void output_disable(struct sway_output *output) {
|
|||||||
list_del(root->outputs, index);
|
list_del(root->outputs, index);
|
||||||
|
|
||||||
output->enabled = false;
|
output->enabled = false;
|
||||||
|
|
||||||
arrange_root();
|
|
||||||
|
|
||||||
// Reconfigure all devices, since devices with map_to_output directives for
|
|
||||||
// an output that goes offline should stop sending events as long as the
|
|
||||||
// output remains offline.
|
|
||||||
input_manager_configure_all_input_mappings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_begin_destroy(struct sway_output *output) {
|
void output_begin_destroy(struct sway_output *output) {
|
||||||
|
@ -19,12 +19,6 @@
|
|||||||
|
|
||||||
struct sway_root *root;
|
struct sway_root *root;
|
||||||
|
|
||||||
static void output_layout_handle_change(struct wl_listener *listener,
|
|
||||||
void *data) {
|
|
||||||
arrange_root();
|
|
||||||
transaction_commit_dirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sway_root *root_create(struct wl_display *wl_display) {
|
struct sway_root *root_create(struct wl_display *wl_display) {
|
||||||
struct sway_root *root = calloc(1, sizeof(struct sway_root));
|
struct sway_root *root = calloc(1, sizeof(struct sway_root));
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@ -81,14 +75,10 @@ struct sway_root *root_create(struct wl_display *wl_display) {
|
|||||||
root->non_desktop_outputs = create_list();
|
root->non_desktop_outputs = create_list();
|
||||||
root->scratchpad = create_list();
|
root->scratchpad = create_list();
|
||||||
|
|
||||||
root->output_layout_change.notify = output_layout_handle_change;
|
|
||||||
wl_signal_add(&root->output_layout->events.change,
|
|
||||||
&root->output_layout_change);
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
void root_destroy(struct sway_root *root) {
|
void root_destroy(struct sway_root *root) {
|
||||||
wl_list_remove(&root->output_layout_change.link);
|
|
||||||
list_free(root->scratchpad);
|
list_free(root->scratchpad);
|
||||||
list_free(root->non_desktop_outputs);
|
list_free(root->non_desktop_outputs);
|
||||||
list_free(root->outputs);
|
list_free(root->outputs);
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "sway/tree/workspace.h"
|
#include "sway/tree/workspace.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/xdg_decoration.h"
|
#include "sway/xdg_decoration.h"
|
||||||
#include "pango.h"
|
|
||||||
#include "stringop.h"
|
#include "stringop.h"
|
||||||
|
|
||||||
bool view_init(struct sway_view *view, enum sway_view_type type,
|
bool view_init(struct sway_view *view, enum sway_view_type type,
|
||||||
@ -81,8 +80,6 @@ void view_destroy(struct sway_view *view) {
|
|||||||
|
|
||||||
view_assign_ctx(view, NULL);
|
view_assign_ctx(view, NULL);
|
||||||
wlr_scene_node_destroy(&view->scene_tree->node);
|
wlr_scene_node_destroy(&view->scene_tree->node);
|
||||||
free(view->title_format);
|
|
||||||
|
|
||||||
if (view->impl->destroy) {
|
if (view->impl->destroy) {
|
||||||
view->impl->destroy(view);
|
view->impl->destroy(view);
|
||||||
} else {
|
} else {
|
||||||
@ -991,77 +988,6 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *escape_pango_markup(const char *buffer) {
|
|
||||||
size_t length = escape_markup_text(buffer, NULL);
|
|
||||||
char *escaped_title = calloc(length + 1, sizeof(char));
|
|
||||||
escape_markup_text(buffer, escaped_title);
|
|
||||||
return escaped_title;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t append_prop(char *buffer, const char *value) {
|
|
||||||
if (!value) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// If using pango_markup in font, we need to escape all markup chars
|
|
||||||
// from values to make sure tags are not inserted by clients
|
|
||||||
if (config->pango_markup) {
|
|
||||||
char *escaped_value = escape_pango_markup(value);
|
|
||||||
lenient_strcat(buffer, escaped_value);
|
|
||||||
size_t len = strlen(escaped_value);
|
|
||||||
free(escaped_value);
|
|
||||||
return len;
|
|
||||||
} else {
|
|
||||||
lenient_strcat(buffer, value);
|
|
||||||
return strlen(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate and return the length of the formatted title.
|
|
||||||
* If buffer is not NULL, also populate the buffer with the formatted title.
|
|
||||||
*/
|
|
||||||
static size_t parse_title_format(struct sway_view *view, char *buffer) {
|
|
||||||
if (!view->title_format || strcmp(view->title_format, "%title") == 0) {
|
|
||||||
return append_prop(buffer, view_get_title(view));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = 0;
|
|
||||||
char *format = view->title_format;
|
|
||||||
char *next = strchr(format, '%');
|
|
||||||
while (next) {
|
|
||||||
// Copy everything up to the %
|
|
||||||
lenient_strncat(buffer, format, next - format);
|
|
||||||
len += next - format;
|
|
||||||
format = next;
|
|
||||||
|
|
||||||
if (strncmp(next, "%title", 6) == 0) {
|
|
||||||
len += append_prop(buffer, view_get_title(view));
|
|
||||||
format += 6;
|
|
||||||
} else if (strncmp(next, "%app_id", 7) == 0) {
|
|
||||||
len += append_prop(buffer, view_get_app_id(view));
|
|
||||||
format += 7;
|
|
||||||
} else if (strncmp(next, "%class", 6) == 0) {
|
|
||||||
len += append_prop(buffer, view_get_class(view));
|
|
||||||
format += 6;
|
|
||||||
} else if (strncmp(next, "%instance", 9) == 0) {
|
|
||||||
len += append_prop(buffer, view_get_instance(view));
|
|
||||||
format += 9;
|
|
||||||
} else if (strncmp(next, "%shell", 6) == 0) {
|
|
||||||
len += append_prop(buffer, view_get_shell(view));
|
|
||||||
format += 6;
|
|
||||||
} else {
|
|
||||||
lenient_strcat(buffer, "%");
|
|
||||||
++format;
|
|
||||||
++len;
|
|
||||||
}
|
|
||||||
next = strchr(format, '%');
|
|
||||||
}
|
|
||||||
lenient_strcat(buffer, format);
|
|
||||||
len += strlen(format);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void view_update_app_id(struct sway_view *view) {
|
void view_update_app_id(struct sway_view *view) {
|
||||||
const char *app_id = view_get_app_id(view);
|
const char *app_id = view_get_app_id(view);
|
||||||
|
|
||||||
@ -1090,7 +1016,7 @@ void view_update_title(struct sway_view *view, bool force) {
|
|||||||
free(view->container->title);
|
free(view->container->title);
|
||||||
free(view->container->formatted_title);
|
free(view->container->formatted_title);
|
||||||
|
|
||||||
size_t len = parse_title_format(view, NULL);
|
size_t len = parse_title_format(view->container, NULL);
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
char *buffer = calloc(len + 1, sizeof(char));
|
char *buffer = calloc(len + 1, sizeof(char));
|
||||||
@ -1098,7 +1024,7 @@ void view_update_title(struct sway_view *view, bool force) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_title_format(view, buffer);
|
parse_title_format(view->container, buffer);
|
||||||
view->container->formatted_title = buffer;
|
view->container->formatted_title = buffer;
|
||||||
} else {
|
} else {
|
||||||
view->container->formatted_title = NULL;
|
view->container->formatted_title = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user