itycodes 4 weeks ago
commit a66f7f7b5d

@ -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;
}

@ -4,6 +4,7 @@
#include <wlr/config.h>
#include <wlr/backend/multi.h>
#include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_keyboard_group.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) {
for (size_t i = 0; i < keysyms_len; ++i) {
xkb_keysym_t keysym = pressed_keysyms[i];
if (keysym >= XKB_KEY_XF86Switch_VT_1 &&
keysym <= XKB_KEY_XF86Switch_VT_12) {
#if WLR_HAS_SESSION
@ -282,6 +284,36 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
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.
*
@ -507,6 +539,11 @@ static void handle_key_event(struct sway_keyboard *keyboard,
keyboard, keyinfo.raw_keysyms, keyinfo.raw_modifiers,
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 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) {
struct sway_view *view = data;
view_set_urgent(view, false);
container_update_itself_and_parents(view->container);
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);
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;
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;
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;
}
// 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,7 +487,7 @@ 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) {
// 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 {
seatop_begin_move_tiling(seat, cont);
}
return;
}

@ -454,6 +454,7 @@ static void handle_im_popup_surface_unmap(struct wl_listener *listener, void *da
struct sway_input_popup *popup =
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
popup->desc.relative = NULL;

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

@ -208,8 +208,8 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) {
wlr_compositor_set_renderer(server->compositor, renderer);
for (int i = 0; i < root->outputs->length; ++i) {
struct sway_output *output = root->outputs->items[i];
struct sway_output *output;
wl_list_for_each(output, &root->all_outputs, link) {
wlr_output_init_render(output->wlr_output,
server->allocator, server->renderer);
}
@ -254,7 +254,8 @@ bool server_init(struct sway_server *server) {
}
}
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_renderer_get_drm_fd(server->renderer));
}

Loading…
Cancel
Save