mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -04:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
273d4be3c6
37 changed files with 550 additions and 135 deletions
36
README.fr.md
36
README.fr.md
|
|
@ -6,14 +6,8 @@ avec i3, **en cours de développement**. Lisez la
|
|||
IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway sur
|
||||
irc.freenode.net).
|
||||
|
||||
[](https://sr.ht/ICd5.png)
|
||||
|
||||
Si vous souhaitez soutenir le développement de Sway, vous pouvez contribuer à [ma page
|
||||
Patreon](https://patreon.com/sircmpwn) ou aux [primes](https://github.com/swaywm/sway/issues/986)
|
||||
pour des fonctionnalités spécifiques.
|
||||
Tout le monde est invité à réclamer une prime et vous pouvez donner une prime pour n'importe quelle
|
||||
fonctionnalité souhaitée. Patreon est plus utile pour supporter l'état général et la
|
||||
maintenance de Sway.
|
||||
Si vous souhaitez soutenir le développement de Sway, vous pouvez contribuer à [la page
|
||||
Patreon de SirCmpwn](https://patreon.com/sircmpwn).
|
||||
|
||||
## Aide en français
|
||||
|
||||
|
|
@ -39,21 +33,21 @@ IRC ou envoyez un e-mail à sir@cmpwn.com (en anglais seulement) pour des consei
|
|||
|
||||
Installez les dépendances :
|
||||
|
||||
* meson
|
||||
* [wlc](https://github.com/Cloudef/wlc)
|
||||
* meson \*
|
||||
* [wlroots](https://github.com/swaywm/wlroots)
|
||||
* wayland
|
||||
* xwayland
|
||||
* libinput >= 1.6.0
|
||||
* libcap
|
||||
* wayland-protocols \*
|
||||
* pcre
|
||||
* json-c >= 0.13
|
||||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 *
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (requis pour les pages man)
|
||||
* git
|
||||
* gdk-pixbuf2 \*\*
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optionnel: requis pour les pages man) \*
|
||||
* git \*
|
||||
|
||||
_\*Uniquement requis pour swaybar, swaybg_
|
||||
_\*Requis uniquement pour la compilation_
|
||||
|
||||
_\*\*Optionnel: requis uniquement pour swaybg_
|
||||
|
||||
Exécutez ces commandes :
|
||||
|
||||
|
|
@ -65,6 +59,8 @@ Sur les systèmes sans logind, vous devez suid le binaire de sway :
|
|||
|
||||
sudo chmod a+s /usr/local/bin/sway
|
||||
|
||||
Sway se débarassera des permissions *root* peu de temps après le démarrage.
|
||||
|
||||
## Configuration
|
||||
|
||||
Si vous utilisez déjà i3, copiez votre configuration i3 à `~/.config/sway/config` et
|
||||
|
|
@ -72,10 +68,6 @@ cela va fonctionner. Sinon, copiez l'exemple de fichier de configuration à
|
|||
`~/.config/sway/config`. Il se trouve généralement dans `/etc/sway/config`.
|
||||
Exécutez `man 5 sway` pour l'information sur la configuration.
|
||||
|
||||
Mes propres dotfiles sont disponibles [ici](https://git.sr.ht/~sircmpwn/dotfiles) si
|
||||
vous voulez un peu d'inspiration. Je vous recommande aussi de consulter le
|
||||
[wiki](https://github.com/swaywm/sway/wiki).
|
||||
|
||||
## Exécution
|
||||
|
||||
Exécutez `sway` à partir d'un TTY. Certains gestionnaires d'affichage peuvent fonctionner,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
[**English**](https://github.com/swaywm/sway/blob/master/README.md#sway--) - [日本語](https://github.com/swaywm/sway/blob/master/README.ja.md#sway--) - [Deutsch](https://github.com/swaywm/sway/blob/master/README.de.md#sway--) - [Ελληνικά](https://github.com/swaywm/sway/blob/master/README.el.md#sway--) - [Français](https://github.com/swaywm/sway/blob/master/README.fr.md#sway--) - [Українська](https://github.com/swaywm/sway/blob/master/README.uk.md#sway--) - [Italiano](https://github.com/swaywm/sway/blob/master/README.it.md#sway--) - [Português](https://github.com/swaywm/sway/blob/master/README.pt.md#sway--) -
|
||||
[Русский](https://github.com/swaywm/sway/blob/master/README.ru.md#sway--) - [Български](https://github.com/swaywm/sway/blob/master/README.bg.md#sway--) - [Español](https://github.com/swaywm/sway/blob/master/README.es.md#sway--) -
|
||||
[Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--)
|
||||
[Polski](https://github.com/swaywm/sway/blob/master/README.pl.md#sway--) - [中文-简体](https://github.com/swaywm/sway/blob/master/README-zh-CN.md#sway--)
|
||||
|
||||
sway is an i3-compatible [Wayland](http://wayland.freedesktop.org/) compositor.
|
||||
Read the [FAQ](https://github.com/swaywm/sway/wiki). Join the [IRC
|
||||
|
|
|
|||
49
README.uk.md
49
README.uk.md
|
|
@ -1,20 +1,12 @@
|
|||
# sway
|
||||
|
||||
**Sway** це сумісний з i3 композитор [Wayland](http://wayland.freedesktop.org/)
|
||||
(**у стані розробки**). Ознайомтесь з
|
||||
[ЧаПами](https://github.com/swaywm/sway/wiki). Приєднуйтесь до [спільноти в
|
||||
Sway це сумісний з i3 композитор [Wayland](http://wayland.freedesktop.org/).
|
||||
Ознайомтесь з [ЧаПами](https://github.com/swaywm/sway/wiki). Приєднуйтесь до [спільноти в
|
||||
IRC](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway на
|
||||
irc.freenode.net).
|
||||
|
||||
[](https://sr.ht/ICd5.png)
|
||||
|
||||
Якщо ви хочете підтримати розробку Sway, ви можете зробити свій внесок у
|
||||
[SirCmpwn'ову сторінку Patreon](https://patreon.com/sircmpwn) або до
|
||||
[фонду винагород](https://github.com/swaywm/sway/issues/986) за реалізацію
|
||||
певного функціоналу.
|
||||
Кожен може виставити винагороду за реалізацію довільної функції
|
||||
(і, відповідно, забрати її собі, виконавши це завдання);
|
||||
кошти від сторінки Patreon підтримують загальну розробку та підтримку Sway.
|
||||
Якщо ви маєте бажання підтримати розробку sway, ви можете зробити свій внесок на сторінці
|
||||
[SirCmpwn у Patreon](https://patreon.com/sircmpwn).
|
||||
|
||||
## Підтримка українською мовою
|
||||
|
||||
|
|
@ -39,28 +31,28 @@ Sway доступний у багатьох дистрибутивах Linux (а
|
|||
для інформації щодо встановлення на вашому дистрибутиві.
|
||||
|
||||
Якщо ви готові та зацікавлені запакувати і підтримувати Sway у вашому
|
||||
дистрибутиві, будемо раді вас бачити у нашому каналі IRC. Ви також можете
|
||||
спитати порад за адресою sir@cmpwn.com.
|
||||
дистрибутиві, звертайтесь за порадами до нашого каналу в IRC або
|
||||
пишіть на електронну пошту [sir@cmpwn.com](mailto:sir@cmpwn.com).
|
||||
|
||||
### З вихідного коду
|
||||
|
||||
Встановіть залежності:
|
||||
|
||||
* meson
|
||||
* [wlc](https://github.com/Cloudef/wlc)
|
||||
* meson \*
|
||||
* [wlroots](https://github.com/swaywm/wlroots)
|
||||
* wayland
|
||||
* xwayland
|
||||
* libinput >= 1.6.0
|
||||
* libcap
|
||||
* wayland-protocols \*
|
||||
* pcre
|
||||
* json-c >= 0.13
|
||||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 *
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (required for man pages)
|
||||
* git
|
||||
* gdk-pixbuf2 \*\*
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (необов'язково, необхідно для сторінок man) \*
|
||||
* git \*
|
||||
|
||||
_\*Лише для swaybar, swaybg_
|
||||
_\*Лише для компіляції_
|
||||
|
||||
_\*\*Необов'язково, необхідно для swaybg_
|
||||
|
||||
Виконайте ці команди:
|
||||
|
||||
|
|
@ -68,15 +60,12 @@ _\*Лише для swaybar, swaybg_
|
|||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
На системах **з** logind, варто встановити декілька можливостей (caps)
|
||||
на виконуваний файл sway:
|
||||
|
||||
sudo setcap "cap_sys_ptrace,cap_sys_tty_config=eip" /usr/local/bin/sway
|
||||
|
||||
На системах **без** logind, необхідно встановити біт SUID на виконуваний файл sway:
|
||||
На системах без logind, необхідно встановити біт SUID на виконуваний файл sway:
|
||||
|
||||
sudo chmod a+s /usr/local/bin/sway
|
||||
|
||||
Sway втратить права доступу root незабаром після запуску.
|
||||
|
||||
## Налаштування
|
||||
|
||||
Якщо ви вже використовуєте i3, скопіюйте свій файл налаштувань
|
||||
|
|
|
|||
68
README.zh-CN.md
Normal file
68
README.zh-CN.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# sway
|
||||
|
||||
sway 是和 i3 兼容的 [Wayland](http://wayland.freedesktop.org/) compositor.
|
||||
阅读 [FAQ](https://github.com/swaywm/sway/wiki). 加入 [IRC
|
||||
频道](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on
|
||||
irc.freenode.net).
|
||||
|
||||
如果你想要支持 sway 的发展, 请到 [SirCmpwn's
|
||||
Patreon page](https://patreon.com/sircmpwn)贡献.
|
||||
|
||||
## 发布签名
|
||||
|
||||
发布是以 [B22DA89A](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x52CB6609B22DA89A) 签名
|
||||
并发布在 [GitHub](https://github.com/swaywm/sway/releases).
|
||||
|
||||
## 安装
|
||||
|
||||
### 从软件包中
|
||||
|
||||
Sway 在很多发行版中可用. 尝试在你的发行版中安装 "sway" 包.
|
||||
如何这不可用, 请到 [此 wiki 页](https://github.com/swaywm/sway/wiki/Unsupported-packages)
|
||||
检查针对你的发行版关于安装的信息.
|
||||
|
||||
如果你有兴趣给你的发行版打包 sway, 停下来到 IRC 频道或者发邮件至 sir@cmpwn.com 获取建议.
|
||||
|
||||
### 从源代码编译
|
||||
|
||||
安装依赖:
|
||||
|
||||
* meson \*
|
||||
* [wlroots](https://github.com/swaywm/wlroots)
|
||||
* wayland
|
||||
* wayland-protocols \*
|
||||
* pcre
|
||||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 \*\*
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (可选的: man pages) \*
|
||||
* git \*
|
||||
|
||||
_\*编译时依赖_
|
||||
|
||||
_\*\*可选的: swaybg 依赖_
|
||||
|
||||
运行这些命令:
|
||||
|
||||
meson build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
在没有 logind 的系统上, 你需要给 sway 二进制设置 suid:
|
||||
|
||||
sudo chmod a+s /usr/local/bin/sway
|
||||
|
||||
Sway 将会在启动后尽快丢掉 root 权限.
|
||||
|
||||
## 配置
|
||||
|
||||
如果你已经在使用 i3, 接下来复制你的 i3 配置到 `~/.config/sway/config`
|
||||
它可以直接工作. 或者, 复制样本配置文件到
|
||||
`~/.config/sway/config`. 它通常位于 `/etc/sway/config`.
|
||||
运行 `man 5 sway` 获取关于配置的信息.
|
||||
|
||||
## 运行
|
||||
|
||||
从 TTY 中运行 `sway` . 某些显示管理器可能会工作但并不被 sway 支持
|
||||
(已知的 gdm 工作得非常好).
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <wayland-server-protocol.h>
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
|
|
@ -54,3 +55,23 @@ float parse_float(const char *value) {
|
|||
}
|
||||
return flt;
|
||||
}
|
||||
|
||||
|
||||
const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel) {
|
||||
switch (subpixel) {
|
||||
case WL_OUTPUT_SUBPIXEL_UNKNOWN:
|
||||
return "unknown";
|
||||
case WL_OUTPUT_SUBPIXEL_NONE:
|
||||
return "none";
|
||||
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
|
||||
return "rgb";
|
||||
case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
|
||||
return "bgr";
|
||||
case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
|
||||
return "vrgb";
|
||||
case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
|
||||
return "vbgr";
|
||||
}
|
||||
sway_assert(false, "Unknown value for wl_output_subpixel.");
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ sway_cmd cmd_fullscreen;
|
|||
sway_cmd cmd_gaps;
|
||||
sway_cmd cmd_hide_edge_borders;
|
||||
sway_cmd cmd_include;
|
||||
sway_cmd cmd_inhibit_idle;
|
||||
sway_cmd cmd_input;
|
||||
sway_cmd cmd_seat;
|
||||
sway_cmd cmd_ipc;
|
||||
|
|
@ -261,6 +262,7 @@ sway_cmd output_cmd_enable;
|
|||
sway_cmd output_cmd_mode;
|
||||
sway_cmd output_cmd_position;
|
||||
sway_cmd output_cmd_scale;
|
||||
sway_cmd output_cmd_subpixel;
|
||||
sway_cmd output_cmd_transform;
|
||||
|
||||
sway_cmd seat_cmd_attach;
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ struct output_config {
|
|||
int x, y;
|
||||
float scale;
|
||||
int32_t transform;
|
||||
enum wl_output_subpixel subpixel;
|
||||
|
||||
char *background;
|
||||
char *background_option;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct criteria {
|
|||
char *cmdlist;
|
||||
char *target; // workspace or output name for `assign` criteria
|
||||
|
||||
bool autofail; // __focused__ while no focus or n/a for focused view
|
||||
pcre *title;
|
||||
pcre *shell;
|
||||
pcre *app_id;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@
|
|||
#include <wlr/types/wlr_idle.h>
|
||||
#include "sway/server.h"
|
||||
|
||||
enum sway_idle_inhibit_mode {
|
||||
INHIBIT_IDLE_APPLICATION, // Application set inhibitor (when visible)
|
||||
INHIBIT_IDLE_FOCUS, // User set inhibitor when focused
|
||||
INHIBIT_IDLE_FULLSCREEN, // User set inhibitor when fullscreen + visible
|
||||
INHIBIT_IDLE_OPEN, // User set inhibitor while open
|
||||
INHIBIT_IDLE_VISIBLE // User set inhibitor when visible
|
||||
};
|
||||
|
||||
struct sway_idle_inhibit_manager_v1 {
|
||||
struct wlr_idle_inhibit_manager_v1 *wlr_manager;
|
||||
struct wl_listener new_idle_inhibitor_v1;
|
||||
|
|
@ -15,14 +23,24 @@ struct sway_idle_inhibit_manager_v1 {
|
|||
struct sway_idle_inhibitor_v1 {
|
||||
struct sway_idle_inhibit_manager_v1 *manager;
|
||||
struct sway_view *view;
|
||||
enum sway_idle_inhibit_mode mode;
|
||||
|
||||
struct wl_list link;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
void idle_inhibit_v1_check_active(
|
||||
void sway_idle_inhibit_v1_check_active(
|
||||
struct sway_idle_inhibit_manager_v1 *manager);
|
||||
|
||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||
enum sway_idle_inhibit_mode mode);
|
||||
|
||||
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
||||
struct sway_view *view);
|
||||
|
||||
void sway_idle_inhibit_v1_user_inhibitor_destroy(
|
||||
struct sway_idle_inhibitor_v1 *inhibitor);
|
||||
|
||||
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
|
||||
struct wl_display *wl_display, struct wlr_idle *idle);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ struct sway_output {
|
|||
|
||||
int lx, ly; // layout coords
|
||||
int width, height; // transformed buffer size
|
||||
enum wl_output_subpixel detected_subpixel;
|
||||
|
||||
bool enabled, configured;
|
||||
list_t *workspaces;
|
||||
|
|
|
|||
|
|
@ -215,10 +215,9 @@ size_t container_titlebar_height(void);
|
|||
void floating_calculate_constraints(int *min_width, int *max_width,
|
||||
int *min_height, int *max_height);
|
||||
|
||||
/**
|
||||
* Resize and center the container in its workspace.
|
||||
*/
|
||||
void container_init_floating(struct sway_container *container);
|
||||
void container_floating_resize_and_center(struct sway_container *con);
|
||||
|
||||
void container_floating_set_default_size(struct sway_container *con);
|
||||
|
||||
void container_set_floating(struct sway_container *container, bool enable);
|
||||
|
||||
|
|
|
|||
|
|
@ -85,4 +85,6 @@ struct sway_container *root_find_container(
|
|||
|
||||
void root_get_box(struct sway_root *root, struct wlr_box *box);
|
||||
|
||||
void root_rename_pid_workspaces(const char *old_name, const char *new_name);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <wayland-server-protocol.h>
|
||||
|
||||
/**
|
||||
* Wrap i into the range [0, max[
|
||||
|
|
@ -29,4 +30,6 @@ bool parse_boolean(const char *boolean, bool current);
|
|||
*/
|
||||
float parse_float(const char *value);
|
||||
|
||||
const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ static struct cmd_handler command_handlers[] = {
|
|||
{ "exit", cmd_exit },
|
||||
{ "floating", cmd_floating },
|
||||
{ "fullscreen", cmd_fullscreen },
|
||||
{ "inhibit_idle", cmd_inhibit_idle },
|
||||
{ "kill", cmd_kill },
|
||||
{ "layout", cmd_layout },
|
||||
{ "mark", cmd_mark },
|
||||
|
|
@ -276,7 +277,6 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
|
|||
// Var replacement, for all but first argument of set
|
||||
for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) {
|
||||
argv[i] = do_var_replacement(argv[i]);
|
||||
unescape_string(argv[i]);
|
||||
}
|
||||
|
||||
if (!config->handler_context.using_criteria) {
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
struct sway_binding *config_binding = mode_bindings->items[i];
|
||||
if (binding_key_compare(binding, config_binding)) {
|
||||
sway_log(SWAY_INFO, "Overwriting binding '%s' for device '%s' "
|
||||
"from `%s` to `%s`", argv[0], binding->input,
|
||||
"to `%s` from `%s`", argv[0], binding->input,
|
||||
binding->command, config_binding->command);
|
||||
if (warn) {
|
||||
config_add_swaynag_warning("Overwriting binding"
|
||||
|
|
@ -420,7 +420,7 @@ struct cmd_results *cmd_bindswitch(int argc, char **argv) {
|
|||
for (int i = 0; i < mode_bindings->length; ++i) {
|
||||
struct sway_switch_binding *config_binding = mode_bindings->items[i];
|
||||
if (binding_switch_compare(binding, config_binding)) {
|
||||
sway_log(SWAY_INFO, "Overwriting binding '%s' from `%s` to `%s`",
|
||||
sway_log(SWAY_INFO, "Overwriting binding '%s' to `%s` from `%s`",
|
||||
argv[0], binding->command, config_binding->command);
|
||||
if (warn) {
|
||||
config_add_swaynag_warning("Overwriting binding"
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
|
|||
|
||||
container_set_floating(container, wants_floating);
|
||||
|
||||
arrange_workspace(container->workspace);
|
||||
// Floating containers in the scratchpad should be ignored
|
||||
if (container->workspace) {
|
||||
arrange_workspace(container->workspace);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
|
|||
51
sway/commands/inhibit_idle.c
Normal file
51
sway/commands/inhibit_idle.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <string.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
||||
struct cmd_results *cmd_inhibit_idle(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "inhibit_idle", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
if (!con || !con->view) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Only views can have idle inhibitors");
|
||||
}
|
||||
|
||||
bool clear = false;
|
||||
enum sway_idle_inhibit_mode mode;
|
||||
if (strcmp(argv[0], "focus") == 0) {
|
||||
mode = INHIBIT_IDLE_FOCUS;
|
||||
} else if (strcmp(argv[0], "fullscreen") == 0) {
|
||||
mode = INHIBIT_IDLE_FULLSCREEN;
|
||||
} else if (strcmp(argv[0], "open") == 0) {
|
||||
mode = INHIBIT_IDLE_OPEN;
|
||||
} else if (strcmp(argv[0], "none") == 0) {
|
||||
clear = true;
|
||||
} else if (strcmp(argv[0], "visible") == 0) {
|
||||
mode = INHIBIT_IDLE_VISIBLE;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Expected `inhibit_idle focus|fullscreen|open|none|visible`");
|
||||
}
|
||||
|
||||
struct sway_idle_inhibitor_v1 *inhibitor =
|
||||
sway_idle_inhibit_v1_user_inhibitor_for_view(con->view);
|
||||
if (inhibitor) {
|
||||
if (clear) {
|
||||
sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor);
|
||||
} else {
|
||||
inhibitor->mode = mode;
|
||||
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
||||
}
|
||||
} else if (!clear) {
|
||||
sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
@ -13,7 +13,8 @@
|
|||
static struct cmd_handler mode_handlers[] = {
|
||||
{ "bindcode", cmd_bindcode },
|
||||
{ "bindswitch", cmd_bindswitch },
|
||||
{ "bindsym", cmd_bindsym }
|
||||
{ "bindsym", cmd_bindsym },
|
||||
{ "set", cmd_set },
|
||||
};
|
||||
|
||||
struct cmd_results *cmd_mode(int argc, char **argv) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static struct cmd_handler output_handlers[] = {
|
|||
{ "res", output_cmd_mode },
|
||||
{ "resolution", output_cmd_mode },
|
||||
{ "scale", output_cmd_scale },
|
||||
{ "subpixel", output_cmd_subpixel },
|
||||
{ "transform", output_cmd_transform },
|
||||
};
|
||||
|
||||
|
|
|
|||
36
sway/commands/output/subpixel.c
Normal file
36
sway/commands/output/subpixel.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <string.h>
|
||||
#include "log.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/output.h"
|
||||
|
||||
struct cmd_results *output_cmd_subpixel(int argc, char **argv) {
|
||||
if (!config->handler_context.output_config) {
|
||||
return cmd_results_new(CMD_FAILURE, "Missing output config");
|
||||
}
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "Missing subpixel argument.");
|
||||
}
|
||||
enum wl_output_subpixel subpixel;
|
||||
|
||||
if (strcmp(*argv, "rgb") == 0) {
|
||||
subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
|
||||
} else if (strcmp(*argv, "bgr") == 0) {
|
||||
subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
|
||||
} else if (strcmp(*argv, "vrgb") == 0) {
|
||||
subpixel = WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
|
||||
} else if (strcmp(*argv, "vbgr") == 0) {
|
||||
subpixel = WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
|
||||
} else if (strcmp(*argv, "none") == 0) {
|
||||
subpixel = WL_OUTPUT_SUBPIXEL_NONE;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "Invalid output subpixel.");
|
||||
}
|
||||
|
||||
struct output_config *oc = config->handler_context.output_config;
|
||||
config->handler_context.leftovers.argc = argc - 1;
|
||||
config->handler_context.leftovers.argv = argv + 1;
|
||||
|
||||
oc->subpixel = subpixel;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include "sway/output.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "sway/tree/root.h"
|
||||
|
||||
static const char expected_syntax[] =
|
||||
"Expected 'rename workspace <old_name> to <new_name>' or "
|
||||
|
|
@ -89,6 +90,9 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
|||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
|
||||
|
||||
root_rename_pid_workspaces(workspace->name, new_name);
|
||||
|
||||
free(workspace->name);
|
||||
workspace->name = new_name;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
#include <unistd.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include "log.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
int output_name_cmp(const void *item, const void *data) {
|
||||
const struct output_config *output = item;
|
||||
|
|
@ -43,6 +44,7 @@ struct output_config *new_output_config(const char *name) {
|
|||
oc->x = oc->y = -1;
|
||||
oc->scale = -1;
|
||||
oc->transform = -1;
|
||||
oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
|
||||
return oc;
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +67,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
|
|||
if (src->scale != -1) {
|
||||
dst->scale = src->scale;
|
||||
}
|
||||
if (src->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN) {
|
||||
dst->subpixel = src->subpixel;
|
||||
}
|
||||
if (src->refresh_rate != -1) {
|
||||
dst->refresh_rate = src->refresh_rate;
|
||||
}
|
||||
|
|
@ -187,10 +192,10 @@ struct output_config *store_output_config(struct output_config *oc) {
|
|||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
||||
"position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)",
|
||||
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (dpms %d)",
|
||||
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
|
||||
oc->x, oc->y, oc->scale, oc->transform, oc->background,
|
||||
oc->background_option, oc->dpms_state);
|
||||
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
|
||||
oc->transform, oc->background, oc->background_option, oc->dpms_state);
|
||||
|
||||
return oc;
|
||||
}
|
||||
|
|
@ -363,6 +368,14 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
|||
sway_log(SWAY_DEBUG, "Set %s scale to %f", oc->name, oc->scale);
|
||||
wlr_output_set_scale(wlr_output, oc->scale);
|
||||
}
|
||||
|
||||
if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) {
|
||||
sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name,
|
||||
sway_wl_output_subpixel_to_string(oc->subpixel));
|
||||
wlr_output_set_subpixel(wlr_output, oc->subpixel);
|
||||
output_damage_whole(output);
|
||||
}
|
||||
|
||||
if (oc && oc->transform >= 0) {
|
||||
sway_log(SWAY_DEBUG, "Set %s transform to %d", oc->name, oc->transform);
|
||||
wlr_output_set_transform(wlr_output, oc->transform);
|
||||
|
|
@ -424,6 +437,8 @@ static void default_output_config(struct output_config *oc,
|
|||
}
|
||||
oc->x = oc->y = -1;
|
||||
oc->scale = 1;
|
||||
struct sway_output *output = wlr_output->data;
|
||||
oc->subpixel = output->detected_subpixel;
|
||||
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
oc->dpms_state = DPMS_ON;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
#include "config.h"
|
||||
|
||||
bool criteria_is_empty(struct criteria *criteria) {
|
||||
return !criteria->title
|
||||
return !criteria->autofail
|
||||
&& !criteria->title
|
||||
&& !criteria->shell
|
||||
&& !criteria->app_id
|
||||
&& !criteria->con_mark
|
||||
|
|
@ -98,6 +99,10 @@ static void find_urgent_iterator(struct sway_container *con, void *data) {
|
|||
|
||||
static bool criteria_matches_view(struct criteria *criteria,
|
||||
struct sway_view *view) {
|
||||
if (criteria->autofail) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (criteria->title) {
|
||||
const char *title = view_get_title(view);
|
||||
if (!title || regex_cmp(title, criteria->title) != 0) {
|
||||
|
|
@ -366,50 +371,66 @@ static enum criteria_token token_from_name(char *name) {
|
|||
* using criteria via IPC. Using __focused__ in config is not useful because
|
||||
* criteria is only executed once per view.
|
||||
*/
|
||||
static char *get_focused_prop(enum criteria_token token) {
|
||||
static char *get_focused_prop(enum criteria_token token, bool *autofail) {
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
struct sway_container *focus = seat_get_focused_container(seat);
|
||||
|
||||
if (!focus || !focus->view) {
|
||||
return NULL;
|
||||
}
|
||||
struct sway_view *view = focus->view;
|
||||
struct sway_view *view = focus ? focus->view : NULL;
|
||||
const char *value = NULL;
|
||||
|
||||
switch (token) {
|
||||
case T_APP_ID:
|
||||
value = view_get_app_id(view);
|
||||
*autofail = true;
|
||||
if (view) {
|
||||
value = view_get_app_id(view);
|
||||
}
|
||||
break;
|
||||
case T_SHELL:
|
||||
value = view_get_shell(view);
|
||||
*autofail = true;
|
||||
if (view) {
|
||||
value = view_get_shell(view);
|
||||
}
|
||||
break;
|
||||
case T_TITLE:
|
||||
value = view_get_title(view);
|
||||
*autofail = true;
|
||||
if (view) {
|
||||
value = view_get_title(view);
|
||||
}
|
||||
break;
|
||||
case T_WORKSPACE:
|
||||
if (focus->workspace) {
|
||||
*autofail = true;
|
||||
if (focus && focus->workspace) {
|
||||
value = focus->workspace->name;
|
||||
}
|
||||
break;
|
||||
case T_CON_ID:
|
||||
if (view->container == NULL) {
|
||||
return NULL;
|
||||
*autofail = true;
|
||||
if (view && view->container) {
|
||||
size_t id = view->container->node.id;
|
||||
size_t id_size = snprintf(NULL, 0, "%zu", id) + 1;
|
||||
char *id_str = malloc(id_size);
|
||||
snprintf(id_str, id_size, "%zu", id);
|
||||
value = id_str;
|
||||
}
|
||||
size_t id = view->container->node.id;
|
||||
size_t id_size = snprintf(NULL, 0, "%zu", id) + 1;
|
||||
char *id_str = malloc(id_size);
|
||||
snprintf(id_str, id_size, "%zu", id);
|
||||
value = id_str;
|
||||
break;
|
||||
#if HAVE_XWAYLAND
|
||||
case T_CLASS:
|
||||
value = view_get_class(view);
|
||||
*autofail = true;
|
||||
if (view) {
|
||||
value = view_get_class(view);
|
||||
}
|
||||
break;
|
||||
case T_INSTANCE:
|
||||
value = view_get_instance(view);
|
||||
*autofail = true;
|
||||
if (view) {
|
||||
value = view_get_instance(view);
|
||||
}
|
||||
break;
|
||||
case T_WINDOW_ROLE:
|
||||
value = view_get_window_role(view);
|
||||
*autofail = true;
|
||||
if (view) {
|
||||
value = view_get_window_role(view);
|
||||
}
|
||||
break;
|
||||
case T_WINDOW_TYPE: // These do not support __focused__
|
||||
case T_ID:
|
||||
|
|
@ -419,6 +440,7 @@ static char *get_focused_prop(enum criteria_token token) {
|
|||
case T_TILING:
|
||||
case T_URGENT:
|
||||
case T_INVALID:
|
||||
*autofail = false;
|
||||
break;
|
||||
}
|
||||
if (value) {
|
||||
|
|
@ -439,7 +461,12 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
|||
|
||||
char *effective_value = NULL;
|
||||
if (value && strcmp(value, "__focused__") == 0) {
|
||||
effective_value = get_focused_prop(token);
|
||||
bool autofail = false;
|
||||
effective_value = get_focused_prop(token, &autofail);
|
||||
if (!effective_value && autofail) {
|
||||
criteria->autofail = true;
|
||||
return true;
|
||||
}
|
||||
} else if (value) {
|
||||
effective_value = strdup(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,24 @@
|
|||
#include <wlr/types/wlr_idle.h>
|
||||
#include "log.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/server.h"
|
||||
|
||||
|
||||
static void destroy_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||
wl_list_remove(&inhibitor->link);
|
||||
wl_list_remove(&inhibitor->destroy.link);
|
||||
sway_idle_inhibit_v1_check_active(inhibitor->manager);
|
||||
free(inhibitor);
|
||||
}
|
||||
|
||||
static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_idle_inhibitor_v1 *inhibitor =
|
||||
wl_container_of(listener, inhibitor, destroy);
|
||||
sway_log(SWAY_DEBUG, "Sway idle inhibitor destroyed");
|
||||
wl_list_remove(&inhibitor->link);
|
||||
wl_list_remove(&inhibitor->destroy.link);
|
||||
idle_inhibit_v1_check_active(inhibitor->manager);
|
||||
free(inhibitor);
|
||||
destroy_inhibitor(inhibitor);
|
||||
}
|
||||
|
||||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -29,28 +35,93 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
inhibitor->manager = manager;
|
||||
inhibitor->mode = INHIBIT_IDLE_APPLICATION;
|
||||
inhibitor->view = view_from_wlr_surface(wlr_inhibitor->surface);
|
||||
wl_list_insert(&manager->inhibitors, &inhibitor->link);
|
||||
|
||||
|
||||
inhibitor->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy);
|
||||
|
||||
idle_inhibit_v1_check_active(manager);
|
||||
sway_idle_inhibit_v1_check_active(manager);
|
||||
}
|
||||
|
||||
void idle_inhibit_v1_check_active(
|
||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||
enum sway_idle_inhibit_mode mode) {
|
||||
struct sway_idle_inhibitor_v1 *inhibitor =
|
||||
calloc(1, sizeof(struct sway_idle_inhibitor_v1));
|
||||
if (!inhibitor) {
|
||||
return;
|
||||
}
|
||||
|
||||
inhibitor->manager = server.idle_inhibit_manager_v1;
|
||||
inhibitor->mode = mode;
|
||||
inhibitor->view = view;
|
||||
wl_list_insert(&inhibitor->manager->inhibitors, &inhibitor->link);
|
||||
|
||||
inhibitor->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&view->events.unmap, &inhibitor->destroy);
|
||||
|
||||
sway_idle_inhibit_v1_check_active(inhibitor->manager);
|
||||
}
|
||||
|
||||
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
||||
struct sway_view *view) {
|
||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||
wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors,
|
||||
link) {
|
||||
if (inhibitor->view == view &&
|
||||
inhibitor->mode != INHIBIT_IDLE_APPLICATION) {
|
||||
return inhibitor;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sway_idle_inhibit_v1_user_inhibitor_destroy(
|
||||
struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||
if (!inhibitor) {
|
||||
return;
|
||||
}
|
||||
if (!sway_assert(inhibitor->mode != INHIBIT_IDLE_APPLICATION,
|
||||
"User should not be able to destroy application inhibitor")) {
|
||||
return;
|
||||
}
|
||||
destroy_inhibitor(inhibitor);
|
||||
}
|
||||
|
||||
static bool check_active(struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||
switch (inhibitor->mode) {
|
||||
case INHIBIT_IDLE_APPLICATION:
|
||||
// If there is no view associated with the inhibitor, assume visible
|
||||
return !inhibitor->view || view_is_visible(inhibitor->view);
|
||||
case INHIBIT_IDLE_FOCUS:;
|
||||
struct sway_seat *seat = NULL;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
struct sway_container *con = seat_get_focused_container(seat);
|
||||
if (con && con->view && con->view == inhibitor->view) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case INHIBIT_IDLE_FULLSCREEN:
|
||||
return inhibitor->view->container &&
|
||||
container_is_fullscreen_or_child(inhibitor->view->container) &&
|
||||
view_is_visible(inhibitor->view);
|
||||
case INHIBIT_IDLE_OPEN:
|
||||
// Inhibitor is destroyed on unmap so it must be open/mapped
|
||||
return true;
|
||||
case INHIBIT_IDLE_VISIBLE:
|
||||
return view_is_visible(inhibitor->view);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sway_idle_inhibit_v1_check_active(
|
||||
struct sway_idle_inhibit_manager_v1 *manager) {
|
||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||
bool inhibited = false;
|
||||
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||
if (!inhibitor->view || !inhibitor->view->container) {
|
||||
/* Cannot guess if view is visible so assume it is */
|
||||
inhibited = true;
|
||||
break;
|
||||
}
|
||||
if (view_is_visible(inhibitor->view)) {
|
||||
inhibited = true;
|
||||
if ((inhibited = check_active(inhibitor))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ static void transaction_progress_queue(void) {
|
|||
list_del(server.transactions, 0);
|
||||
|
||||
if (!server.transactions->length) {
|
||||
idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
||||
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
|
|||
// Respect minimum and maximum sizes
|
||||
view->natural_width = ev->width;
|
||||
view->natural_height = ev->height;
|
||||
container_init_floating(view->container);
|
||||
container_floating_resize_and_center(view->container);
|
||||
|
||||
configure(view, view->container->content_x,
|
||||
view->container->content_y,
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|||
}
|
||||
|
||||
if (node->type == N_WORKSPACE) {
|
||||
// Emtpy workspace
|
||||
// Empty workspace
|
||||
e->target_node = node;
|
||||
e->target_edge = WLR_EDGE_NONE;
|
||||
workspace_get_box(node->sway_workspace, &e->drop_box);
|
||||
|
|
@ -164,7 +164,7 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
|||
|
||||
// Use the hovered view - but we must be over the actual surface
|
||||
con = node->sway_container;
|
||||
if (!con->view->surface || node == &e->con->node
|
||||
if (!con->view || !con->view->surface || node == &e->con->node
|
||||
|| node_has_ancestor(node, &e->con->node)) {
|
||||
e->target_node = NULL;
|
||||
e->target_edge = WLR_EDGE_NONE;
|
||||
|
|
|
|||
|
|
@ -644,6 +644,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
|||
json_object_object_add(output_json, "focused",
|
||||
json_object_new_boolean(focused));
|
||||
|
||||
const char *subpixel = sway_wl_output_subpixel_to_string(output->wlr_output->subpixel);
|
||||
json_object_object_add(output_json, "subpixel_hinting", json_object_new_string(subpixel));
|
||||
json_object_array_add(outputs, output_json);
|
||||
}
|
||||
struct sway_output *output;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ sway_sources = files(
|
|||
'commands/fullscreen.c',
|
||||
'commands/gaps.c',
|
||||
'commands/hide_edge_borders.c',
|
||||
'commands/inhibit_idle.c',
|
||||
'commands/kill.c',
|
||||
'commands/mark.c',
|
||||
'commands/opacity.c',
|
||||
|
|
@ -169,6 +170,7 @@ sway_sources = files(
|
|||
'commands/output/mode.c',
|
||||
'commands/output/position.c',
|
||||
'commands/output/scale.c',
|
||||
'commands/output/subpixel.c',
|
||||
'commands/output/transform.c',
|
||||
|
||||
'tree/arrange.c',
|
||||
|
|
|
|||
|
|
@ -211,6 +211,9 @@ following properties:
|
|||
|- scale
|
||||
: float
|
||||
: The scale currently in use on the output or _-1_ for disabled outputs
|
||||
|- subpixel_hinting
|
||||
: string
|
||||
: The subpixel hinting current in use on the output. This can be _rgb_, _bgr_, _vrgb_, _vbgr_, or _none_
|
||||
|- transform
|
||||
: string
|
||||
: The transform currently in use for the output. This can be _normal_, _90_,
|
||||
|
|
@ -242,6 +245,7 @@ following properties:
|
|||
"active": true,
|
||||
"primary": false,
|
||||
"scale": 1.0,
|
||||
"subpixel_hinting": "rgb",
|
||||
"transform": "normal",
|
||||
"current_workspace": "1",
|
||||
"modes": [
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ must be separated by one space. For example:
|
|||
applications to taste. HiDPI isn't supported with Xwayland clients (windows
|
||||
will blur).
|
||||
|
||||
*output* <name> subpixel rgb|bgr|vrgb|vbgr|none
|
||||
Manually sets the subpixel hinting for the specified output. This value is
|
||||
usually auto-detected, but some displays may misreport their subpixel
|
||||
geometry. Using the correct subpixel hinting allows for sharper text.
|
||||
Incorrect values will result in blurrier text. When changing this via
|
||||
*swaymsg*, some applications may need to be restarted to use the new value.
|
||||
|
||||
*output* <name> background|bg <file> <mode> [<fallback_color>]
|
||||
Sets the wallpaper for the given output to the specified file, using the
|
||||
given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). If
|
||||
|
|
|
|||
|
|
@ -146,6 +146,18 @@ set|plus|minus <amount>
|
|||
_right_, _bottom_, and _left_ or per direction with _horizontal_ and
|
||||
_vertical_.
|
||||
|
||||
*inhibit_idle* focus|fullscreen|open|none|visible
|
||||
Set/unset an idle inhibitor for the view. _focus_ will inhibit idle when
|
||||
the view is focused by any seat. _fullscreen_ will inhibit idle when the
|
||||
view is fullscreen (or a descendant of a fullscreen container) and is
|
||||
visible. _open_ will inhibit idle until the view is closed (or the
|
||||
inhibitor is unset/changed). _visible_ will inhibit idle when the view is
|
||||
visible on any output. _none_ will remove any existing idle inhibitor for
|
||||
the view.
|
||||
|
||||
This can also be used with criteria to set an idle inhibitor for any
|
||||
existing view or with _for_window_ to set idle inhibitors for future views.
|
||||
|
||||
*layout* default|splith|splitv|stacking|tabbed
|
||||
Sets the layout mode of the focused container.
|
||||
|
||||
|
|
@ -573,9 +585,9 @@ The default colors are:
|
|||
Switches to the specified mode. The default mode _default_.
|
||||
|
||||
*mode* [--pango_markup] <mode> <mode-subcommands...>
|
||||
The only valid _mode-subcommands..._ are *bindsym*, *bindcode* and
|
||||
*bindswitch*. If _--pango_markup_ is given, then _mode_ will be interpreted
|
||||
as pango markup.
|
||||
The only valid _mode-subcommands..._ are *bindsym*, *bindcode*,
|
||||
*bindswitch*, and *set*. If _--pango_markup_ is given, then _mode_ will be
|
||||
interpreted as pango markup.
|
||||
|
||||
*mouse_warping* output|container|none
|
||||
If _output_ is specified, the mouse will be moved to new outputs as you
|
||||
|
|
|
|||
|
|
@ -649,18 +649,45 @@ void floating_calculate_constraints(int *min_width, int *max_width,
|
|||
|
||||
}
|
||||
|
||||
void container_init_floating(struct sway_container *con) {
|
||||
struct sway_workspace *ws = con->workspace;
|
||||
static void floating_natural_resize(struct sway_container *con) {
|
||||
int min_width, max_width, min_height, max_height;
|
||||
floating_calculate_constraints(&min_width, &max_width,
|
||||
&min_height, &max_height);
|
||||
|
||||
if (!con->view) {
|
||||
con->width = max_width;
|
||||
con->height = max_height;
|
||||
con->width = fmax(min_width, fmin(con->width, max_width));
|
||||
con->height = fmax(min_height, fmin(con->height, max_height));
|
||||
} else {
|
||||
struct sway_view *view = con->view;
|
||||
con->content_width =
|
||||
fmax(min_width, fmin(view->natural_width, max_width));
|
||||
con->content_height =
|
||||
fmax(min_height, fmin(view->natural_height, max_height));
|
||||
container_set_geometry_from_content(con);
|
||||
}
|
||||
}
|
||||
|
||||
void container_floating_resize_and_center(struct sway_container *con) {
|
||||
struct sway_workspace *ws = con->workspace;
|
||||
if (!ws) {
|
||||
// On scratchpad, just resize
|
||||
floating_natural_resize(con);
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout,
|
||||
ws->output->wlr_output);
|
||||
if (!ob) {
|
||||
// On NOOP output. Will be called again when moved to an output
|
||||
con->x = 0;
|
||||
con->y = 0;
|
||||
con->width = 0;
|
||||
con->height = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
floating_natural_resize(con);
|
||||
if (!con->view) {
|
||||
if (con->width > ws->width || con->height > ws->height) {
|
||||
struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout,
|
||||
ws->output->wlr_output);
|
||||
con->x = ob->x + (ob->width - con->width) / 2;
|
||||
con->y = ob->y + (ob->height - con->height) / 2;
|
||||
} else {
|
||||
|
|
@ -668,15 +695,8 @@ void container_init_floating(struct sway_container *con) {
|
|||
con->y = ws->y + (ws->height - con->height) / 2;
|
||||
}
|
||||
} else {
|
||||
struct sway_view *view = con->view;
|
||||
con->content_width =
|
||||
fmax(min_width, fmin(view->natural_width, max_width));
|
||||
con->content_height =
|
||||
fmax(min_height, fmin(view->natural_height, max_height));
|
||||
if (con->content_width > ws->width
|
||||
|| con->content_height > ws->height) {
|
||||
struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout,
|
||||
ws->output->wlr_output);
|
||||
con->content_x = ob->x + (ob->width - con->content_width) / 2;
|
||||
con->content_y = ob->y + (ob->height - con->content_height) / 2;
|
||||
} else {
|
||||
|
|
@ -692,6 +712,31 @@ void container_init_floating(struct sway_container *con) {
|
|||
}
|
||||
}
|
||||
|
||||
void container_floating_set_default_size(struct sway_container *con) {
|
||||
if (!sway_assert(con->workspace, "Expected a container on a workspace")) {
|
||||
return;
|
||||
}
|
||||
|
||||
int min_width, max_width, min_height, max_height;
|
||||
floating_calculate_constraints(&min_width, &max_width,
|
||||
&min_height, &max_height);
|
||||
struct wlr_box *box = calloc(1, sizeof(struct wlr_box));
|
||||
workspace_get_box(con->workspace, box);
|
||||
|
||||
double width = fmax(min_width, fmin(box->width * 0.5, max_width));
|
||||
double height = fmax(min_height, fmin(box->height * 0.75, max_height));
|
||||
if (!con->view) {
|
||||
con->width = width;
|
||||
con->height = height;
|
||||
} else {
|
||||
con->content_width = width;
|
||||
con->content_height = height;
|
||||
container_set_geometry_from_content(con);
|
||||
}
|
||||
|
||||
free(box);
|
||||
}
|
||||
|
||||
void container_set_floating(struct sway_container *container, bool enable) {
|
||||
if (container_is_floating(container) == enable) {
|
||||
return;
|
||||
|
|
@ -704,7 +749,8 @@ void container_set_floating(struct sway_container *container, bool enable) {
|
|||
struct sway_container *old_parent = container->parent;
|
||||
container_detach(container);
|
||||
workspace_add_floating(workspace, container);
|
||||
container_init_floating(container);
|
||||
container_floating_set_default_size(container);
|
||||
container_floating_resize_and_center(container);
|
||||
if (container->view) {
|
||||
view_set_tiled(container->view, false);
|
||||
if (container->view->using_csd) {
|
||||
|
|
@ -988,7 +1034,7 @@ void container_fullscreen_disable(struct sway_container *con) {
|
|||
// criteria, it needs to be reinitialized as floating to get the proper
|
||||
// size and location
|
||||
if (container_is_floating(con) && (con->width == 0 || con->height == 0)) {
|
||||
container_init_floating(con);
|
||||
container_floating_resize_and_center(con);
|
||||
}
|
||||
|
||||
con->fullscreen_mode = FULLSCREEN_NONE;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,27 @@ static void restore_workspaces(struct sway_output *output) {
|
|||
struct sway_workspace *ws = root->noop_output->workspaces->items[0];
|
||||
workspace_detach(ws);
|
||||
output_add_workspace(output, ws);
|
||||
|
||||
// If the floater was made floating while on the NOOP output, its width
|
||||
// and height will be zero and it should be reinitialized as a floating
|
||||
// container to get the appropriate size and location. Additionally, if
|
||||
// the floater is wider or taller than the output or is completely
|
||||
// outside of the output's bounds, do the same as the output layout has
|
||||
// likely changed and the maximum size needs to be checked and the
|
||||
// floater re-centered
|
||||
for (int i = 0; i < ws->floating->length; i++) {
|
||||
struct sway_container *floater = ws->floating->items[i];
|
||||
if (floater->width == 0 || floater->height == 0 ||
|
||||
floater->width > output->width ||
|
||||
floater->height > output->height ||
|
||||
floater->x > output->lx + output->width ||
|
||||
floater->y > output->ly + output->height ||
|
||||
floater->x + floater->width < output->lx ||
|
||||
floater->y + floater->height < output->ly) {
|
||||
container_floating_resize_and_center(floater);
|
||||
}
|
||||
}
|
||||
|
||||
ipc_event_workspace(NULL, ws, "move");
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +92,7 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
|
|||
node_init(&output->node, N_OUTPUT, output);
|
||||
output->wlr_output = wlr_output;
|
||||
wlr_output->data = output;
|
||||
output->detected_subpixel = wlr_output->subpixel;
|
||||
|
||||
wl_signal_init(&output->events.destroy);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ void root_scratchpad_add_container(struct sway_container *con) {
|
|||
struct sway_container *parent = con->parent;
|
||||
struct sway_workspace *workspace = con->workspace;
|
||||
container_set_floating(con, true);
|
||||
container_floating_set_default_size(con);
|
||||
container_floating_move_to_center(con);
|
||||
container_detach(con);
|
||||
con->scratchpad = true;
|
||||
list_add(root->scratchpad, con);
|
||||
|
|
@ -124,15 +126,7 @@ void root_scratchpad_show(struct sway_container *con) {
|
|||
struct wlr_box workspace_box;
|
||||
workspace_get_box(new_ws, &workspace_box);
|
||||
if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) {
|
||||
// Maybe resize it
|
||||
if (con->width > new_ws->width || con->height > new_ws->height) {
|
||||
container_init_floating(con);
|
||||
}
|
||||
|
||||
// Center it
|
||||
double new_lx = new_ws->x + (new_ws->width - con->width) / 2;
|
||||
double new_ly = new_ws->y + (new_ws->height - con->height) / 2;
|
||||
container_floating_move_to(con, new_lx, new_ly);
|
||||
container_floating_resize_and_center(con);
|
||||
}
|
||||
|
||||
arrange_workspace(new_ws);
|
||||
|
|
@ -390,3 +384,17 @@ void root_get_box(struct sway_root *root, struct wlr_box *box) {
|
|||
box->width = root->width;
|
||||
box->height = root->height;
|
||||
}
|
||||
|
||||
void root_rename_pid_workspaces(const char *old_name, const char *new_name) {
|
||||
if (!pid_workspaces.prev && !pid_workspaces.next) {
|
||||
wl_list_init(&pid_workspaces);
|
||||
}
|
||||
|
||||
struct pid_workspace *pw = NULL;
|
||||
wl_list_for_each(pw, &pid_workspaces, link) {
|
||||
if (strcmp(pw->workspace, old_name) == 0) {
|
||||
free(pw->workspace);
|
||||
pw->workspace = strdup(new_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,9 @@ void init_themes(list_t **themes, list_t **basedirs) {
|
|||
*themes = create_list();
|
||||
for (int i = 0; i < (*basedirs)->length; ++i) {
|
||||
list_t *dir_themes = load_themes_in_dir((*basedirs)->items[i]);
|
||||
if (dir_themes == NULL) {
|
||||
continue;
|
||||
}
|
||||
list_cat(*themes, dir_themes);
|
||||
list_free(dir_themes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,11 +186,12 @@ static void pretty_print_output(json_object *o) {
|
|||
json_object_object_get_ex(o, "focused", &focused);
|
||||
json_object_object_get_ex(o, "active", &active);
|
||||
json_object_object_get_ex(o, "current_workspace", &ws);
|
||||
json_object *make, *model, *serial, *scale, *transform;
|
||||
json_object *make, *model, *serial, *scale, *subpixel, *transform;
|
||||
json_object_object_get_ex(o, "make", &make);
|
||||
json_object_object_get_ex(o, "model", &model);
|
||||
json_object_object_get_ex(o, "serial", &serial);
|
||||
json_object_object_get_ex(o, "scale", &scale);
|
||||
json_object_object_get_ex(o, "subpixel_hinting", &subpixel);
|
||||
json_object_object_get_ex(o, "transform", &transform);
|
||||
json_object *x, *y;
|
||||
json_object_object_get_ex(rect, "x", &x);
|
||||
|
|
@ -209,6 +210,7 @@ static void pretty_print_output(json_object *o) {
|
|||
" Current mode: %dx%d @ %f Hz\n"
|
||||
" Position: %d,%d\n"
|
||||
" Scale factor: %f\n"
|
||||
" Subpixel hinting: %s\n"
|
||||
" Transform: %s\n"
|
||||
" Workspace: %s\n",
|
||||
json_object_get_string(name),
|
||||
|
|
@ -221,6 +223,7 @@ static void pretty_print_output(json_object *o) {
|
|||
(float)json_object_get_int(refresh) / 1000,
|
||||
json_object_get_int(x), json_object_get_int(y),
|
||||
json_object_get_double(scale),
|
||||
json_object_get_string(subpixel),
|
||||
json_object_get_string(transform),
|
||||
json_object_get_string(ws)
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue