mirror of
https://github.com/swaywm/sway.git
synced 2026-04-17 06:46:32 -04:00
Merge branch 'master' into inhibit_floating_modifier
This commit is contained in:
commit
926920096f
29 changed files with 320 additions and 76 deletions
17
config.in
17
config.in
|
|
@ -16,9 +16,7 @@ set $right l
|
||||||
# Your preferred terminal emulator
|
# Your preferred terminal emulator
|
||||||
set $term foot
|
set $term foot
|
||||||
# Your preferred application launcher
|
# Your preferred application launcher
|
||||||
# Note: pass the final command to swaymsg so that the resulting window can be opened
|
set $menu wmenu-run
|
||||||
# on the original workspace that the command was run on.
|
|
||||||
set $menu dmenu_path | wmenu | xargs swaymsg exec --
|
|
||||||
|
|
||||||
### Output configuration
|
### Output configuration
|
||||||
#
|
#
|
||||||
|
|
@ -195,6 +193,19 @@ mode "resize" {
|
||||||
bindsym Escape mode "default"
|
bindsym Escape mode "default"
|
||||||
}
|
}
|
||||||
bindsym $mod+r mode "resize"
|
bindsym $mod+r mode "resize"
|
||||||
|
#
|
||||||
|
# Utilities:
|
||||||
|
#
|
||||||
|
# Special keys to adjust volume via PulseAudio
|
||||||
|
bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
|
||||||
|
bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
|
||||||
|
bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
|
||||||
|
bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
|
||||||
|
# Special keys to adjust brightness via brightnessctl
|
||||||
|
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
|
||||||
|
bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
|
||||||
|
# Special key to take a screenshot with grim
|
||||||
|
bindsym Print exec grim
|
||||||
|
|
||||||
#
|
#
|
||||||
# Status Bar:
|
# Status Bar:
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ struct sway_container *container_find_resize_parent(struct sway_container *con,
|
||||||
sway_cmd cmd_exec_validate;
|
sway_cmd cmd_exec_validate;
|
||||||
sway_cmd cmd_exec_process;
|
sway_cmd cmd_exec_process;
|
||||||
|
|
||||||
|
sway_cmd cmd_allow_tearing;
|
||||||
sway_cmd cmd_assign;
|
sway_cmd cmd_assign;
|
||||||
sway_cmd cmd_bar;
|
sway_cmd cmd_bar;
|
||||||
sway_cmd cmd_bindcode;
|
sway_cmd cmd_bindcode;
|
||||||
|
|
@ -283,6 +284,7 @@ sway_cmd input_cmd_xkb_switch_layout;
|
||||||
sway_cmd input_cmd_xkb_variant;
|
sway_cmd input_cmd_xkb_variant;
|
||||||
|
|
||||||
sway_cmd output_cmd_adaptive_sync;
|
sway_cmd output_cmd_adaptive_sync;
|
||||||
|
sway_cmd output_cmd_allow_tearing;
|
||||||
sway_cmd output_cmd_background;
|
sway_cmd output_cmd_background;
|
||||||
sway_cmd output_cmd_color_profile;
|
sway_cmd output_cmd_color_profile;
|
||||||
sway_cmd output_cmd_disable;
|
sway_cmd output_cmd_disable;
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,7 @@ struct output_config {
|
||||||
enum render_bit_depth render_bit_depth;
|
enum render_bit_depth render_bit_depth;
|
||||||
bool set_color_transform;
|
bool set_color_transform;
|
||||||
struct wlr_color_transform *color_transform;
|
struct wlr_color_transform *color_transform;
|
||||||
|
int allow_tearing;
|
||||||
|
|
||||||
char *background;
|
char *background;
|
||||||
char *background_option;
|
char *background_option;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ struct sway_output {
|
||||||
uint32_t refresh_nsec;
|
uint32_t refresh_nsec;
|
||||||
int max_render_time; // In milliseconds
|
int max_render_time; // In milliseconds
|
||||||
struct wl_event_source *repaint_timer;
|
struct wl_event_source *repaint_timer;
|
||||||
bool gamma_lut_changed;
|
bool allow_tearing;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_output_non_desktop {
|
struct sway_output_non_desktop {
|
||||||
|
|
@ -137,8 +137,6 @@ enum wlr_direction opposite_direction(enum wlr_direction d);
|
||||||
|
|
||||||
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data);
|
|
||||||
|
|
||||||
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ struct sway_server {
|
||||||
struct wl_listener xdg_activation_v1_new_token;
|
struct wl_listener xdg_activation_v1_new_token;
|
||||||
|
|
||||||
struct wl_listener request_set_cursor_shape;
|
struct wl_listener request_set_cursor_shape;
|
||||||
|
|
||||||
|
struct wlr_tearing_control_manager_v1 *tearing_control_v1;
|
||||||
|
struct wl_listener tearing_control_new_object;
|
||||||
|
struct wl_list tearing_controllers; // sway_tearing_controller::link
|
||||||
|
|
||||||
struct wl_list pending_launcher_ctxs; // launcher_ctx::link
|
struct wl_list pending_launcher_ctxs; // launcher_ctx::link
|
||||||
|
|
||||||
|
|
@ -182,4 +186,6 @@ void xdg_activation_v1_handle_new_token(struct wl_listener *listener,
|
||||||
|
|
||||||
void set_rr_scheduling(void);
|
void set_rr_scheduling(void);
|
||||||
|
|
||||||
|
void handle_new_tearing_hint(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <wlr/config.h>
|
#include <wlr/config.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
#include <wlr/types/wlr_tearing_control_v1.h>
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#if WLR_HAS_XWAYLAND
|
#if WLR_HAS_XWAYLAND
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland.h>
|
||||||
|
|
@ -34,6 +35,12 @@ enum sway_view_prop {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum sway_view_tearing_mode {
|
||||||
|
TEARING_OVERRIDE_FALSE,
|
||||||
|
TEARING_OVERRIDE_TRUE,
|
||||||
|
TEARING_WINDOW_HINT,
|
||||||
|
};
|
||||||
|
|
||||||
struct sway_view_impl {
|
struct sway_view_impl {
|
||||||
void (*get_constraints)(struct sway_view *view, double *min_width,
|
void (*get_constraints)(struct sway_view *view, double *min_width,
|
||||||
double *max_width, double *min_height, double *max_height);
|
double *max_width, double *min_height, double *max_height);
|
||||||
|
|
@ -111,6 +118,9 @@ struct sway_view {
|
||||||
int max_render_time; // In milliseconds
|
int max_render_time; // In milliseconds
|
||||||
|
|
||||||
enum seat_config_shortcuts_inhibit shortcuts_inhibit;
|
enum seat_config_shortcuts_inhibit shortcuts_inhibit;
|
||||||
|
|
||||||
|
enum sway_view_tearing_mode tearing_mode;
|
||||||
|
enum wp_tearing_control_v1_presentation_hint tearing_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_xdg_shell_view {
|
struct sway_xdg_shell_view {
|
||||||
|
|
@ -335,4 +345,6 @@ void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx);
|
||||||
|
|
||||||
void view_send_frame_done(struct sway_view *view);
|
void view_send_frame_done(struct sway_view *view);
|
||||||
|
|
||||||
|
bool view_can_tear(struct sway_view *view);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -160,8 +160,8 @@ add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir
|
||||||
version = '"@0@"'.format(meson.project_version())
|
version = '"@0@"'.format(meson.project_version())
|
||||||
git = find_program('git', native: true, required: false)
|
git = find_program('git', native: true, required: false)
|
||||||
if git.found()
|
if git.found()
|
||||||
git_commit = run_command([git, 'rev-parse', '--short', 'HEAD'], check: false)
|
git_commit = run_command([git, '--git-dir=.git', 'rev-parse', '--short', 'HEAD'], check: false)
|
||||||
git_branch = run_command([git, 'rev-parse', '--abbrev-ref', 'HEAD'], check: false)
|
git_branch = run_command([git, '--git-dir=.git', 'rev-parse', '--abbrev-ref', 'HEAD'], check: false)
|
||||||
if git_commit.returncode() == 0 and git_branch.returncode() == 0
|
if git_commit.returncode() == 0 and git_branch.returncode() == 0
|
||||||
version = '"@0@-@1@ (" __DATE__ ", branch \'@2@\')"'.format(
|
version = '"@0@-@1@ (" __DATE__ ", branch \'@2@\')"'.format(
|
||||||
meson.project_version(),
|
meson.project_version(),
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ protocols = [
|
||||||
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
||||||
wl_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
wl_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
||||||
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||||
|
wl_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
||||||
'wlr-layer-shell-unstable-v1.xml',
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
'idle.xml',
|
'idle.xml',
|
||||||
'wlr-output-power-management-unstable-v1.xml',
|
'wlr-output-power-management-unstable-v1.xml',
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ static const struct cmd_handler config_handlers[] = {
|
||||||
|
|
||||||
/* Runtime-only commands. Keep alphabetized */
|
/* Runtime-only commands. Keep alphabetized */
|
||||||
static const struct cmd_handler command_handlers[] = {
|
static const struct cmd_handler command_handlers[] = {
|
||||||
|
{ "allow_tearing", cmd_allow_tearing },
|
||||||
{ "border", cmd_border },
|
{ "border", cmd_border },
|
||||||
{ "create_output", cmd_create_output },
|
{ "create_output", cmd_create_output },
|
||||||
{ "exit", cmd_exit },
|
{ "exit", cmd_exit },
|
||||||
|
|
|
||||||
24
sway/commands/allow_tearing.c
Normal file
24
sway/commands/allow_tearing.c
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <sway/commands.h>
|
||||||
|
#include "sway/config.h"
|
||||||
|
#include "sway/tree/view.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *cmd_allow_tearing(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "allow_tearing", EXPECTED_AT_LEAST, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_container *container = config->handler_context.container;
|
||||||
|
if (!container || !container->view) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "Tearing can only be allowed on views");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wants_tearing = parse_boolean(argv[0], true);
|
||||||
|
|
||||||
|
struct sway_view *view = container->view;
|
||||||
|
view->tearing_mode = wants_tearing ? TEARING_OVERRIDE_TRUE :
|
||||||
|
TEARING_OVERRIDE_FALSE;
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
|
}
|
||||||
|
|
@ -95,10 +95,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_keyboard *keyboard =
|
||||||
|
wlr_keyboard_from_input_device(dev->wlr_device);
|
||||||
|
if (keyboard->keymap == NULL && dev->is_virtual) {
|
||||||
|
// The `sway_keyboard_set_layout` function is by default skipped
|
||||||
|
// when configuring virtual keyboards.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
struct xkb_switch_layout_action *action =
|
struct xkb_switch_layout_action *action =
|
||||||
&actions[actions_len++];
|
&actions[actions_len++];
|
||||||
|
action->keyboard = keyboard;
|
||||||
|
|
||||||
action->keyboard = wlr_keyboard_from_input_device(dev->wlr_device);
|
|
||||||
if (relative) {
|
if (relative) {
|
||||||
action->layout = get_layout_relative(action->keyboard, relative);
|
action->layout = get_layout_relative(action->keyboard, relative);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws = workspace_create(NULL, ws_name);
|
ws = workspace_create(NULL, ws_name);
|
||||||
|
arrange_workspace(ws);
|
||||||
}
|
}
|
||||||
free(ws_name);
|
free(ws_name);
|
||||||
struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws);
|
struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
// must be in order for the bsearch
|
// must be in order for the bsearch
|
||||||
static const struct cmd_handler output_handlers[] = {
|
static const struct cmd_handler output_handlers[] = {
|
||||||
{ "adaptive_sync", output_cmd_adaptive_sync },
|
{ "adaptive_sync", output_cmd_adaptive_sync },
|
||||||
|
{ "allow_tearing", output_cmd_allow_tearing },
|
||||||
{ "background", output_cmd_background },
|
{ "background", output_cmd_background },
|
||||||
{ "bg", output_cmd_background },
|
{ "bg", output_cmd_background },
|
||||||
{ "color_profile", output_cmd_color_profile },
|
{ "color_profile", output_cmd_color_profile },
|
||||||
|
|
|
||||||
23
sway/commands/output/allow_tearing.c
Normal file
23
sway/commands/output/allow_tearing.c
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/config.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *output_cmd_allow_tearing(int argc, char **argv) {
|
||||||
|
if (!config->handler_context.output_config) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "Missing output config");
|
||||||
|
}
|
||||||
|
if (argc == 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "Missing allow_tearing argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_boolean(argv[0],
|
||||||
|
(config->handler_context.output_config->allow_tearing == 1))) {
|
||||||
|
config->handler_context.output_config->allow_tearing = 1;
|
||||||
|
} else {
|
||||||
|
config->handler_context.output_config->allow_tearing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->handler_context.leftovers.argc = argc - 1;
|
||||||
|
config->handler_context.leftovers.argv = argv + 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <wlr/render/color.h>
|
#include <wlr/render/color.h>
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
static bool read_file_into_buf(const char *path, void **buf, size_t *size) {
|
static bool read_file_into_buf(const char *path, void **buf, size_t *size) {
|
||||||
/* Why not use fopen/fread directly? glibc will succesfully open directories,
|
/* Why not use fopen/fread directly? glibc will succesfully open directories,
|
||||||
|
|
@ -70,12 +71,23 @@ struct cmd_results *output_cmd_color_profile(int argc, char **argv) {
|
||||||
return cmd_results_new(CMD_INVALID,
|
return cmd_results_new(CMD_INVALID,
|
||||||
"Invalid color profile specification: icc type requires a file");
|
"Invalid color profile specification: icc type requires a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *icc_path = strdup(argv[1]);
|
||||||
|
if (!expand_path(&icc_path)) {
|
||||||
|
struct cmd_results *cmd_res = cmd_results_new(CMD_INVALID,
|
||||||
|
"Invalid color profile specification: invalid file path");
|
||||||
|
free(icc_path);
|
||||||
|
return cmd_res;
|
||||||
|
}
|
||||||
|
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
if (!read_file_into_buf(argv[1], &data, &size)) {
|
if (!read_file_into_buf(icc_path, &data, &size)) {
|
||||||
|
free(icc_path);
|
||||||
return cmd_results_new(CMD_FAILURE,
|
return cmd_results_new(CMD_FAILURE,
|
||||||
"Failed to load color profile: could not read ICC file");
|
"Failed to load color profile: could not read ICC file");
|
||||||
}
|
}
|
||||||
|
free(icc_path);
|
||||||
|
|
||||||
struct wlr_color_transform *tmp =
|
struct wlr_color_transform *tmp =
|
||||||
wlr_color_transform_init_linear_to_icc(data, size);
|
wlr_color_transform_init_linear_to_icc(data, size);
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ struct output_config *new_output_config(const char *name) {
|
||||||
oc->set_color_transform = false;
|
oc->set_color_transform = false;
|
||||||
oc->color_transform = NULL;
|
oc->color_transform = NULL;
|
||||||
oc->power = -1;
|
oc->power = -1;
|
||||||
|
oc->allow_tearing = -1;
|
||||||
return oc;
|
return oc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,6 +217,9 @@ static void merge_output_config(struct output_config *dst, struct output_config
|
||||||
if (src->power != -1) {
|
if (src->power != -1) {
|
||||||
dst->power = src->power;
|
dst->power = src->power;
|
||||||
}
|
}
|
||||||
|
if (src->allow_tearing != -1) {
|
||||||
|
dst->allow_tearing = src->allow_tearing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void store_output_config(struct output_config *oc) {
|
void store_output_config(struct output_config *oc) {
|
||||||
|
|
@ -258,11 +262,11 @@ void store_output_config(struct output_config *oc) {
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
||||||
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
|
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
|
||||||
"(max render time: %d)",
|
"(max render time: %d) (allow tearing: %d)",
|
||||||
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
|
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
|
||||||
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
|
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
|
||||||
oc->transform, oc->background, oc->background_option, oc->power,
|
oc->transform, oc->background, oc->background_option, oc->power,
|
||||||
oc->max_render_time);
|
oc->max_render_time, oc->allow_tearing);
|
||||||
|
|
||||||
// If the configuration was not merged into an existing configuration, add
|
// If the configuration was not merged into an existing configuration, add
|
||||||
// it to the list. Otherwise we're done with it and can free it.
|
// it to the list. Otherwise we're done with it and can free it.
|
||||||
|
|
@ -487,7 +491,7 @@ static void queue_output_config(struct output_config *oc,
|
||||||
wlr_output_state_set_scale(pending, scale);
|
wlr_output_state_set_scale(pending, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oc && oc->adaptive_sync != -1) {
|
if (oc && oc->adaptive_sync != -1 && wlr_output->adaptive_sync_supported) {
|
||||||
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
|
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
|
||||||
oc->adaptive_sync);
|
oc->adaptive_sync);
|
||||||
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
||||||
|
|
@ -574,6 +578,13 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
||||||
wlr_color_transform_unref(output->color_transform);
|
wlr_color_transform_unref(output->color_transform);
|
||||||
output->color_transform = oc->color_transform;
|
output->color_transform = oc->color_transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oc && oc->allow_tearing >= 0) {
|
||||||
|
sway_log(SWAY_DEBUG, "Set %s allow tearing to %d",
|
||||||
|
oc->name, oc->allow_tearing);
|
||||||
|
output->allow_tearing = oc->allow_tearing;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -594,6 +605,7 @@ static void default_output_config(struct output_config *oc,
|
||||||
oc->subpixel = output->detected_subpixel;
|
oc->subpixel = output->detected_subpixel;
|
||||||
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
oc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
oc->max_render_time = 0;
|
oc->max_render_time = 0;
|
||||||
|
oc->allow_tearing = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_output_config returns a merged output_config containing all stored
|
// find_output_config returns a merged output_config containing all stored
|
||||||
|
|
@ -639,9 +651,9 @@ struct output_config *find_output_config(struct sway_output *sway_output) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool config_has_auto_mode(struct output_config *oc) {
|
static bool config_has_manual_mode(struct output_config *oc) {
|
||||||
if (!oc) {
|
if (!oc) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
if (oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t)-1) {
|
if (oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t)-1) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -742,7 +754,8 @@ static bool search_mode(struct search_context *ctx, size_t output_idx) {
|
||||||
struct wlr_output_state *state = &backend_state->base;
|
struct wlr_output_state *state = &backend_state->base;
|
||||||
struct wlr_output *wlr_output = backend_state->output;
|
struct wlr_output *wlr_output = backend_state->output;
|
||||||
|
|
||||||
if (!config_has_auto_mode(cfg->config)) {
|
// We only search for mode if one is not explicitly specified in the config
|
||||||
|
if (config_has_manual_mode(cfg->config)) {
|
||||||
return search_adaptive_sync(ctx, output_idx);
|
return search_adaptive_sync(ctx, output_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,23 @@ static void output_configure_scene(struct sway_output *output,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool output_can_tear(struct sway_output *output) {
|
||||||
|
struct sway_workspace *workspace = output->current.active_workspace;
|
||||||
|
if (!workspace) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_container *fullscreen_con = root->fullscreen_global;
|
||||||
|
if (!fullscreen_con) {
|
||||||
|
fullscreen_con = workspace->current.fullscreen;
|
||||||
|
}
|
||||||
|
if (fullscreen_con && fullscreen_con->view) {
|
||||||
|
return (output->allow_tearing && view_can_tear(fullscreen_con->view));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int output_repaint_timer_handler(void *data) {
|
static int output_repaint_timer_handler(void *data) {
|
||||||
struct sway_output *output = data;
|
struct sway_output *output = data;
|
||||||
|
|
||||||
|
|
@ -247,10 +264,8 @@ static int output_repaint_timer_handler(void *data) {
|
||||||
.color_transform = output->color_transform,
|
.color_transform = output->color_transform,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
|
||||||
struct wlr_scene_output *scene_output = output->scene_output;
|
struct wlr_scene_output *scene_output = output->scene_output;
|
||||||
if (!wlr_output->needs_frame && !output->gamma_lut_changed &&
|
if (!wlr_scene_output_needs_frame(scene_output)) {
|
||||||
!pixman_region32_not_empty(&scene_output->pending_commit_damage)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -260,19 +275,13 @@ static int output_repaint_timer_handler(void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->gamma_lut_changed) {
|
if (output_can_tear(output)) {
|
||||||
output->gamma_lut_changed = false;
|
pending.tearing_page_flip = true;
|
||||||
struct wlr_gamma_control_v1 *gamma_control =
|
|
||||||
wlr_gamma_control_manager_v1_get_control(
|
|
||||||
server.gamma_control_manager_v1, output->wlr_output);
|
|
||||||
if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
|
|
||||||
wlr_output_state_finish(&pending);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wlr_output_test_state(output->wlr_output, &pending)) {
|
if (!wlr_output_test_state(output->wlr_output, &pending)) {
|
||||||
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
|
sway_log(SWAY_DEBUG, "Output test failed on '%s', retrying without tearing page-flip",
|
||||||
wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL);
|
output->wlr_output->name);
|
||||||
|
pending.tearing_page_flip = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -446,11 +455,6 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
update_output_manager_config(output->server);
|
update_output_manager_config(output->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next time the output is enabled, try to re-apply the gamma LUT
|
|
||||||
if ((event->state->committed & WLR_OUTPUT_STATE_ENABLED) && !output->wlr_output->enabled) {
|
|
||||||
output->gamma_lut_changed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_present(struct wl_listener *listener, void *data) {
|
static void handle_present(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -461,7 +465,7 @@ static void handle_present(struct wl_listener *listener, void *data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->last_presentation = *output_event->when;
|
output->last_presentation = output_event->when;
|
||||||
output->refresh_nsec = output_event->refresh;
|
output->refresh_nsec = output_event->refresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,21 +563,6 @@ void handle_output_layout_change(struct wl_listener *listener,
|
||||||
update_output_manager_config(server);
|
update_output_manager_config(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
|
|
||||||
struct sway_server *server =
|
|
||||||
wl_container_of(listener, server, gamma_control_set_gamma);
|
|
||||||
const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
|
|
||||||
|
|
||||||
struct sway_output *output = event->output->data;
|
|
||||||
|
|
||||||
if(!output) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
output->gamma_lut_changed = true;
|
|
||||||
wlr_output_schedule_frame(output->wlr_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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 sway_output *output) {
|
||||||
|
|
|
||||||
64
sway/desktop/tearing.c
Normal file
64
sway/desktop/tearing.c
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/types/wlr_tearing_control_v1.h>
|
||||||
|
#include "sway/server.h"
|
||||||
|
#include "sway/tree/view.h"
|
||||||
|
#include "sway/output.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
struct sway_tearing_controller {
|
||||||
|
struct wlr_tearing_control_v1 *tearing_control;
|
||||||
|
struct wl_listener set_hint;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
|
||||||
|
struct wl_list link; // sway_server::tearing_controllers
|
||||||
|
};
|
||||||
|
|
||||||
|
static void handle_tearing_controller_set_hint(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct sway_tearing_controller *controller =
|
||||||
|
wl_container_of(listener, controller, set_hint);
|
||||||
|
|
||||||
|
struct sway_view *view = view_from_wlr_surface(
|
||||||
|
controller->tearing_control->surface);
|
||||||
|
if (view) {
|
||||||
|
view->tearing_hint = controller->tearing_control->current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_tearing_controller_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct sway_tearing_controller *controller =
|
||||||
|
wl_container_of(listener, controller, destroy);
|
||||||
|
wl_list_remove(&controller->set_hint.link);
|
||||||
|
wl_list_remove(&controller->destroy.link);
|
||||||
|
wl_list_remove(&controller->link);
|
||||||
|
free(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_new_tearing_hint(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct sway_server *server =
|
||||||
|
wl_container_of(listener, server, tearing_control_new_object);
|
||||||
|
struct wlr_tearing_control_v1 *tearing_control = data;
|
||||||
|
|
||||||
|
enum wp_tearing_control_v1_presentation_hint hint =
|
||||||
|
wlr_tearing_control_manager_v1_surface_hint_from_surface(
|
||||||
|
server->tearing_control_v1, tearing_control->surface);
|
||||||
|
sway_log(SWAY_DEBUG, "New presentation hint %d received for surface %p",
|
||||||
|
hint, tearing_control->surface);
|
||||||
|
|
||||||
|
struct sway_tearing_controller *controller =
|
||||||
|
calloc(1, sizeof(struct sway_tearing_controller));
|
||||||
|
if (!controller) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controller->tearing_control = tearing_control;
|
||||||
|
controller->set_hint.notify = handle_tearing_controller_set_hint;
|
||||||
|
wl_signal_add(&tearing_control->events.set_hint, &controller->set_hint);
|
||||||
|
controller->destroy.notify = handle_tearing_controller_destroy;
|
||||||
|
wl_signal_add(&tearing_control->events.destroy, &controller->destroy);
|
||||||
|
wl_list_init(&controller->link);
|
||||||
|
|
||||||
|
wl_list_insert(&server->tearing_controllers, &controller->link);
|
||||||
|
}
|
||||||
|
|
@ -632,6 +632,15 @@ static void arrange_root(struct sway_root *root) {
|
||||||
for (int i = 0; i < root->scratchpad->length; i++) {
|
for (int i = 0; i < root->scratchpad->length; i++) {
|
||||||
struct sway_container *con = root->scratchpad->items[i];
|
struct sway_container *con = root->scratchpad->items[i];
|
||||||
|
|
||||||
|
// When a container is moved to a scratchpad, it's possible that it
|
||||||
|
// was moved into a floating container as part of the same transaction.
|
||||||
|
// In this case, we need to make sure we reparent all the container's
|
||||||
|
// children so that disabling the container will disable all descendants.
|
||||||
|
if (!con->view) for (int ii = 0; ii < con->current.children->length; ii++) {
|
||||||
|
struct sway_container *child = con->current.children->items[ii];
|
||||||
|
wlr_scene_node_reparent(&child->scene_tree->node, con->content_tree);
|
||||||
|
}
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&con->scene_tree->node, false);
|
wlr_scene_node_set_enabled(&con->scene_tree->node, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -299,18 +299,17 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_box new_geo;
|
struct wlr_box *new_geo = &xdg_surface->geometry;
|
||||||
wlr_xdg_surface_get_geometry(xdg_surface, &new_geo);
|
bool new_size = new_geo->width != view->geometry.width ||
|
||||||
bool new_size = new_geo.width != view->geometry.width ||
|
new_geo->height != view->geometry.height ||
|
||||||
new_geo.height != view->geometry.height ||
|
new_geo->x != view->geometry.x ||
|
||||||
new_geo.x != view->geometry.x ||
|
new_geo->y != view->geometry.y;
|
||||||
new_geo.y != view->geometry.y;
|
|
||||||
|
|
||||||
if (new_size) {
|
if (new_size) {
|
||||||
// The client changed its surface size in this commit. For floating
|
// The client changed its surface size in this commit. For floating
|
||||||
// containers, we resize the container to match. For tiling containers,
|
// containers, we resize the container to match. For tiling containers,
|
||||||
// we only recenter the surface.
|
// we only recenter the surface.
|
||||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
memcpy(&view->geometry, new_geo, sizeof(struct wlr_box));
|
||||||
if (container_is_floating(view->container)) {
|
if (container_is_floating(view->container)) {
|
||||||
view_update_size(view);
|
view_update_size(view);
|
||||||
// Only set the toplevel size the current container actually has a size.
|
// Only set the toplevel size the current container actually has a size.
|
||||||
|
|
@ -463,12 +462,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
struct sway_view *view = &xdg_shell_view->view;
|
struct sway_view *view = &xdg_shell_view->view;
|
||||||
struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_toplevel;
|
struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_toplevel;
|
||||||
|
|
||||||
view->natural_width = toplevel->base->current.geometry.width;
|
view->natural_width = toplevel->base->geometry.width;
|
||||||
view->natural_height = toplevel->base->current.geometry.height;
|
view->natural_height = toplevel->base->geometry.height;
|
||||||
if (!view->natural_width && !view->natural_height) {
|
|
||||||
view->natural_width = toplevel->base->surface->current.width;
|
|
||||||
view->natural_height = toplevel->base->surface->current.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool csd = false;
|
bool csd = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,9 +289,6 @@ static void set_activated(struct sway_view *view, bool activated) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_xwayland_surface_activate(surface, activated);
|
wlr_xwayland_surface_activate(surface, activated);
|
||||||
if (activated) {
|
|
||||||
wlr_xwayland_surface_restack(surface, NULL, XCB_STACK_MODE_ABOVE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_tiled(struct sway_view *view, bool tiled) {
|
static void set_tiled(struct sway_view *view, bool tiled) {
|
||||||
|
|
|
||||||
|
|
@ -399,6 +399,8 @@ static void ipc_json_describe_enabled_output(struct sway_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
|
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
|
||||||
|
|
||||||
|
json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing));
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
||||||
|
|
@ -593,6 +595,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
||||||
|
|
||||||
json_object_object_add(object, "max_render_time", json_object_new_int(c->view->max_render_time));
|
json_object_object_add(object, "max_render_time", json_object_new_int(c->view->max_render_time));
|
||||||
|
|
||||||
|
json_object_object_add(object, "allow_tearing", json_object_new_boolean(view_can_tear(c->view)));
|
||||||
|
|
||||||
json_object_object_add(object, "shell", json_object_new_string(view_get_shell(c->view)));
|
json_object_object_add(object, "shell", json_object_new_string(view_get_shell(c->view)));
|
||||||
|
|
||||||
json_object_object_add(object, "inhibit_idle",
|
json_object_object_add(object, "inhibit_idle",
|
||||||
|
|
@ -1129,7 +1133,9 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
|
||||||
json_object *layouts_arr = json_object_new_array();
|
json_object *layouts_arr = json_object_new_array();
|
||||||
json_object_object_add(object, "xkb_layout_names", layouts_arr);
|
json_object_object_add(object, "xkb_layout_names", layouts_arr);
|
||||||
|
|
||||||
xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(keymap);
|
xkb_layout_index_t num_layouts =
|
||||||
|
keymap ? xkb_keymap_num_layouts(keymap) : 0;
|
||||||
|
// Virtual keyboards might have null keymap
|
||||||
xkb_layout_index_t layout_idx;
|
xkb_layout_index_t layout_idx;
|
||||||
for (layout_idx = 0; layout_idx < num_layouts; layout_idx++) {
|
for (layout_idx = 0; layout_idx < num_layouts; layout_idx++) {
|
||||||
const char *layout = xkb_keymap_layout_get_name(keymap, layout_idx);
|
const char *layout = xkb_keymap_layout_get_name(keymap, layout_idx);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ sway_sources = files(
|
||||||
'desktop/idle_inhibit_v1.c',
|
'desktop/idle_inhibit_v1.c',
|
||||||
'desktop/layer_shell.c',
|
'desktop/layer_shell.c',
|
||||||
'desktop/output.c',
|
'desktop/output.c',
|
||||||
|
'desktop/tearing.c',
|
||||||
'desktop/transaction.c',
|
'desktop/transaction.c',
|
||||||
'desktop/xdg_shell.c',
|
'desktop/xdg_shell.c',
|
||||||
'desktop/launcher.c',
|
'desktop/launcher.c',
|
||||||
|
|
@ -41,6 +42,7 @@ sway_sources = files(
|
||||||
'config/seat.c',
|
'config/seat.c',
|
||||||
'config/input.c',
|
'config/input.c',
|
||||||
|
|
||||||
|
'commands/allow_tearing.c',
|
||||||
'commands/assign.c',
|
'commands/assign.c',
|
||||||
'commands/bar.c',
|
'commands/bar.c',
|
||||||
'commands/bind.c',
|
'commands/bind.c',
|
||||||
|
|
@ -188,6 +190,7 @@ sway_sources = files(
|
||||||
'commands/input/xkb_variant.c',
|
'commands/input/xkb_variant.c',
|
||||||
|
|
||||||
'commands/output/adaptive_sync.c',
|
'commands/output/adaptive_sync.c',
|
||||||
|
'commands/output/allow_tearing.c',
|
||||||
'commands/output/background.c',
|
'commands/output/background.c',
|
||||||
'commands/output/disable.c',
|
'commands/output/disable.c',
|
||||||
'commands/output/dpms.c',
|
'commands/output/dpms.c',
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||||
|
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
|
||||||
#include <wlr/types/wlr_output_management_v1.h>
|
#include <wlr/types/wlr_output_management_v1.h>
|
||||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||||
|
|
@ -248,6 +249,11 @@ bool server_init(struct sway_server *server) {
|
||||||
wlr_drm_create(server->wl_display, server->renderer);
|
wlr_drm_create(server->wl_display, server->renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (wlr_renderer_get_drm_fd(server->renderer) >= 0 &&
|
||||||
|
server->renderer->features.timeline) {
|
||||||
|
wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1,
|
||||||
|
wlr_renderer_get_drm_fd(server->renderer));
|
||||||
|
}
|
||||||
|
|
||||||
server->allocator = wlr_allocator_autocreate(server->backend,
|
server->allocator = wlr_allocator_autocreate(server->backend,
|
||||||
server->renderer);
|
server->renderer);
|
||||||
|
|
@ -266,9 +272,8 @@ bool server_init(struct sway_server *server) {
|
||||||
|
|
||||||
server->gamma_control_manager_v1 =
|
server->gamma_control_manager_v1 =
|
||||||
wlr_gamma_control_manager_v1_create(server->wl_display);
|
wlr_gamma_control_manager_v1_create(server->wl_display);
|
||||||
server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma;
|
wlr_scene_set_gamma_control_manager_v1(root->root_scene,
|
||||||
wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma,
|
server->gamma_control_manager_v1);
|
||||||
&server->gamma_control_set_gamma);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
@ -372,6 +377,13 @@ bool server_init(struct sway_server *server) {
|
||||||
wlr_content_type_manager_v1_create(server->wl_display, 1);
|
wlr_content_type_manager_v1_create(server->wl_display, 1);
|
||||||
wlr_fractional_scale_manager_v1_create(server->wl_display, 1);
|
wlr_fractional_scale_manager_v1_create(server->wl_display, 1);
|
||||||
|
|
||||||
|
server->tearing_control_v1 =
|
||||||
|
wlr_tearing_control_manager_v1_create(server->wl_display, 1);
|
||||||
|
server->tearing_control_new_object.notify = handle_new_tearing_hint;
|
||||||
|
wl_signal_add(&server->tearing_control_v1->events.new_object,
|
||||||
|
&server->tearing_control_new_object);
|
||||||
|
wl_list_init(&server->tearing_controllers);
|
||||||
|
|
||||||
struct wlr_xdg_foreign_registry *foreign_registry =
|
struct wlr_xdg_foreign_registry *foreign_registry =
|
||||||
wlr_xdg_foreign_registry_create(server->wl_display);
|
wlr_xdg_foreign_registry_create(server->wl_display);
|
||||||
wlr_xdg_foreign_v1_create(server->wl_display, foreign_registry);
|
wlr_xdg_foreign_v1_create(server->wl_display, foreign_registry);
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,26 @@ must be separated by one space. For example:
|
||||||
may have no effect or produce unexpected output when used together with future
|
may have no effect or produce unexpected output when used together with future
|
||||||
HDR support features.
|
HDR support features.
|
||||||
|
|
||||||
|
*output* <name> allow_tearing yes|no
|
||||||
|
Allows or disallows screen tearing as a result of immediate page flips,
|
||||||
|
and an immediate presentation mode from a client. The default is that no
|
||||||
|
screen tearing is allowed.
|
||||||
|
|
||||||
|
With immediate page flips, frames from the client are presented as soon
|
||||||
|
as possible instead of synchronizing with the monitor's vblank interval
|
||||||
|
(VSync).
|
||||||
|
|
||||||
|
It is recommended to set *max_render_time* to *off*. In that case a page flip
|
||||||
|
happens as soon as a client updates. Otherwise, tearing will only happen if
|
||||||
|
rendering takes longer than the configured milliseconds before the next
|
||||||
|
display refresh.
|
||||||
|
|
||||||
|
To adjust whether tearing is allowed for specific applications, see
|
||||||
|
*allow_tearing* in *sway*(5). Note that tearing will only be enabled
|
||||||
|
when it's allowed for both the output and the application.
|
||||||
|
|
||||||
|
This setting only has effect when a window is fullscreen on the output.
|
||||||
|
|
||||||
# SEE ALSO
|
# SEE ALSO
|
||||||
|
|
||||||
*sway*(5) *sway-input*(5)
|
*sway*(5) *sway-input*(5)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ which you may only select one. *[...]* is used for optional arguments, and
|
||||||
This section only lists general commands. For input and output commands, refer
|
This section only lists general commands. For input and output commands, refer
|
||||||
to *sway-input*(5) and *sway-output*(5).
|
to *sway-input*(5) and *sway-output*(5).
|
||||||
|
|
||||||
|
## Config only commands
|
||||||
The following commands may only be used in the configuration file.
|
The following commands may only be used in the configuration file.
|
||||||
|
|
||||||
*bar* [<bar-id>] <bar-subcommands...>
|
*bar* [<bar-id>] <bar-subcommands...>
|
||||||
|
|
@ -98,6 +99,7 @@ The following commands may only be used in the configuration file.
|
||||||
machines, it may be desirable to have Xwayland started immediately by
|
machines, it may be desirable to have Xwayland started immediately by
|
||||||
using _force_ instead of _enable_.
|
using _force_ instead of _enable_.
|
||||||
|
|
||||||
|
## Runtime only commands
|
||||||
The following commands cannot be used directly in the configuration file.
|
The following commands cannot be used directly in the configuration file.
|
||||||
They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
|
They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
|
||||||
|
|
||||||
|
|
@ -215,6 +217,20 @@ set|plus|minus|toggle <amount>
|
||||||
effect on the output the window is currently on. See *sway-output*(5) for
|
effect on the output the window is currently on. See *sway-output*(5) for
|
||||||
further details.
|
further details.
|
||||||
|
|
||||||
|
*allow_tearing* yes|no
|
||||||
|
Allows or disallows screen tearing as a result of immediate page flips
|
||||||
|
for a fullscreen application.
|
||||||
|
|
||||||
|
When this option is not set, the tearing hints provided by the application
|
||||||
|
determine whether tearing is allowed. When _yes_ is specified,
|
||||||
|
the application allows tearing regardless of the tearing hints.
|
||||||
|
When _no_ is specified, tearing will never be allowed on the application,
|
||||||
|
regardless of the tearing hints.
|
||||||
|
|
||||||
|
This setting only has an effect if tearing is allowed on the output through
|
||||||
|
the per-output *allow_tearing* setting. See *sway-output*(5)
|
||||||
|
for further details.
|
||||||
|
|
||||||
*move* left|right|up|down [<px> px]
|
*move* left|right|up|down [<px> px]
|
||||||
Moves the focused container in the direction specified. The optional _px_
|
Moves the focused container in the direction specified. The optional _px_
|
||||||
argument specifies how many pixels to move the container. If unspecified,
|
argument specifies how many pixels to move the container. If unspecified,
|
||||||
|
|
@ -371,6 +387,7 @@ set|plus|minus|toggle <amount>
|
||||||
|
|
||||||
The default format is "%title".
|
The default format is "%title".
|
||||||
|
|
||||||
|
## Config or runtime commands
|
||||||
The following commands may be used either in the configuration file or at
|
The following commands may be used either in the configuration file or at
|
||||||
runtime.
|
runtime.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -773,11 +773,11 @@ void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, s
|
||||||
// Fall back to centering on the workspace.
|
// Fall back to centering on the workspace.
|
||||||
container_floating_move_to_center(con);
|
container_floating_move_to_center(con);
|
||||||
} else {
|
} else {
|
||||||
int rel_x = con->pending.x - old->x + (con->pending.width / 2);
|
double rel_x = con->pending.x - old->x + (con->pending.width / 2);
|
||||||
int rel_y = con->pending.y - old->y + (con->pending.height / 2);
|
double rel_y = con->pending.y - old->y + (con->pending.height / 2);
|
||||||
|
|
||||||
con->pending.x = new->x + (double)(rel_x * new->width) / old->width - (con->pending.width / 2);
|
con->pending.x = new->x + (rel_x * new->width) / old->width - (con->pending.width / 2);
|
||||||
con->pending.y = new->y + (double)(rel_y * new->height) / old->height - (con->pending.height / 2);
|
con->pending.y = new->y + (rel_y * new->height) / old->height - (con->pending.height / 2);
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y);
|
sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
|
||||||
view->executed_criteria = create_list();
|
view->executed_criteria = create_list();
|
||||||
view->allow_request_urgent = true;
|
view->allow_request_urgent = true;
|
||||||
view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
|
view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
|
||||||
|
view->tearing_mode = TEARING_WINDOW_HINT;
|
||||||
wl_signal_init(&view->events.unmap);
|
wl_signal_init(&view->events.unmap);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1260,6 +1261,19 @@ bool view_is_transient_for(struct sway_view *child,
|
||||||
child->impl->is_transient_for(child, ancestor);
|
child->impl->is_transient_for(child, ancestor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool view_can_tear(struct sway_view *view) {
|
||||||
|
switch (view->tearing_mode) {
|
||||||
|
case TEARING_OVERRIDE_FALSE:
|
||||||
|
return false;
|
||||||
|
case TEARING_OVERRIDE_TRUE:
|
||||||
|
return true;
|
||||||
|
case TEARING_WINDOW_HINT:
|
||||||
|
return view->tearing_hint ==
|
||||||
|
WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_frame_done_iterator(struct wlr_scene_buffer *scene_buffer,
|
static void send_frame_done_iterator(struct wlr_scene_buffer *scene_buffer,
|
||||||
int x, int y, void *data) {
|
int x, int y, void *data) {
|
||||||
struct timespec *when = data;
|
struct timespec *when = data;
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ static void pretty_print_output(json_object *o) {
|
||||||
json_object_object_get_ex(o, "current_workspace", &ws);
|
json_object_object_get_ex(o, "current_workspace", &ws);
|
||||||
json_object_object_get_ex(o, "non_desktop", &non_desktop);
|
json_object_object_get_ex(o, "non_desktop", &non_desktop);
|
||||||
json_object *make, *model, *serial, *scale, *scale_filter, *subpixel,
|
json_object *make, *model, *serial, *scale, *scale_filter, *subpixel,
|
||||||
*transform, *max_render_time, *adaptive_sync_status;
|
*transform, *max_render_time, *adaptive_sync_status, *allow_tearing;
|
||||||
json_object_object_get_ex(o, "make", &make);
|
json_object_object_get_ex(o, "make", &make);
|
||||||
json_object_object_get_ex(o, "model", &model);
|
json_object_object_get_ex(o, "model", &model);
|
||||||
json_object_object_get_ex(o, "serial", &serial);
|
json_object_object_get_ex(o, "serial", &serial);
|
||||||
|
|
@ -203,6 +203,7 @@ static void pretty_print_output(json_object *o) {
|
||||||
json_object_object_get_ex(o, "transform", &transform);
|
json_object_object_get_ex(o, "transform", &transform);
|
||||||
json_object_object_get_ex(o, "max_render_time", &max_render_time);
|
json_object_object_get_ex(o, "max_render_time", &max_render_time);
|
||||||
json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status);
|
json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status);
|
||||||
|
json_object_object_get_ex(o, "allow_tearing", &allow_tearing);
|
||||||
json_object *x, *y;
|
json_object *x, *y;
|
||||||
json_object_object_get_ex(rect, "x", &x);
|
json_object_object_get_ex(rect, "x", &x);
|
||||||
json_object_object_get_ex(rect, "y", &y);
|
json_object_object_get_ex(rect, "y", &y);
|
||||||
|
|
@ -256,6 +257,9 @@ static void pretty_print_output(json_object *o) {
|
||||||
|
|
||||||
printf(" Adaptive sync: %s\n",
|
printf(" Adaptive sync: %s\n",
|
||||||
json_object_get_string(adaptive_sync_status));
|
json_object_get_string(adaptive_sync_status));
|
||||||
|
|
||||||
|
printf(" Allow tearing: %s\n",
|
||||||
|
json_object_get_boolean(allow_tearing) ? "yes" : "no");
|
||||||
} else {
|
} else {
|
||||||
printf(
|
printf(
|
||||||
"Output %s '%s %s %s' (disabled)\n",
|
"Output %s '%s %s %s' (disabled)\n",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue