Compare commits

...

19 Commits

Author SHA1 Message Date
itycodes 41267dc124 wlroots submodule
4 weeks ago
itycodes c6ce7a1c35 Implement a murder command
4 weeks ago
itycodes 8dabd05195 Implementations of the screencopy extensions
4 weeks ago
itycodes a66f7f7b5d Merge branch 'master' of https://github.com/swaywm/sway
4 weeks ago
Kirill Primak 015e357fce desktop/output: chase wlroots private fields update
1 month ago
Kenny Levinsen a63027245a config/output: Remove remaining logs from queue_output_config
1 month ago
Kenny Levinsen 17ecb9eb1d config/output: Remove initial values in find_output_config
1 month ago
Kenny Levinsen af0d4a048a config/output: Always set all output fields on finalize
1 month ago
Kenny Levinsen 7e0c0dda42 config/output: Always set output states from config
1 month ago
Kenny Levinsen 7d93652105 config/output: Improve modeset state logging
1 month ago
Simon Ser 35d8adefc4 input/seatop_default: refactor move/resize button logic
1 month ago
Alexander Orzechowski 8363699f14 layer_shell: Restore sway 1.9 ordering
1 month ago
Alexander Orzechowski ce6b2db0f2 layer_shell: Arrange exclusive zone clients first
1 month ago
Jan Palus db76fefd0c trigger container update after disabling urgent in timer
1 month ago
Simon Ser dd063a0ef7 input/keyboard: add support for pointer keys
1 month ago
Simon Ser 17e2e52c6d server: check backend support for timelines
1 month ago
Furkan Sahin 7f1cd0b73b
input/mouse: bugfix button2 being interpreted as trying to move the container
2 months ago
ShootingStarDragons f855b0898b fix: sway crashes if switch to another workspace with surface when IME popup is shown
2 months ago
Kenny Levinsen c90cb37b2a Re-init renderer for all outputs on lost context
2 months ago

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "subprojects/wlroots"]
path = subprojects/wlroots
url = https://gitea.itycodes.org/itycodes/wlseeds

@ -150,6 +150,7 @@ sway_cmd cmd_input;
sway_cmd cmd_seat; sway_cmd cmd_seat;
sway_cmd cmd_ipc; sway_cmd cmd_ipc;
sway_cmd cmd_kill; sway_cmd cmd_kill;
sway_cmd cmd_murder;
sway_cmd cmd_layout; sway_cmd cmd_layout;
sway_cmd cmd_log_colors; sway_cmd cmd_log_colors;
sway_cmd cmd_mark; sway_cmd cmd_mark;

@ -106,7 +106,8 @@ struct sway_server {
struct wlr_content_type_manager_v1 *content_type_manager_v1; struct wlr_content_type_manager_v1 *content_type_manager_v1;
struct wlr_data_control_manager_v1 *data_control_manager_v1; struct wlr_data_control_manager_v1 *data_control_manager_v1;
struct wlr_screencopy_manager_v1 *screencopy_manager_v1; struct wlr_screencopy_manager_v1 *screencopy_manager_v1;
struct wlr_ext_screencopy_manager_v1 *ext_screencopy_manager_v1; struct wlr_ext_output_image_capture_source_manager_v1 *ext_output_image_source_manager_v1;
struct wlr_ext_image_copy_capture_manager_v1 *ext_image_copy_capture_manager_v1;
struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1; struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1;
struct wlr_security_context_manager_v1 *security_context_manager_v1; struct wlr_security_context_manager_v1 *security_context_manager_v1;

@ -272,6 +272,8 @@ void view_set_tiled(struct sway_view *view, bool tiled);
void view_close(struct sway_view *view); void view_close(struct sway_view *view);
void view_murder(struct sway_view *view);
void view_close_popups(struct sway_view *view); void view_close_popups(struct sway_view *view);
// view implementation // view implementation

@ -16,8 +16,8 @@ protocols = [
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', wl_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
wl_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml', wl_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml',
wl_protocol_dir / 'staging/ext-image-source/ext-image-source-v1.xml', wl_protocol_dir / 'staging/ext-image-capture-source/ext-image-capture-source-v1.xml',
wl_protocol_dir / 'staging/ext-screencopy/ext-screencopy-v1.xml', wl_protocol_dir / 'staging/ext-image-copy-capture/ext-image-copy-capture-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',

@ -0,0 +1 @@
Subproject commit 41849d3951c89dce619c6cc511de43005e4e2d12

@ -124,6 +124,7 @@ static const struct cmd_handler command_handlers[] = {
{ "mark", cmd_mark }, { "mark", cmd_mark },
{ "max_render_time", cmd_max_render_time }, { "max_render_time", cmd_max_render_time },
{ "move", cmd_move }, { "move", cmd_move },
{ "murder", cmd_murder },
{ "nop", cmd_nop }, { "nop", cmd_nop },
{ "opacity", cmd_opacity }, { "opacity", cmd_opacity },
{ "reload", cmd_reload }, { "reload", cmd_reload },

@ -0,0 +1,31 @@
#include "log.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "sway/commands.h"
static void close_container_iterator(struct sway_container *con, void *data) {
if (con->view) {
view_murder(con->view);
}
}
struct cmd_results *cmd_murder(int argc, char **argv) {
if (!root->outputs->length) {
return cmd_results_new(CMD_INVALID,
"Can't run this command while there's no outputs connected.");
}
struct sway_container *con = config->handler_context.container;
struct sway_workspace *ws = config->handler_context.workspace;
if (con) {
close_container_iterator(con, NULL);
container_for_each_child(con, close_container_iterator, NULL);
} else {
workspace_for_each_container(ws, close_container_iterator, NULL);
}
return cmd_results_new(CMD_SUCCESS, NULL);
}

@ -285,7 +285,6 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
mhz = mhz <= 0 ? INT_MAX : mhz; mhz = mhz <= 0 ? INT_MAX : mhz;
if (wl_list_empty(&output->modes) || custom) { 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, wlr_output_state_set_custom_mode(pending, width, height,
refresh_rate > 0 ? mhz : 0); refresh_rate > 0 ? mhz : 0);
return; return;
@ -305,10 +304,7 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
} }
} }
} }
if (best) { 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 {
best = wlr_output_preferred_mode(output); best = wlr_output_preferred_mode(output);
sway_log(SWAY_INFO, "Configured mode (%dx%d@%.3fHz) not available, " sway_log(SWAY_INFO, "Configured mode (%dx%d@%.3fHz) not available, "
"applying preferred mode (%dx%d@%.3fHz)", "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"); sway_log(SWAY_ERROR, "Modeline can only be set to DRM output");
return; 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); struct wlr_output_mode *mode = wlr_drm_connector_add_mode(output, drm_mode);
if (mode) { if (mode) {
wlr_output_state_set_mode(pending, 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_x = (double) width / (output->phys_width / MM_PER_INCH);
double dpi_y = (double) height / (output->phys_height / 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) { if (dpi_x <= HIDPI_DPI_LIMIT || dpi_y <= HIDPI_DPI_LIMIT) {
return 1; return 1;
} }
@ -427,78 +421,57 @@ static void queue_output_config(struct output_config *oc,
struct wlr_output *wlr_output = output->wlr_output; struct wlr_output *wlr_output = output->wlr_output;
if (output_config_is_disabling(oc)) { if (output_config_is_disabling(oc)) {
sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name);
wlr_output_state_set_enabled(pending, false); wlr_output_state_set_enabled(pending, false);
return; return;
} }
sway_log(SWAY_DEBUG, "Turning on output %s", wlr_output->name);
wlr_output_state_set_enabled(pending, true); wlr_output_state_set_enabled(pending, true);
if (oc && oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t) -1) { 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); set_modeline(wlr_output, pending, &oc->drm_mode);
} else if (oc && oc->width > 0 && oc->height > 0) { } 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, set_mode(wlr_output, pending, oc->width, oc->height,
oc->refresh_rate, oc->custom_mode == 1); oc->refresh_rate, oc->custom_mode == 1);
} else if (!wl_list_empty(&wlr_output->modes)) { } else if (!wl_list_empty(&wlr_output->modes)) {
sway_log(SWAY_DEBUG, "Set preferred mode");
struct wlr_output_mode *preferred_mode = struct wlr_output_mode *preferred_mode =
wlr_output_preferred_mode(wlr_output); wlr_output_preferred_mode(wlr_output);
wlr_output_state_set_mode(pending, preferred_mode); wlr_output_state_set_mode(pending, preferred_mode);
} }
if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) { if (oc && oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN) {
sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name,
sway_wl_output_subpixel_to_string(oc->subpixel));
wlr_output_state_set_subpixel(pending, oc->subpixel); 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) { if (oc && oc->transform >= 0) {
tr = oc->transform; wlr_output_state_set_transform(pending, oc->transform);
#if WLR_HAS_DRM_BACKEND #if WLR_HAS_DRM_BACKEND
} else if (wlr_output_is_drm(wlr_output)) { } else if (wlr_output_is_drm(wlr_output)) {
tr = wlr_drm_connector_get_panel_orientation(wlr_output); wlr_output_state_set_transform(pending,
sway_log(SWAY_DEBUG, "Auto-detected output transform: %d", tr); wlr_drm_connector_get_panel_orientation(wlr_output));
#endif #endif
} } else {
if (wlr_output->transform != tr) { wlr_output_state_set_transform(pending, WL_OUTPUT_TRANSFORM_NORMAL);
sway_log(SWAY_DEBUG, "Set %s transform to %d", wlr_output->name, tr);
wlr_output_state_set_transform(pending, tr);
} }
// Apply the scale last before the commit, because the scale auto-detection // Apply the scale after sorting out the mode, because the scale
// reads the pending output size // auto-detection reads the pending output size
float scale;
if (oc && oc->scale > 0) { if (oc && oc->scale > 0) {
scale = oc->scale;
// The factional-scale-v1 protocol uses increments of 120ths to send // 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 // the scale factor to the client. Adjust the scale so that we use the
// same value as the clients'. // same value as the clients'.
float adjusted_scale = round(scale * 120) / 120; wlr_output_state_set_scale(pending, round(oc->scale * 120) / 120);
if (scale != adjusted_scale) {
sway_log(SWAY_INFO, "Adjusting output scale from %f to %f",
scale, adjusted_scale);
scale = adjusted_scale;
}
} else { } else {
scale = compute_default_scale(wlr_output, pending); wlr_output_state_set_scale(pending,
sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale); compute_default_scale(wlr_output, pending));
}
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);
} }
if (oc && oc->adaptive_sync != -1 && wlr_output->adaptive_sync_supported) { if (wlr_output->adaptive_sync_supported) {
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name, if (oc && oc->adaptive_sync != -1) {
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);
} else {
wlr_output_state_set_adaptive_sync_enabled(pending, false);
}
} }
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) { if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
@ -513,6 +486,8 @@ static void queue_output_config(struct output_config *oc,
} else { } else {
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888); wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
} }
} else {
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
} }
} }
@ -531,9 +506,9 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
return true; return true;
} }
if (oc) {
enum scale_filter_mode scale_filter_old = output->scale_filter; enum scale_filter_mode scale_filter_old = output->scale_filter;
switch (oc->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_DEFAULT:
case SCALE_FILTER_SMART: case SCALE_FILTER_SMART:
output->scale_filter = ceilf(wlr_output->scale) == wlr_output->scale ? output->scale_filter = ceilf(wlr_output->scale) == wlr_output->scale ?
@ -541,7 +516,7 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
break; break;
case SCALE_FILTER_LINEAR: case SCALE_FILTER_LINEAR:
case SCALE_FILTER_NEAREST: case SCALE_FILTER_NEAREST:
output->scale_filter = oc->scale_filter; output->scale_filter = scale_filter_new;
break; break;
} }
if (scale_filter_old != output->scale_filter) { if (scale_filter_old != output->scale_filter) {
@ -549,7 +524,6 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
sway_output_scale_filter_to_string(output->scale_filter)); sway_output_scale_filter_to_string(output->scale_filter));
wlr_damage_ring_add_whole(&output->scene_output->damage_ring); wlr_damage_ring_add_whole(&output->scene_output->damage_ring);
} }
}
// Find position for it // Find position for it
if (oc && (oc->x != -1 || oc->y != -1)) { if (oc && (oc->x != -1 || oc->y != -1)) {
@ -571,25 +545,19 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
output_enable(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 && oc->set_color_transform) {
if (oc->color_transform) { if (oc->color_transform) {
wlr_color_transform_ref(oc->color_transform); wlr_color_transform_ref(oc->color_transform);
} }
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;
} else {
wlr_color_transform_unref(output->color_transform);
output->color_transform = NULL;
} }
if (oc && oc->allow_tearing >= 0) { output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0;
sway_log(SWAY_DEBUG, "Set %s allow tearing to %d", output->allow_tearing = oc && oc->allow_tearing > 0;
oc->name, oc->allow_tearing);
output->allow_tearing = oc->allow_tearing;
}
return true; return true;
} }
@ -605,15 +573,6 @@ static struct output_config *find_output_config_from_list(
return NULL; return NULL;
} }
// Set output defaults for the "base" configuration
result->enabled = 1;
result->power = 1;
result->scale = 0; // auto
result->subpixel = sway_output->detected_subpixel;
result->transform = WL_OUTPUT_TRANSFORM_NORMAL;
result->max_render_time = 0;
result->allow_tearing = 0;
char id[128]; char id[128];
output_get_identifier(id, sizeof(id), sway_output); output_get_identifier(id, sizeof(id), sway_output);
@ -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", sway_log(SWAY_DEBUG, " adaptive_sync: %s",
state->adaptive_sync_enabled ? "enabled": "disabled"); 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); 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; backend_state->output = cfg->output->wlr_output;
wlr_output_state_init(&backend_state->base); 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); 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; 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, 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; struct wlr_scene_node *node;
wl_list_for_each(node, &tree->children, link) { wl_list_for_each(node, &tree->children, link) {
struct sway_layer_surface *surface = scene_descriptor_try_get(node, 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; continue;
} }
if ((surface->scene->layer_surface->current.exclusive_zone > 0) != exclusive) {
continue;
}
wlr_scene_layer_surface_v1_configure(surface->scene, full_area, usable_area); 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); &usable_area.width, &usable_area.height);
const struct wlr_box full_area = usable_area; 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_overlay, true);
arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom); arrange_surface(output, &full_area, &usable_area, output->layers.shell_top, true);
arrange_surface(output, &full_area, &usable_area, output->layers.shell_top); arrange_surface(output, &full_area, &usable_area, output->layers.shell_bottom, true);
arrange_surface(output, &full_area, &usable_area, output->layers.shell_overlay); 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)) { if (!wlr_box_equal(&usable_area, &output->usable_area)) {
sway_log(SWAY_DEBUG, "Usable area changed, rearranging output"); 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) { struct wlr_scene_buffer *buffer) {
// if we are scaling down, we should always choose linear // if we are scaling down, we should always choose linear
if (buffer->dst_width > 0 && buffer->dst_height > 0 && ( if (buffer->dst_width > 0 && buffer->dst_height > 0 && (
buffer->dst_width < buffer->buffer_width || buffer->dst_width < buffer->WLR_PRIVATE.buffer_width ||
buffer->dst_height < buffer->buffer_height)) { buffer->dst_height < buffer->WLR_PRIVATE.buffer_height)) {
return WLR_SCALE_FILTER_BILINEAR; return WLR_SCALE_FILTER_BILINEAR;
} }

@ -4,6 +4,7 @@
#include <wlr/config.h> #include <wlr/config.h>
#include <wlr/backend/multi.h> #include <wlr/backend/multi.h>
#include <wlr/interfaces/wlr_keyboard.h> #include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_keyboard.h> #include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_keyboard_group.h> #include <wlr/types/wlr_keyboard_group.h>
#include <xkbcommon/xkbcommon-names.h> #include <xkbcommon/xkbcommon-names.h>
@ -267,6 +268,7 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
const xkb_keysym_t *pressed_keysyms, uint32_t modifiers, size_t keysyms_len) { const xkb_keysym_t *pressed_keysyms, uint32_t modifiers, size_t keysyms_len) {
for (size_t i = 0; i < keysyms_len; ++i) { for (size_t i = 0; i < keysyms_len; ++i) {
xkb_keysym_t keysym = pressed_keysyms[i]; xkb_keysym_t keysym = pressed_keysyms[i];
if (keysym >= XKB_KEY_XF86Switch_VT_1 && if (keysym >= XKB_KEY_XF86Switch_VT_1 &&
keysym <= XKB_KEY_XF86Switch_VT_12) { keysym <= XKB_KEY_XF86Switch_VT_12) {
#if WLR_HAS_SESSION #if WLR_HAS_SESSION
@ -282,6 +284,36 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
return false; return false;
} }
static bool keyboard_execute_pointer_keysyms(struct sway_keyboard *keyboard,
uint32_t time, const xkb_keysym_t *pressed_keysyms, size_t keysyms_len,
enum wl_keyboard_key_state state) {
struct sway_cursor *cursor = keyboard->seat_device->sway_seat->cursor;
for (size_t i = 0; i < keysyms_len; ++i) {
xkb_keysym_t keysym = pressed_keysyms[i];
uint32_t button = wlr_keyboard_keysym_to_pointer_button(keysym);
if (button != 0) {
dispatch_cursor_button(cursor, &keyboard->wlr->base, time, button,
(enum wl_pointer_button_state)state);
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
return true;
}
int dx, dy;
wlr_keyboard_keysym_to_pointer_motion(keysym, &dx, &dy);
if (state == WL_KEYBOARD_KEY_STATE_PRESSED && (dx != 0 || dy != 0)) {
dx *= 10;
dy *= 10;
pointer_motion(cursor, time, &keyboard->wlr->base, dx, dy, dx, dy);
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
return true;
}
}
return false;
}
/** /**
* Get keysyms and modifiers from the keyboard as xkb sees them. * Get keysyms and modifiers from the keyboard as xkb sees them.
* *
@ -507,6 +539,11 @@ static void handle_key_event(struct sway_keyboard *keyboard,
keyboard, keyinfo.raw_keysyms, keyinfo.raw_modifiers, keyboard, keyinfo.raw_keysyms, keyinfo.raw_modifiers,
keyinfo.raw_keysyms_len); keyinfo.raw_keysyms_len);
} }
if (!handled) {
handled = keyboard_execute_pointer_keysyms(keyboard, event->time_msec,
keyinfo.translated_keysyms, keyinfo.translated_keysyms_len,
event->state);
}
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) { if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
// If the pressed event was sent to a client and we have a focused // If the pressed event was sent to a client and we have a focused

@ -1094,6 +1094,7 @@ static void seat_send_unfocus(struct sway_node *node, struct sway_seat *seat) {
static int handle_urgent_timeout(void *data) { static int handle_urgent_timeout(void *data) {
struct sway_view *view = data; struct sway_view *view = data;
view_set_urgent(view, false); view_set_urgent(view, false);
container_update_itself_and_parents(view->container);
return 0; return 0;
} }

@ -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); struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; 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 // Handle mouse bindings
if (trigger_pointer_button_binding(seat, device, button, state, modifiers, if (trigger_pointer_button_binding(seat, device, button, state, modifiers,
on_titlebar, on_border, on_contents, on_workspace)) { on_titlebar, on_border, on_contents, on_workspace)) {
@ -403,12 +410,8 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
} }
// Handle tiling resize via mod // Handle tiling resize via mod
bool mod_pressed = modifiers & config->floating_mod; if (cont && !is_floating_or_child && mod_pressed && mod_resize_btn_pressed &&
if (cont && !is_floating_or_child && mod_pressed &&
state == WL_POINTER_BUTTON_STATE_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 = 0;
edge |= cursor->cursor->x > cont->pending.x + cont->pending.width / 2 ? edge |= cursor->cursor->x > cont->pending.x + cont->pending.width / 2 ?
WLR_EDGE_RIGHT : WLR_EDGE_LEFT; WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
@ -430,7 +433,6 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
seatop_begin_resize_tiling(seat, cont, edge); seatop_begin_resize_tiling(seat, cont, edge);
return; return;
} }
}
// Handle changing focus when clicking on a container // Handle changing focus when clicking on a container
if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) {
@ -454,13 +456,11 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle beginning floating move // Handle beginning floating move
if (cont && is_floating_or_child && !is_fullscreen_or_child && if (cont && is_floating_or_child && !is_fullscreen_or_child &&
state == WL_POINTER_BUTTON_STATE_PRESSED) { state == WL_POINTER_BUTTON_STATE_PRESSED &&
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT; (mod_move_btn_pressed || titlebar_left_btn_pressed)) {
if (button == btn_move && (mod_pressed || on_titlebar)) {
seatop_begin_move_floating(seat, container_toplevel_ancestor(cont)); seatop_begin_move_floating(seat, container_toplevel_ancestor(cont));
return; return;
} }
}
// Handle beginning floating resize // Handle beginning floating resize
if (cont && is_floating_or_child && !is_fullscreen_or_child && if (cont && is_floating_or_child && !is_fullscreen_or_child &&
@ -473,9 +473,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
} }
// Via mod+click // Via mod+click
uint32_t btn_resize = config->floating_mod_inverse ? if (mod_resize_btn_pressed) {
BTN_LEFT : BTN_RIGHT;
if (mod_pressed && button == btn_resize) {
struct sway_container *floater = container_toplevel_ancestor(cont); struct sway_container *floater = container_toplevel_ancestor(cont);
edge = 0; edge = 0;
edge |= cursor->cursor->x > floater->pending.x + floater->pending.width / 2 ? edge |= cursor->cursor->x > floater->pending.x + floater->pending.width / 2 ?
@ -489,7 +487,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
} }
// Handle moving a tiling container // 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 && state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating_or_child &&
cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) { cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) {
// If moving a container by its title bar, use a threshold for the drag // If moving a container by its title bar, use a threshold for the drag
@ -498,7 +496,6 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
} else { } else {
seatop_begin_move_tiling(seat, cont); seatop_begin_move_tiling(seat, cont);
} }
return; return;
} }

@ -454,6 +454,7 @@ static void handle_im_popup_surface_unmap(struct wl_listener *listener, void *da
struct sway_input_popup *popup = struct sway_input_popup *popup =
wl_container_of(listener, popup, popup_surface_unmap); wl_container_of(listener, popup, popup_surface_unmap);
scene_descriptor_destroy(&popup->scene_tree->node, SWAY_SCENE_DESC_POPUP);
// relative should already be freed as it should be a child of the just unmapped scene // relative should already be freed as it should be a child of the just unmapped scene
popup->desc.relative = NULL; popup->desc.relative = NULL;

@ -73,6 +73,7 @@ sway_sources = files(
'commands/inhibit_idle.c', 'commands/inhibit_idle.c',
'commands/kill.c', 'commands/kill.c',
'commands/mark.c', 'commands/mark.c',
'commands/murder.c',
'commands/max_render_time.c', 'commands/max_render_time.c',
'commands/opacity.c', 'commands/opacity.c',
'commands/include.c', 'commands/include.c',

@ -39,6 +39,9 @@ void *scene_descriptor_try_get(struct wlr_scene_node *node,
void scene_descriptor_destroy(struct wlr_scene_node *node, void scene_descriptor_destroy(struct wlr_scene_node *node,
enum sway_scene_descriptor_type type) { enum sway_scene_descriptor_type type) {
struct scene_descriptor *desc = scene_node_get_descriptor(node, type); struct scene_descriptor *desc = scene_node_get_descriptor(node, type);
if (!desc) {
return;
}
descriptor_destroy(desc); descriptor_destroy(desc);
} }

@ -19,8 +19,8 @@
#include <wlr/types/wlr_export_dmabuf_v1.h> #include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h> #include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
#include <wlr/types/wlr_foreign_toplevel_management_v1.h> #include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_ext_image_source_v1.h> #include <wlr/types/wlr_ext_image_capture_source_v1.h>
#include <wlr/types/wlr_ext_screencopy_v1.h> #include <wlr/types/wlr_ext_image_copy_capture_v1.h>
#include <wlr/types/wlr_fractional_scale_v1.h> #include <wlr/types/wlr_fractional_scale_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h> #include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle_notify_v1.h> #include <wlr/types/wlr_idle_notify_v1.h>
@ -109,7 +109,8 @@ static bool is_privileged(const struct wl_global *global) {
global == server.foreign_toplevel_manager->global || global == server.foreign_toplevel_manager->global ||
global == server.data_control_manager_v1->global || global == server.data_control_manager_v1->global ||
global == server.screencopy_manager_v1->global || global == server.screencopy_manager_v1->global ||
global == server.ext_screencopy_manager_v1->global || global == server.ext_image_copy_capture_manager_v1->global ||
global == server.ext_output_image_source_manager_v1->global ||
global == server.export_dmabuf_manager_v1->global || global == server.export_dmabuf_manager_v1->global ||
global == server.security_context_manager_v1->global || global == server.security_context_manager_v1->global ||
global == server.gamma_control_manager_v1->global || global == server.gamma_control_manager_v1->global ||
@ -208,8 +209,8 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) {
wlr_compositor_set_renderer(server->compositor, renderer); wlr_compositor_set_renderer(server->compositor, renderer);
for (int i = 0; i < root->outputs->length; ++i) { struct sway_output *output;
struct sway_output *output = root->outputs->items[i]; wl_list_for_each(output, &root->all_outputs, link) {
wlr_output_init_render(output->wlr_output, wlr_output_init_render(output->wlr_output,
server->allocator, server->renderer); server->allocator, server->renderer);
} }
@ -254,7 +255,8 @@ bool server_init(struct sway_server *server) {
} }
} }
if (wlr_renderer_get_drm_fd(server->renderer) >= 0 && if (wlr_renderer_get_drm_fd(server->renderer) >= 0 &&
server->renderer->features.timeline) { server->renderer->features.timeline &&
server->backend->features.timeline) {
wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1, wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1,
wlr_renderer_get_drm_fd(server->renderer)); wlr_renderer_get_drm_fd(server->renderer));
} }
@ -371,8 +373,8 @@ bool server_init(struct sway_server *server) {
server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display); server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display);
server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display); server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display);
server->ext_screencopy_manager_v1 = wlr_ext_screencopy_manager_v1_create(server->wl_display, 1); server->ext_output_image_source_manager_v1 = wlr_ext_output_image_capture_source_manager_v1_create(server->wl_display, 1);
wlr_ext_output_image_source_manager_v1_create(server->wl_display, 1); server->ext_image_copy_capture_manager_v1 = wlr_ext_image_copy_capture_manager_v1_create(server->wl_display, 1);
server->data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display); server->data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display);
server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display); server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display);
wlr_viewporter_create(server->wl_display); wlr_viewporter_create(server->wl_display);

@ -454,6 +454,11 @@ void view_close(struct sway_view *view) {
} }
} }
void view_murder(struct sway_view *view) {
struct wl_client *client = wl_resource_get_client(view->surface->resource);
wl_client_destroy(client);
}
void view_close_popups(struct sway_view *view) { void view_close_popups(struct sway_view *view) {
if (view->impl->close_popups) { if (view->impl->close_popups) {
view->impl->close_popups(view); view->impl->close_popups(view);

Loading…
Cancel
Save