mirror of
https://github.com/swaywm/sway.git
synced 2024-11-14 06:24:20 +01:00
Compare commits
17 Commits
761d8fbf25
...
966af2f577
Author | SHA1 | Date | |
---|---|---|---|
|
966af2f577 | ||
|
4cfcb3643b | ||
|
d417a8fcd0 | ||
|
f38719f575 | ||
|
1e53007bc3 | ||
|
e7c972b04a | ||
|
839434abc0 | ||
|
015e357fce | ||
|
a63027245a | ||
|
17ecb9eb1d | ||
|
af0d4a048a | ||
|
7e0c0dda42 | ||
|
7d93652105 | ||
|
35d8adefc4 | ||
|
8363699f14 | ||
|
ce6b2db0f2 | ||
|
69ffa4437c |
@ -1,7 +1,5 @@
|
||||
# sway
|
||||
|
||||
[English][en] - [عربي][ar] - **[Česky][cs]** - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [ქართული][ge] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||
|
||||
sway je s [i3] kompatibilní [Wayland] kompozitor. Přečtěte si [FAQ]. Připojte se na
|
||||
[IRC kanál][IRC channel] \(#sway na irc.libera.chat).
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
# sway
|
||||
|
||||
[English][en] - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - **[Svenska][sv]** - [Ελληνικά][gr] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||
|
||||
sway är en [i3]-kompatibel [Wayland] compositor. Läs våran [FAQ]-sida. Gå med i vår
|
||||
[IRC-kanal] \(#sway på irc.libera.chat).
|
||||
|
||||
|
@ -63,6 +63,7 @@ struct sway_cursor {
|
||||
struct wl_listener tool_tip;
|
||||
struct wl_listener tool_proximity;
|
||||
struct wl_listener tool_button;
|
||||
struct wl_listener tool_axis_scroll;
|
||||
bool simulating_pointer_from_tool_tip;
|
||||
bool simulating_pointer_from_tool_button;
|
||||
uint32_t tool_buttons;
|
||||
|
@ -48,6 +48,8 @@ struct sway_seatop_impl {
|
||||
struct wlr_touch_cancel_event *event);
|
||||
void (*tablet_tool_motion)(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, uint32_t time_msec);
|
||||
void (*tablet_tool_axis_scroll)(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, struct wlr_tablet_tool_axis_scroll_event *event);
|
||||
void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool,
|
||||
uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
|
||||
void (*end)(struct sway_seat *seat);
|
||||
@ -300,6 +302,10 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec);
|
||||
void seatop_pointer_axis(struct sway_seat *seat,
|
||||
struct wlr_pointer_axis_event *event);
|
||||
|
||||
void seatop_tablet_tool_axis_scroll(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool,
|
||||
struct wlr_tablet_tool_axis_scroll_event *event);
|
||||
|
||||
void seatop_tablet_tool_tip(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, uint32_t time_msec,
|
||||
enum wlr_tablet_tool_tip_state state);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh -eu
|
||||
|
||||
prev=$(git describe --tags --abbrev=0)
|
||||
next=$(meson rewrite kwargs info project / 2>&1 >/dev/null | jq -r '.kwargs["project#/"].version')
|
||||
next=$(meson rewrite kwargs info project / | jq -r '.kwargs["project#/"].version')
|
||||
|
||||
case "$next" in
|
||||
*-dev)
|
||||
|
@ -285,7 +285,6 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
|
||||
mhz = mhz <= 0 ? INT_MAX : mhz;
|
||||
|
||||
if (wl_list_empty(&output->modes) || custom) {
|
||||
sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
|
||||
wlr_output_state_set_custom_mode(pending, width, height,
|
||||
refresh_rate > 0 ? mhz : 0);
|
||||
return;
|
||||
@ -305,10 +304,7 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best) {
|
||||
sway_log(SWAY_INFO, "Assigning configured mode (%dx%d@%.3fHz) to %s",
|
||||
best->width, best->height, best->refresh / 1000.f, output->name);
|
||||
} else {
|
||||
if (!best) {
|
||||
best = wlr_output_preferred_mode(output);
|
||||
sway_log(SWAY_INFO, "Configured mode (%dx%d@%.3fHz) not available, "
|
||||
"applying preferred mode (%dx%d@%.3fHz)",
|
||||
@ -325,7 +321,6 @@ static void set_modeline(struct wlr_output *output,
|
||||
sway_log(SWAY_ERROR, "Modeline can only be set to DRM output");
|
||||
return;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "Assigning custom modeline to %s", output->name);
|
||||
struct wlr_output_mode *mode = wlr_drm_connector_add_mode(output, drm_mode);
|
||||
if (mode) {
|
||||
wlr_output_state_set_mode(pending, mode);
|
||||
@ -391,7 +386,6 @@ static int compute_default_scale(struct wlr_output *output,
|
||||
|
||||
double dpi_x = (double) width / (output->phys_width / MM_PER_INCH);
|
||||
double dpi_y = (double) height / (output->phys_height / MM_PER_INCH);
|
||||
sway_log(SWAY_DEBUG, "Output DPI: %fx%f", dpi_x, dpi_y);
|
||||
if (dpi_x <= HIDPI_DPI_LIMIT || dpi_y <= HIDPI_DPI_LIMIT) {
|
||||
return 1;
|
||||
}
|
||||
@ -427,78 +421,57 @@ static void queue_output_config(struct output_config *oc,
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
if (output_config_is_disabling(oc)) {
|
||||
sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name);
|
||||
wlr_output_state_set_enabled(pending, false);
|
||||
return;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Turning on output %s", wlr_output->name);
|
||||
wlr_output_state_set_enabled(pending, true);
|
||||
|
||||
if (oc && oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t) -1) {
|
||||
sway_log(SWAY_DEBUG, "Set %s modeline",
|
||||
wlr_output->name);
|
||||
set_modeline(wlr_output, pending, &oc->drm_mode);
|
||||
} else if (oc && oc->width > 0 && oc->height > 0) {
|
||||
sway_log(SWAY_DEBUG, "Set %s mode to %dx%d (%f Hz)",
|
||||
wlr_output->name, oc->width, oc->height, oc->refresh_rate);
|
||||
set_mode(wlr_output, pending, oc->width, oc->height,
|
||||
oc->refresh_rate, oc->custom_mode == 1);
|
||||
} else if (!wl_list_empty(&wlr_output->modes)) {
|
||||
sway_log(SWAY_DEBUG, "Set preferred mode");
|
||||
struct wlr_output_mode *preferred_mode =
|
||||
wlr_output_preferred_mode(wlr_output);
|
||||
wlr_output_state_set_mode(pending, preferred_mode);
|
||||
}
|
||||
|
||||
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));
|
||||
if (oc && oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN) {
|
||||
wlr_output_state_set_subpixel(pending, oc->subpixel);
|
||||
} else {
|
||||
wlr_output_state_set_subpixel(pending, output->detected_subpixel);
|
||||
}
|
||||
|
||||
enum wl_output_transform tr = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
if (oc && oc->transform >= 0) {
|
||||
tr = oc->transform;
|
||||
wlr_output_state_set_transform(pending, oc->transform);
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
} else if (wlr_output_is_drm(wlr_output)) {
|
||||
tr = wlr_drm_connector_get_panel_orientation(wlr_output);
|
||||
sway_log(SWAY_DEBUG, "Auto-detected output transform: %d", tr);
|
||||
wlr_output_state_set_transform(pending,
|
||||
wlr_drm_connector_get_panel_orientation(wlr_output));
|
||||
#endif
|
||||
}
|
||||
if (wlr_output->transform != tr) {
|
||||
sway_log(SWAY_DEBUG, "Set %s transform to %d", wlr_output->name, tr);
|
||||
wlr_output_state_set_transform(pending, tr);
|
||||
} else {
|
||||
wlr_output_state_set_transform(pending, WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
}
|
||||
|
||||
// Apply the scale last before the commit, because the scale auto-detection
|
||||
// reads the pending output size
|
||||
float scale;
|
||||
// Apply the scale after sorting out the mode, because the scale
|
||||
// auto-detection reads the pending output size
|
||||
if (oc && oc->scale > 0) {
|
||||
scale = oc->scale;
|
||||
|
||||
// The factional-scale-v1 protocol uses increments of 120ths to send
|
||||
// the scale factor to the client. Adjust the scale so that we use the
|
||||
// same value as the clients'.
|
||||
float adjusted_scale = round(scale * 120) / 120;
|
||||
if (scale != adjusted_scale) {
|
||||
sway_log(SWAY_INFO, "Adjusting output scale from %f to %f",
|
||||
scale, adjusted_scale);
|
||||
scale = adjusted_scale;
|
||||
}
|
||||
wlr_output_state_set_scale(pending, round(oc->scale * 120) / 120);
|
||||
} else {
|
||||
scale = compute_default_scale(wlr_output, pending);
|
||||
sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale);
|
||||
}
|
||||
if (scale != wlr_output->scale) {
|
||||
sway_log(SWAY_DEBUG, "Set %s scale to %f", wlr_output->name, scale);
|
||||
wlr_output_state_set_scale(pending, scale);
|
||||
wlr_output_state_set_scale(pending,
|
||||
compute_default_scale(wlr_output, pending));
|
||||
}
|
||||
|
||||
if (oc && oc->adaptive_sync != -1 && wlr_output->adaptive_sync_supported) {
|
||||
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
|
||||
oc->adaptive_sync);
|
||||
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
||||
if (wlr_output->adaptive_sync_supported) {
|
||||
if (oc && oc->adaptive_sync != -1) {
|
||||
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
||||
} else {
|
||||
wlr_output_state_set_adaptive_sync_enabled(pending, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
@ -513,6 +486,8 @@ static void queue_output_config(struct output_config *oc,
|
||||
} else {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
} else {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,24 +506,23 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
||||
return true;
|
||||
}
|
||||
|
||||
if (oc) {
|
||||
enum scale_filter_mode scale_filter_old = output->scale_filter;
|
||||
switch (oc->scale_filter) {
|
||||
case SCALE_FILTER_DEFAULT:
|
||||
case SCALE_FILTER_SMART:
|
||||
output->scale_filter = ceilf(wlr_output->scale) == wlr_output->scale ?
|
||||
SCALE_FILTER_NEAREST : SCALE_FILTER_LINEAR;
|
||||
break;
|
||||
case SCALE_FILTER_LINEAR:
|
||||
case SCALE_FILTER_NEAREST:
|
||||
output->scale_filter = oc->scale_filter;
|
||||
break;
|
||||
}
|
||||
if (scale_filter_old != output->scale_filter) {
|
||||
sway_log(SWAY_DEBUG, "Set %s scale_filter to %s", oc->name,
|
||||
sway_output_scale_filter_to_string(output->scale_filter));
|
||||
wlr_damage_ring_add_whole(&output->scene_output->damage_ring);
|
||||
}
|
||||
enum scale_filter_mode scale_filter_old = output->scale_filter;
|
||||
enum scale_filter_mode scale_filter_new = oc ? oc->scale_filter : SCALE_FILTER_DEFAULT;
|
||||
switch (scale_filter_new) {
|
||||
case SCALE_FILTER_DEFAULT:
|
||||
case SCALE_FILTER_SMART:
|
||||
output->scale_filter = ceilf(wlr_output->scale) == wlr_output->scale ?
|
||||
SCALE_FILTER_NEAREST : SCALE_FILTER_LINEAR;
|
||||
break;
|
||||
case SCALE_FILTER_LINEAR:
|
||||
case SCALE_FILTER_NEAREST:
|
||||
output->scale_filter = scale_filter_new;
|
||||
break;
|
||||
}
|
||||
if (scale_filter_old != output->scale_filter) {
|
||||
sway_log(SWAY_DEBUG, "Set %s scale_filter to %s", oc->name,
|
||||
sway_output_scale_filter_to_string(output->scale_filter));
|
||||
wlr_damage_ring_add_whole(&output->scene_output->damage_ring);
|
||||
}
|
||||
|
||||
// Find position for it
|
||||
@ -571,25 +545,19 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
||||
output_enable(output);
|
||||
}
|
||||
|
||||
if (oc && oc->max_render_time >= 0) {
|
||||
sway_log(SWAY_DEBUG, "Set %s max render time to %d",
|
||||
oc->name, oc->max_render_time);
|
||||
output->max_render_time = oc->max_render_time;
|
||||
}
|
||||
|
||||
if (oc && oc->set_color_transform) {
|
||||
if (oc->color_transform) {
|
||||
wlr_color_transform_ref(oc->color_transform);
|
||||
}
|
||||
wlr_color_transform_unref(output->color_transform);
|
||||
output->color_transform = oc->color_transform;
|
||||
} else {
|
||||
wlr_color_transform_unref(output->color_transform);
|
||||
output->color_transform = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0;
|
||||
output->allow_tearing = oc && oc->allow_tearing > 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -605,15 +573,6 @@ static struct output_config *find_output_config_from_list(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Set output defaults for the "base" configuration
|
||||
result->enabled = 1;
|
||||
result->power = 1;
|
||||
result->scale = 0; // auto
|
||||
result->subpixel = sway_output->detected_subpixel;
|
||||
result->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
result->max_render_time = 0;
|
||||
result->allow_tearing = 0;
|
||||
|
||||
char id[128];
|
||||
output_get_identifier(id, sizeof(id), sway_output);
|
||||
|
||||
@ -692,6 +651,13 @@ static void dump_output_state(struct wlr_output *wlr_output, struct wlr_output_s
|
||||
sway_log(SWAY_DEBUG, " adaptive_sync: %s",
|
||||
state->adaptive_sync_enabled ? "enabled": "disabled");
|
||||
}
|
||||
if (state->committed & WLR_OUTPUT_STATE_SCALE) {
|
||||
sway_log(SWAY_DEBUG, " scale: %f", state->scale);
|
||||
}
|
||||
if (state->committed & WLR_OUTPUT_STATE_SUBPIXEL) {
|
||||
sway_log(SWAY_DEBUG, " subpixel: %s",
|
||||
sway_wl_output_subpixel_to_string(state->subpixel));
|
||||
}
|
||||
}
|
||||
|
||||
static bool search_valid_config(struct search_context *ctx, size_t output_idx);
|
||||
@ -906,9 +872,8 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
|
||||
backend_state->output = cfg->output->wlr_output;
|
||||
wlr_output_state_init(&backend_state->base);
|
||||
|
||||
sway_log(SWAY_DEBUG, "Preparing config for %s",
|
||||
cfg->output->wlr_output->name);
|
||||
queue_output_config(cfg->config, cfg->output, &backend_state->base);
|
||||
dump_output_state(cfg->output->wlr_output, &backend_state->base);
|
||||
}
|
||||
|
||||
struct wlr_output_swapchain_manager swapchain_mgr;
|
||||
|
@ -54,7 +54,7 @@ struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||
}
|
||||
|
||||
static void arrange_surface(struct sway_output *output, const struct wlr_box *full_area,
|
||||
struct wlr_box *usable_area, struct wlr_scene_tree *tree) {
|
||||
struct wlr_box *usable_area, struct wlr_scene_tree *tree, bool exclusive) {
|
||||
struct wlr_scene_node *node;
|
||||
wl_list_for_each(node, &tree->children, link) {
|
||||
struct sway_layer_surface *surface = scene_descriptor_try_get(node,
|
||||
@ -68,6 +68,10 @@ static void arrange_surface(struct sway_output *output, const struct wlr_box *fu
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((surface->scene->layer_surface->current.exclusive_zone > 0) != exclusive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wlr_scene_layer_surface_v1_configure(surface->scene, full_area, usable_area);
|
||||
}
|
||||
}
|
||||
@ -78,10 +82,15 @@ void arrange_layers(struct sway_output *output) {
|
||||
&usable_area.width, &usable_area.height);
|
||||
const struct wlr_box full_area = usable_area;
|
||||
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_background);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_top);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_overlay);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_overlay, true);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_top, true);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom, true);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_background, true);
|
||||
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_overlay, false);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_top, false);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom, false);
|
||||
arrange_surface(output, &full_area, &usable_area, output->layers.shell_background, false);
|
||||
|
||||
if (!wlr_box_equal(&usable_area, &output->usable_area)) {
|
||||
sway_log(SWAY_DEBUG, "Usable area changed, rearranging output");
|
||||
|
@ -188,8 +188,8 @@ static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output,
|
||||
struct wlr_scene_buffer *buffer) {
|
||||
// if we are scaling down, we should always choose linear
|
||||
if (buffer->dst_width > 0 && buffer->dst_height > 0 && (
|
||||
buffer->dst_width < buffer->buffer_width ||
|
||||
buffer->dst_height < buffer->buffer_height)) {
|
||||
buffer->dst_width < buffer->WLR_PRIVATE.buffer_width ||
|
||||
buffer->dst_height < buffer->WLR_PRIVATE.buffer_height)) {
|
||||
return WLR_SCALE_FILTER_BILINEAR;
|
||||
}
|
||||
|
||||
@ -457,19 +457,47 @@ static void handle_request_state(struct wl_listener *listener, void *data) {
|
||||
struct sway_output *output =
|
||||
wl_container_of(listener, output, request_state);
|
||||
const struct wlr_output_event_request_state *event = data;
|
||||
const struct wlr_output_state *state = event->state;
|
||||
|
||||
uint32_t committed = event->state->committed;
|
||||
wlr_output_commit_state(output->wlr_output, event->state);
|
||||
// Store the requested changes so that the active configuration is
|
||||
// consistent with the current state, and to avoid duplicate logic to apply
|
||||
// the changes.
|
||||
struct output_config *oc = new_output_config(output->wlr_output->name);
|
||||
if (!oc) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (committed & (
|
||||
WLR_OUTPUT_STATE_MODE |
|
||||
WLR_OUTPUT_STATE_TRANSFORM |
|
||||
WLR_OUTPUT_STATE_SCALE)) {
|
||||
arrange_layers(output);
|
||||
arrange_output(output);
|
||||
transaction_commit_dirty();
|
||||
int committed = state->committed;
|
||||
if (committed & WLR_OUTPUT_STATE_MODE) {
|
||||
if (state->mode != NULL) {
|
||||
oc->width = state->mode->width;
|
||||
oc->height = state->mode->height;
|
||||
oc->refresh_rate = state->mode->refresh / 1000.f;
|
||||
} else {
|
||||
oc->width = state->custom_mode.width;
|
||||
oc->height = state->custom_mode.height;
|
||||
oc->refresh_rate = state->custom_mode.refresh / 1000.f;
|
||||
}
|
||||
committed &= ~WLR_OUTPUT_STATE_MODE;
|
||||
}
|
||||
if (committed & WLR_OUTPUT_STATE_SCALE) {
|
||||
oc->scale = state->scale;
|
||||
committed &= ~WLR_OUTPUT_STATE_SCALE;
|
||||
}
|
||||
if (committed & WLR_OUTPUT_STATE_TRANSFORM) {
|
||||
oc->transform = state->transform;
|
||||
committed &= ~WLR_OUTPUT_STATE_TRANSFORM;
|
||||
}
|
||||
|
||||
update_output_manager_config(output->server);
|
||||
// We do not expect or support any other changes here
|
||||
assert(committed == 0);
|
||||
store_output_config(oc);
|
||||
apply_stored_output_configs();
|
||||
|
||||
if (server.delayed_modeset != NULL) {
|
||||
wl_event_source_remove(server.delayed_modeset);
|
||||
server.delayed_modeset = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,6 +582,10 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
||||
static struct output_config *output_config_for_config_head(
|
||||
struct wlr_output_configuration_head_v1 *config_head) {
|
||||
struct output_config *oc = new_output_config(config_head->state.output->name);
|
||||
if (!oc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oc->enabled = config_head->state.enabled;
|
||||
if (!oc->enabled) {
|
||||
return oc;
|
||||
@ -584,7 +616,8 @@ static void output_manager_apply(struct sway_server *server,
|
||||
size_t configs_len = config->output_configs->length + wl_list_length(&cfg->heads);
|
||||
struct output_config **configs = calloc(configs_len, sizeof(*configs));
|
||||
if (!configs) {
|
||||
goto done;
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
goto error;
|
||||
}
|
||||
size_t start_new_configs = config->output_configs->length;
|
||||
for (size_t idx = 0; idx < start_new_configs; idx++) {
|
||||
@ -597,6 +630,10 @@ static void output_manager_apply(struct sway_server *server,
|
||||
// Generate the configuration and store it as a temporary
|
||||
// config. We keep a record of it so we can remove it later.
|
||||
struct output_config *oc = output_config_for_config_head(config_head);
|
||||
if (!oc) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
goto error_config;
|
||||
}
|
||||
configs[config_idx++] = oc;
|
||||
}
|
||||
|
||||
@ -604,6 +641,8 @@ static void output_manager_apply(struct sway_server *server,
|
||||
// if any output configured for enablement fails to be enabled, even if it
|
||||
// was not part of the config heads we were asked to configure.
|
||||
ok = apply_output_configs(configs, configs_len, test_only, false);
|
||||
|
||||
error_config:
|
||||
for (size_t idx = start_new_configs; idx < configs_len; idx++) {
|
||||
struct output_config *cfg = configs[idx];
|
||||
if (!test_only && ok) {
|
||||
@ -614,7 +653,7 @@ static void output_manager_apply(struct sway_server *server,
|
||||
}
|
||||
free(configs);
|
||||
|
||||
done:
|
||||
error:
|
||||
if (ok) {
|
||||
wlr_output_configuration_v1_send_succeeded(cfg);
|
||||
if (server->delayed_modeset != NULL) {
|
||||
@ -649,6 +688,11 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
|
||||
struct sway_output *output = event->output->data;
|
||||
|
||||
struct output_config *oc = new_output_config(output->wlr_output->name);
|
||||
if (!oc) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->mode) {
|
||||
case ZWLR_OUTPUT_POWER_V1_MODE_OFF:
|
||||
oc->power = 0;
|
||||
|
@ -725,6 +725,38 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) {
|
||||
0, 0, event->time_msec);
|
||||
}
|
||||
|
||||
static void handle_tool_axis_scroll(struct wl_listener *listener, void *data) {
|
||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis_scroll);
|
||||
struct wlr_tablet_tool_axis_scroll_event *event = data;
|
||||
cursor_handle_activity_from_device(cursor, &event->tablet->base);
|
||||
|
||||
struct sway_tablet_tool *sway_tool = event->tool->data;
|
||||
struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2;
|
||||
struct sway_seat *seat = cursor->seat;
|
||||
|
||||
|
||||
double sx, sy;
|
||||
struct wlr_surface *surface = NULL;
|
||||
node_at_coords(seat, cursor->cursor->x, cursor->cursor->y,
|
||||
&surface, &sx, &sy);
|
||||
|
||||
if (surface && wlr_surface_accepts_tablet_v2(tablet_v2, surface)) {
|
||||
sway_log(SWAY_DEBUG, "axis_scroll, accepts tablet");
|
||||
seatop_tablet_tool_axis_scroll(cursor->seat, sway_tool, event);
|
||||
} else {
|
||||
struct wlr_pointer_axis_event simulated_pointer_event = {
|
||||
.pointer = NULL, // FIXME
|
||||
.time_msec = event->time_msec,
|
||||
.source = event->source,
|
||||
.orientation = event->orientation,
|
||||
.delta = event->delta,
|
||||
.delta_discrete = 0,
|
||||
};
|
||||
seatop_pointer_axis(cursor->seat, &simulated_pointer_event);
|
||||
sway_log(SWAY_DEBUG, "axis_scroll, simulating");
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_tool_button(struct wl_listener *listener, void *data) {
|
||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button);
|
||||
struct wlr_tablet_tool_button_event *event = data;
|
||||
@ -1141,6 +1173,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
|
||||
wl_signal_add(&wlr_cursor->events.tablet_tool_proximity, &cursor->tool_proximity);
|
||||
cursor->tool_proximity.notify = handle_tool_proximity;
|
||||
|
||||
wl_signal_add(&wlr_cursor->events.tablet_tool_axis_scroll, &cursor->tool_axis_scroll);
|
||||
cursor->tool_axis_scroll.notify = handle_tool_axis_scroll;
|
||||
|
||||
wl_signal_add(&wlr_cursor->events.tablet_tool_button, &cursor->tool_button);
|
||||
cursor->tool_button.notify = handle_tool_button;
|
||||
|
||||
|
@ -1585,6 +1585,14 @@ void seatop_pointer_axis(struct sway_seat *seat,
|
||||
}
|
||||
}
|
||||
|
||||
void seatop_tablet_tool_axis_scroll(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool,
|
||||
struct wlr_tablet_tool_axis_scroll_event *event) {
|
||||
if (seat->seatop_impl->tablet_tool_axis_scroll) {
|
||||
seat->seatop_impl->tablet_tool_axis_scroll(seat, tool, event);
|
||||
}
|
||||
}
|
||||
|
||||
void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event,
|
||||
double lx, double ly) {
|
||||
if (seat->seatop_impl->touch_motion) {
|
||||
|
@ -355,6 +355,13 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
|
||||
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||
|
||||
bool mod_pressed = modifiers & config->floating_mod;
|
||||
uint32_t mod_move_btn = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
||||
uint32_t mod_resize_btn = config->floating_mod_inverse ? BTN_LEFT : BTN_RIGHT;
|
||||
bool mod_move_btn_pressed = mod_pressed && button == mod_move_btn;
|
||||
bool mod_resize_btn_pressed = mod_pressed && button == mod_resize_btn;
|
||||
bool titlebar_left_btn_pressed = on_titlebar && button == BTN_LEFT;
|
||||
|
||||
// Handle mouse bindings
|
||||
if (trigger_pointer_button_binding(seat, device, button, state, modifiers,
|
||||
on_titlebar, on_border, on_contents, on_workspace)) {
|
||||
@ -403,33 +410,28 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
}
|
||||
|
||||
// Handle tiling resize via mod
|
||||
bool mod_pressed = modifiers & config->floating_mod;
|
||||
if (cont && !is_floating_or_child && mod_pressed &&
|
||||
if (cont && !is_floating_or_child && mod_pressed && mod_resize_btn_pressed &&
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
uint32_t btn_resize = config->floating_mod_inverse ?
|
||||
BTN_LEFT : BTN_RIGHT;
|
||||
if (button == btn_resize) {
|
||||
edge = 0;
|
||||
edge |= cursor->cursor->x > cont->pending.x + cont->pending.width / 2 ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
||||
edge |= cursor->cursor->y > cont->pending.y + cont->pending.height / 2 ?
|
||||
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
||||
edge = 0;
|
||||
edge |= cursor->cursor->x > cont->pending.x + cont->pending.width / 2 ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
||||
edge |= cursor->cursor->y > cont->pending.y + cont->pending.height / 2 ?
|
||||
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
||||
|
||||
const char *image = NULL;
|
||||
if (edge == (WLR_EDGE_LEFT | WLR_EDGE_TOP)) {
|
||||
image = "nw-resize";
|
||||
} else if (edge == (WLR_EDGE_TOP | WLR_EDGE_RIGHT)) {
|
||||
image = "ne-resize";
|
||||
} else if (edge == (WLR_EDGE_RIGHT | WLR_EDGE_BOTTOM)) {
|
||||
image = "se-resize";
|
||||
} else if (edge == (WLR_EDGE_BOTTOM | WLR_EDGE_LEFT)) {
|
||||
image = "sw-resize";
|
||||
}
|
||||
cursor_set_image(seat->cursor, image, NULL);
|
||||
seat_set_focus_container(seat, cont);
|
||||
seatop_begin_resize_tiling(seat, cont, edge);
|
||||
return;
|
||||
const char *image = NULL;
|
||||
if (edge == (WLR_EDGE_LEFT | WLR_EDGE_TOP)) {
|
||||
image = "nw-resize";
|
||||
} else if (edge == (WLR_EDGE_TOP | WLR_EDGE_RIGHT)) {
|
||||
image = "ne-resize";
|
||||
} else if (edge == (WLR_EDGE_RIGHT | WLR_EDGE_BOTTOM)) {
|
||||
image = "se-resize";
|
||||
} else if (edge == (WLR_EDGE_BOTTOM | WLR_EDGE_LEFT)) {
|
||||
image = "sw-resize";
|
||||
}
|
||||
cursor_set_image(seat->cursor, image, NULL);
|
||||
seat_set_focus_container(seat, cont);
|
||||
seatop_begin_resize_tiling(seat, cont, edge);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle changing focus when clicking on a container
|
||||
@ -454,12 +456,10 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
|
||||
// Handle beginning floating move
|
||||
if (cont && is_floating_or_child && !is_fullscreen_or_child &&
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
||||
if (button == btn_move && (mod_pressed || on_titlebar)) {
|
||||
seatop_begin_move_floating(seat, container_toplevel_ancestor(cont));
|
||||
return;
|
||||
}
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED &&
|
||||
(mod_move_btn_pressed || titlebar_left_btn_pressed)) {
|
||||
seatop_begin_move_floating(seat, container_toplevel_ancestor(cont));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle beginning floating resize
|
||||
@ -473,9 +473,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
}
|
||||
|
||||
// Via mod+click
|
||||
uint32_t btn_resize = config->floating_mod_inverse ?
|
||||
BTN_LEFT : BTN_RIGHT;
|
||||
if (mod_pressed && button == btn_resize) {
|
||||
if (mod_resize_btn_pressed) {
|
||||
struct sway_container *floater = container_toplevel_ancestor(cont);
|
||||
edge = 0;
|
||||
edge |= cursor->cursor->x > floater->pending.x + floater->pending.width / 2 ?
|
||||
@ -489,18 +487,15 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
}
|
||||
|
||||
// Handle moving a tiling container
|
||||
if (config->tiling_drag && (mod_pressed || on_titlebar) &&
|
||||
if (config->tiling_drag && (mod_move_btn_pressed || titlebar_left_btn_pressed) &&
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating_or_child &&
|
||||
cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE &&
|
||||
button == (config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT)) {
|
||||
|
||||
cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) {
|
||||
// If moving a container by its title bar, use a threshold for the drag
|
||||
if (!mod_pressed && config->tiling_drag_threshold > 0) {
|
||||
seatop_begin_move_tiling_threshold(seat, cont);
|
||||
} else {
|
||||
seatop_begin_move_tiling(seat, cont);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -798,12 +793,28 @@ static void handle_pointer_axis(struct sway_seat *seat,
|
||||
|
||||
if (!handled) {
|
||||
wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec,
|
||||
event->orientation, scroll_factor * event->delta,
|
||||
event->orientation, scroll_factor * event->delta,
|
||||
roundf(scroll_factor * event->delta_discrete), event->source,
|
||||
event->relative_direction);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_tablet_tool_axis_scroll(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, struct wlr_tablet_tool_axis_scroll_event *event) {
|
||||
// FIXME: Do nothing except pass it to clients for now
|
||||
struct sway_input_device *input_device =
|
||||
event->tablet ? event->tablet->base.data : NULL;
|
||||
struct input_config *ic =
|
||||
input_device ? input_device_get_config(input_device) : NULL;
|
||||
float scroll_factor =
|
||||
(ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor;
|
||||
|
||||
wlr_tablet_v2_tablet_tool_notify_scroll(tool->tablet_v2_tool, event->time_msec,
|
||||
event->orientation, scroll_factor * event->delta,
|
||||
event->source,
|
||||
event->relative_direction);
|
||||
}
|
||||
|
||||
/*------------------------------------\
|
||||
* Functions used by gesture support /
|
||||
*----------------------------------*/
|
||||
@ -1131,6 +1142,7 @@ static const struct sway_seatop_impl seatop_impl = {
|
||||
.pointer_axis = handle_pointer_axis,
|
||||
.tablet_tool_tip = handle_tablet_tool_tip,
|
||||
.tablet_tool_motion = handle_tablet_tool_motion,
|
||||
.tablet_tool_axis_scroll = handle_tablet_tool_axis_scroll,
|
||||
.hold_begin = handle_hold_begin,
|
||||
.hold_end = handle_hold_end,
|
||||
.pinch_begin = handle_pinch_begin,
|
||||
|
@ -144,6 +144,22 @@ static void handle_pointer_axis(struct sway_seat *seat,
|
||||
event->relative_direction);
|
||||
}
|
||||
|
||||
static void handle_tablet_tool_axis_scroll(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, struct wlr_tablet_tool_axis_scroll_event *event) {
|
||||
struct sway_input_device *input_device =
|
||||
event->tablet ? event->tablet->base.data : NULL;
|
||||
struct input_config *ic =
|
||||
input_device ? input_device_get_config(input_device) : NULL;
|
||||
float scroll_factor =
|
||||
(ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor;
|
||||
|
||||
wlr_tablet_v2_tablet_tool_notify_scroll(tool->tablet_v2_tool, event->time_msec,
|
||||
event->orientation, scroll_factor * event->delta,
|
||||
event->source,
|
||||
event->relative_direction);
|
||||
seatop_begin_default(seat);
|
||||
}
|
||||
|
||||
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct wlr_input_device *device, uint32_t button,
|
||||
enum wl_pointer_button_state state) {
|
||||
@ -212,6 +228,7 @@ static const struct sway_seatop_impl seatop_impl = {
|
||||
.pointer_axis = handle_pointer_axis,
|
||||
.tablet_tool_tip = handle_tablet_tool_tip,
|
||||
.tablet_tool_motion = handle_tablet_tool_motion,
|
||||
.tablet_tool_axis_scroll = handle_tablet_tool_axis_scroll,
|
||||
.touch_motion = handle_touch_motion,
|
||||
.touch_up = handle_touch_up,
|
||||
.touch_down = handle_touch_down,
|
||||
|
@ -70,6 +70,7 @@
|
||||
#define SWAY_XDG_SHELL_VERSION 5
|
||||
#define SWAY_LAYER_SHELL_VERSION 4
|
||||
#define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
||||
#define SWAY_PRESENTATION_VERSION 2
|
||||
|
||||
bool allow_unsupported_gpu = false;
|
||||
|
||||
@ -327,7 +328,7 @@ bool server_init(struct sway_server *server) {
|
||||
wl_signal_add(&server->pointer_constraints->events.new_constraint,
|
||||
&server->pointer_constraint);
|
||||
|
||||
wlr_presentation_create(server->wl_display, server->backend);
|
||||
wlr_presentation_create(server->wl_display, server->backend, SWAY_PRESENTATION_VERSION);
|
||||
wlr_alpha_modifier_v1_create(server->wl_display);
|
||||
|
||||
server->output_manager_v1 =
|
||||
|
@ -349,7 +349,7 @@ void container_arrange_title_bar(struct sway_container *con) {
|
||||
h_padding = width - config->titlebar_h_padding - marks_buffer_width;
|
||||
}
|
||||
|
||||
h_padding = MAX(h_padding, 0);
|
||||
h_padding = MAX(h_padding, config->titlebar_h_padding);
|
||||
|
||||
int alloc_width = MIN((int)node->width,
|
||||
width - h_padding - config->titlebar_h_padding);
|
||||
@ -375,7 +375,7 @@ void container_arrange_title_bar(struct sway_container *con) {
|
||||
h_padding = config->titlebar_h_padding;
|
||||
}
|
||||
|
||||
h_padding = MAX(h_padding, 0);
|
||||
h_padding = MAX(h_padding, config->titlebar_h_padding);
|
||||
|
||||
int alloc_width = MIN((int) node->width,
|
||||
width - h_padding - config->titlebar_h_padding);
|
||||
|
Loading…
Reference in New Issue
Block a user