1
1
Fork 0
mirror of https://github.com/swaywm/sway synced 2024-05-29 15:06:15 +02:00

Merge branch 'master' into workspace-critierion

This commit is contained in:
bonsaiiV 2024-05-01 11:45:29 +00:00 committed by GitHub
commit 8c84893de7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
118 changed files with 612 additions and 491 deletions

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809
#include <assert.h>
#include <cairo.h>
#include <errno.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "gesture.h"
#include <math.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200112L
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200112L
#include <limits.h>
#include <string.h>
#include <stdbool.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <fcntl.h>
#include <math.h>

View File

@ -291,6 +291,14 @@ struct output_config {
char *background_fallback;
};
/**
* An output config pre-matched to an output
*/
struct matched_output_config {
struct sway_output *output;
struct output_config *config;
};
/**
* Stores size of gaps for each side
*/
@ -680,20 +688,22 @@ const char *sway_output_scale_filter_to_string(enum scale_filter_mode scale_filt
struct output_config *new_output_config(const char *name);
void merge_output_config(struct output_config *dst, struct output_config *src);
bool apply_output_configs(struct matched_output_config *configs,
size_t configs_len, bool test_only);
bool apply_output_config(struct output_config *oc, struct sway_output *output);
void apply_all_output_configs(void);
bool test_output_config(struct output_config *oc, struct sway_output *output);
struct output_config *store_output_config(struct output_config *oc);
/**
* store_output_config stores a new output config. An output may be matched by
* three different config types, in order of precedence: Identifier, name and
* wildcard. When storing a config type of lower precedence, assume that the
* user wants the config to take immediate effect by superseding (clearing) the
* same values from higher presedence configuration.
*/
void store_output_config(struct output_config *oc);
struct output_config *find_output_config(struct sway_output *output);
void apply_output_config_to_outputs(struct output_config *oc);
void reset_outputs(void);
void free_output_config(struct output_config *oc);
bool spawn_swaybg(void);

View File

@ -114,7 +114,7 @@ void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
void dispatch_cursor_button(struct sway_cursor *cursor,
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
enum wlr_button_state state);
enum wl_pointer_button_state state);
void dispatch_cursor_axis(struct sway_cursor *cursor,
struct wlr_pointer_axis_event *event);

View File

@ -4,6 +4,7 @@
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/types/wlr_transient_seat_v1.h>
#include "sway/server.h"
#include "sway/config.h"
#include "list.h"
@ -24,6 +25,7 @@ struct sway_input_manager {
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
struct wlr_pointer_gestures_v1 *pointer_gestures;
struct wlr_transient_seat_manager_v1 *transient_seat_manager;
struct wl_listener new_input;
struct wl_listener inhibit_activate;
@ -31,6 +33,7 @@ struct sway_input_manager {
struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor;
struct wl_listener virtual_keyboard_new;
struct wl_listener virtual_pointer_new;
struct wl_listener transient_seat_create;
};
struct sway_input_manager *input_manager_create(struct sway_server *server);

View File

@ -17,7 +17,7 @@ struct sway_seat;
struct sway_seatop_impl {
void (*button)(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state);
enum wl_pointer_button_state state);
void (*pointer_motion)(struct sway_seat *seat, uint32_t time_msec);
void (*pointer_axis)(struct sway_seat *seat,
struct wlr_pointer_axis_event *event);
@ -124,6 +124,7 @@ struct sway_seat {
struct wl_listener start_drag;
struct wl_listener request_set_selection;
struct wl_listener request_set_primary_selection;
struct wl_listener destroy;
struct wl_list devices; // sway_seat_device::link
struct wl_list keyboard_groups; // sway_keyboard_group::link
@ -286,13 +287,13 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
struct sway_workspace *workspace);
void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
uint32_t button, enum wlr_button_state state);
uint32_t button, enum wl_pointer_button_state state);
void seat_consider_warp_to_focus(struct sway_seat *seat);
void seatop_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state);
enum wl_pointer_button_state state);
void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec);

View File

@ -50,7 +50,7 @@ struct sway_output {
enum wl_output_subpixel detected_subpixel;
enum scale_filter_mode scale_filter;
bool enabling, enabled;
bool enabled;
list_t *workspaces;
struct sway_output_state current;

View File

@ -46,6 +46,7 @@ struct sway_server {
struct wl_listener new_output;
struct wl_listener output_layout_change;
struct wl_listener renderer_lost;
struct wlr_idle_notifier_v1 *idle_notifier_v1;
struct sway_idle_inhibit_manager_v1 idle_inhibit_manager_v1;

View File

@ -192,6 +192,7 @@ struct sway_xdg_popup {
struct wl_listener surface_commit;
struct wl_listener new_popup;
struct wl_listener reposition;
struct wl_listener destroy;
};

View File

@ -14,6 +14,7 @@ project(
add_project_arguments(
[
'-DWLR_USE_UNSTABLE',
'-D_POSIX_C_SOURCE=200809L',
'-Wno-unused-parameter',
'-Wno-unused-result',

31
release.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh -eu
prev=$(git describe --tags --abbrev=0)
next=$(meson rewrite kwargs info project / 2>&1 >/dev/null | jq -r '.kwargs["project#/"].version')
case "$next" in
*-dev)
echo "This is a development version"
exit 1
;;
esac
if [ "$prev" = "$next" ]; then
echo "Version not bumped in meson.build"
exit 1
fi
if ! git diff-index --quiet HEAD -- meson.build; then
echo "meson.build not committed"
exit 1
fi
shortlog="$(git shortlog --no-merges "$prev..")"
(echo "sway $next"; echo ""; echo "$shortlog") | git tag "$next" -ase -F -
prefix=sway-$next
archive=$prefix.tar.gz
git archive --prefix="$prefix/" -o "$archive" "$next"
gpg --output "$archive".sig --detach-sig "$archive"
gh release create "sway $next" -t "$next" -n "" -d "$archive" "$archive.sig"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <string.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809
#include <stdio.h>
#include <string.h>
#include <strings.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <strings.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "config.h"
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <strings.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <strings.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "config.h"
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <libevdev/libevdev.h>
#include <linux/input-event-codes.h>
#include <string.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "gesture.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <strings.h>
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include <strings.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <strings.h>
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <errno.h>
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "sway/commands.h"
#include "util.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <wlr/interfaces/wlr_keyboard.h>
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/config.h"
#include "sway/commands.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <string.h>
#include "sway/commands.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
@ -770,15 +769,6 @@ static struct cmd_results *cmd_move_in_direction(
ipc_event_window(container, "move");
}
// Hack to re-focus container
seat_set_raw_focus(config->handler_context.seat, &new_ws->node);
seat_set_focus_container(config->handler_context.seat, container);
if (old_ws != new_ws) {
ipc_event_workspace(old_ws, new_ws, "focus");
workspace_detect_urgent(old_ws);
workspace_detect_urgent(new_ws);
}
container_end_mouse_operation(container);
return cmd_results_new(CMD_SUCCESS, NULL);

View File

@ -103,13 +103,13 @@ struct cmd_results *cmd_output(int argc, char **argv) {
bool background = output->background;
output = store_output_config(output);
store_output_config(output);
// If reloading, the output configs will be applied after reading the
// entire config and before the deferred commands so that an auto generated
// workspace name is not given to re-enabled outputs.
if (!config->reloading && !config->validating) {
apply_output_config_to_outputs(output);
apply_all_output_configs();
if (background) {
if (!spawn_swaybg()) {
return cmd_results_new(CMD_FAILURE,

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <libgen.h>
#include <stdio.h>
#include <string.h>

View File

@ -29,7 +29,7 @@ struct cmd_results *output_cmd_toggle(int argc, char **argv) {
config->handler_context.output_config->enabled = 1;
}
free(oc);
free_output_config(oc);
config->handler_context.leftovers.argc = argc;
config->handler_context.leftovers.argv = argv;
return NULL;

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <linux/input-event-codes.h>
#include <strings.h>
@ -85,12 +84,12 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) {
static struct cmd_results *press_or_release(struct sway_cursor *cursor,
char *action, char *button_str) {
enum wlr_button_state state;
enum wl_pointer_button_state state;
uint32_t button;
if (strcasecmp(action, "press") == 0) {
state = WLR_BUTTON_PRESSED;
state = WL_POINTER_BUTTON_STATE_PRESSED;
} else if (strcasecmp(action, "release") == 0) {
state = WLR_BUTTON_RELEASED;
state = WL_POINTER_BUTTON_STATE_RELEASED;
} else {
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
@ -105,16 +104,16 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor,
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN
|| button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) {
// Dispatch axis event
enum wlr_axis_orientation orientation =
enum wl_pointer_axis orientation =
(button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN)
? WLR_AXIS_ORIENTATION_VERTICAL
: WLR_AXIS_ORIENTATION_HORIZONTAL;
? WL_POINTER_AXIS_VERTICAL_SCROLL
: WL_POINTER_AXIS_HORIZONTAL_SCROLL;
double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT)
? -1 : 1;
struct wlr_pointer_axis_event event = {
.pointer = NULL,
.time_msec = 0,
.source = WLR_AXIS_SOURCE_WHEEL,
.source = WL_POINTER_AXIS_SOURCE_WHEEL,
.orientation = orientation,
.delta = delta * 15,
.delta_discrete = delta

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <limits.h>
#include <string.h>
#include <strings.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <string.h>
#include <strings.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <strings.h>
#include "config.h"
#include "log.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <limits.h>
#include <string.h>

View File

@ -1,3 +1,4 @@
#undef _POSIX_C_SOURCE
#define _XOPEN_SOURCE 700 // for realpath
#include <stdio.h>
#include <stdbool.h>
@ -36,19 +37,26 @@
struct sway_config *config = NULL;
static struct xkb_state *keysym_translation_state_create(
struct xkb_rule_names rules) {
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV);
struct xkb_rule_names rules, uint32_t context_flags) {
struct xkb_context *context = xkb_context_new(context_flags | XKB_CONTEXT_NO_SECURE_GETENV);
struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names(
context,
&rules,
XKB_KEYMAP_COMPILE_NO_FLAGS);
xkb_context_unref(context);
if (xkb_keymap == NULL) {
sway_log(SWAY_ERROR, "Failed to compile keysym translation XKB keymap");
return NULL;
}
return xkb_state_new(xkb_keymap);
}
static void keysym_translation_state_destroy(
struct xkb_state *state) {
if (state == NULL) {
return;
}
xkb_keymap_unref(xkb_state_get_keymap(state));
xkb_state_unref(state);
}
@ -336,8 +344,14 @@ static void config_defaults(struct sway_config *config) {
// The keysym to keycode translation
struct xkb_rule_names rules = {0};
config->keysym_translation_state =
keysym_translation_state_create(rules);
config->keysym_translation_state = keysym_translation_state_create(rules, 0);
if (config->keysym_translation_state == NULL) {
config->keysym_translation_state = keysym_translation_state_create(rules,
XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
}
if (config->keysym_translation_state == NULL) {
goto cleanup;
}
return;
cleanup:
@ -518,7 +532,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
}
sway_switch_retrigger_bindings_for_all();
reset_outputs();
apply_all_output_configs();
spawn_swaybg();
config->reloading = false;
@ -984,8 +998,12 @@ void translate_keysyms(struct input_config *input_config) {
struct xkb_rule_names rules = {0};
input_config_fill_rule_names(input_config, &rules);
config->keysym_translation_state =
keysym_translation_state_create(rules);
config->keysym_translation_state = keysym_translation_state_create(rules, 0);
if (config->keysym_translation_state == NULL) {
sway_log(SWAY_ERROR, "Failed to create keysym translation XKB state "
"for device '%s'", input_config->identifier);
return;
}
for (int i = 0; i < config->modes->length; ++i) {
struct sway_mode *mode = config->modes->items[i];

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <limits.h>
#include <float.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <drm_fourcc.h>
#include <stdbool.h>
@ -10,6 +9,7 @@
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_swapchain_manager.h>
#include "sway/config.h"
#include "sway/input/cursor.h"
#include "sway/output.h"
@ -79,7 +79,72 @@ struct output_config *new_output_config(const char *name) {
return oc;
}
void merge_output_config(struct output_config *dst, struct output_config *src) {
// supersede_output_config clears all fields in dst that were set in src
static void supersede_output_config(struct output_config *dst, struct output_config *src) {
if (src->enabled != -1) {
dst->enabled = -1;
}
if (src->width != -1) {
dst->width = -1;
}
if (src->height != -1) {
dst->height = -1;
}
if (src->x != -1) {
dst->x = -1;
}
if (src->y != -1) {
dst->y = -1;
}
if (src->scale != -1) {
dst->scale = -1;
}
if (src->scale_filter != SCALE_FILTER_DEFAULT) {
dst->scale_filter = SCALE_FILTER_DEFAULT;
}
if (src->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN) {
dst->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
}
if (src->refresh_rate != -1) {
dst->refresh_rate = -1;
}
if (src->custom_mode != -1) {
dst->custom_mode = -1;
}
if (src->drm_mode.type != (uint32_t) -1) {
dst->drm_mode.type = -1;
}
if (src->transform != -1) {
dst->transform = -1;
}
if (src->max_render_time != -1) {
dst->max_render_time = -1;
}
if (src->adaptive_sync != -1) {
dst->adaptive_sync = -1;
}
if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
dst->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
}
if (src->background) {
free(dst->background);
dst->background = NULL;
}
if (src->background_option) {
free(dst->background_option);
dst->background_option = NULL;
}
if (src->background_fallback) {
free(dst->background_fallback);
dst->background_fallback = NULL;
}
if (src->power != -1) {
dst->power = -1;
}
}
// merge_output_config sets all fields in dst that were set in src
static void merge_output_config(struct output_config *dst, struct output_config *src) {
if (src->enabled != -1) {
dst->enabled = src->enabled;
}
@ -142,94 +207,42 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
}
}
static void merge_wildcard_on_all(struct output_config *wildcard) {
for (int i = 0; i < config->output_configs->length; i++) {
struct output_config *oc = config->output_configs->items[i];
if (strcmp(wildcard->name, oc->name) != 0) {
sway_log(SWAY_DEBUG, "Merging output * config on %s", oc->name);
merge_output_config(oc, wildcard);
}
}
}
static void merge_id_on_name(struct output_config *oc) {
struct sway_output *output = all_output_by_name_or_id(oc->name);
if (output == NULL) {
return;
}
const char *name = output->wlr_output->name;
char id[128];
output_get_identifier(id, sizeof(id), output);
char *id_on_name = format_str("%s on %s", id, name);
if (!id_on_name) {
return;
}
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
if (i >= 0) {
sway_log(SWAY_DEBUG, "Merging on top of existing id on name config");
merge_output_config(config->output_configs->items[i], oc);
} else {
// If both a name and identifier config, exist generate an id on name
int ni = list_seq_find(config->output_configs, output_name_cmp, name);
int ii = list_seq_find(config->output_configs, output_name_cmp, id);
if ((ni >= 0 && ii >= 0) || (ni >= 0 && strcmp(oc->name, id) == 0)
|| (ii >= 0 && strcmp(oc->name, name) == 0)) {
struct output_config *ion_oc = new_output_config(id_on_name);
if (ni >= 0) {
merge_output_config(ion_oc, config->output_configs->items[ni]);
}
if (ii >= 0) {
merge_output_config(ion_oc, config->output_configs->items[ii]);
}
merge_output_config(ion_oc, oc);
list_add(config->output_configs, ion_oc);
sway_log(SWAY_DEBUG, "Generated id on name output config \"%s\""
" (enabled: %d) (%dx%d@%fHz position %d,%d scale %f "
"transform %d) (bg %s %s) (power %d) (max render time: %d)",
ion_oc->name, ion_oc->enabled, ion_oc->width, ion_oc->height,
ion_oc->refresh_rate, ion_oc->x, ion_oc->y, ion_oc->scale,
ion_oc->transform, ion_oc->background,
ion_oc->background_option, ion_oc->power,
ion_oc->max_render_time);
}
}
free(id_on_name);
}
struct output_config *store_output_config(struct output_config *oc) {
void store_output_config(struct output_config *oc) {
bool merged = false;
bool wildcard = strcmp(oc->name, "*") == 0;
if (wildcard) {
merge_wildcard_on_all(oc);
} else {
merge_id_on_name(oc);
struct sway_output *output = wildcard ? NULL : output_by_name_or_id(oc->name);
char id[128];
if (output) {
output_get_identifier(id, sizeof(id), output);
}
int i = list_seq_find(config->output_configs, output_name_cmp, oc->name);
if (i >= 0) {
sway_log(SWAY_DEBUG, "Merging on top of existing output config");
struct output_config *current = config->output_configs->items[i];
merge_output_config(current, oc);
free_output_config(oc);
oc = current;
} else if (!wildcard) {
sway_log(SWAY_DEBUG, "Adding non-wildcard output config");
i = list_seq_find(config->output_configs, output_name_cmp, "*");
if (i >= 0) {
sway_log(SWAY_DEBUG, "Merging on top of output * config");
struct output_config *current = new_output_config(oc->name);
merge_output_config(current, config->output_configs->items[i]);
merge_output_config(current, oc);
free_output_config(oc);
oc = current;
for (int i = 0; i < config->output_configs->length; i++) {
struct output_config *old = config->output_configs->items[i];
// If the old config matches the new config's name, regardless of
// whether it was name or identifier, merge on top of the existing
// config. If the new config is a wildcard, this also merges on top of
// old wildcard configs.
if (strcmp(old->name, oc->name) == 0) {
merge_output_config(old, oc);
merged = true;
continue;
}
// If the new config is a wildcard config we supersede all non-wildcard
// configs. Old wildcard configs have already been handled above.
if (wildcard) {
supersede_output_config(old, oc);
continue;
}
// If the new config matches an output's name, and the old config
// matches on that output's identifier, supersede it.
if (output && strcmp(old->name, id) == 0 &&
strcmp(oc->name, output->wlr_output->name) == 0) {
supersede_output_config(old, oc);
}
list_add(config->output_configs, oc);
} else {
// New wildcard config. Just add it
sway_log(SWAY_DEBUG, "Adding output * config");
list_add(config->output_configs, oc);
}
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
@ -240,7 +253,13 @@ struct output_config *store_output_config(struct output_config *oc) {
oc->transform, oc->background, oc->background_option, oc->power,
oc->max_render_time);
return oc;
// 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.
if (!merged) {
list_add(config->output_configs, oc);
} else {
free_output_config(oc);
}
}
static void set_mode(struct wlr_output *output, struct wlr_output_state *pending,
@ -504,31 +523,12 @@ static void queue_output_config(struct output_config *oc,
}
}
bool apply_output_config(struct output_config *oc, struct sway_output *output) {
static bool finalize_output_config(struct output_config *oc, struct sway_output *output) {
if (output == root->fallback_output) {
return false;
}
struct wlr_output *wlr_output = output->wlr_output;
// Flag to prevent the output mode event handler from calling us
output->enabling = (!oc || oc->enabled);
struct wlr_output_state pending = {0};
queue_output_config(oc, output, &pending);
sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
if (!wlr_output_commit_state(wlr_output, &pending)) {
// Failed to commit output changes, maybe the output is missing a CRTC.
// Leave the output disabled for now and try again when the output gets
// the mode we asked for.
sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name);
output->enabling = false;
return false;
}
output->enabling = false;
if (oc && !oc->enabled) {
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
if (output->enabled) {
@ -584,25 +584,9 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
output->max_render_time = oc->max_render_time;
}
// Reconfigure all devices, since input config may have been applied before
// this output came online, and some config items (like map_to_output) are
// dependent on an output being present.
input_manager_configure_all_input_mappings();
// Reconfigure the cursor images, since the scale may have changed.
input_manager_configure_xcursor();
return true;
}
bool test_output_config(struct output_config *oc, struct sway_output *output) {
if (output == root->fallback_output) {
return false;
}
struct wlr_output_state pending = {0};
queue_output_config(oc, output, &pending);
return wlr_output_test_state(output->wlr_output, &pending);
}
static void default_output_config(struct output_config *oc,
struct wlr_output *wlr_output) {
oc->enabled = 1;
@ -622,140 +606,167 @@ static void default_output_config(struct output_config *oc,
oc->max_render_time = 0;
}
static struct output_config *get_output_config(char *identifier,
struct sway_output *sway_output) {
// find_output_config returns a merged output_config containing all stored
// configuration that applies to the specified output.
struct output_config *find_output_config(struct sway_output *sway_output) {
const char *name = sway_output->wlr_output->name;
struct output_config *oc = NULL;
struct output_config *oc_id_on_name = NULL;
struct output_config *oc_name = NULL;
struct output_config *oc_id = NULL;
char *id_on_name = format_str("%s on %s", identifier, name);
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
if (i >= 0) {
oc_id_on_name = config->output_configs->items[i];
} else {
i = list_seq_find(config->output_configs, output_name_cmp, name);
if (i >= 0) {
oc_name = config->output_configs->items[i];
}
i = list_seq_find(config->output_configs, output_name_cmp, identifier);
if (i >= 0) {
oc_id = config->output_configs->items[i];
}
}
struct output_config *result = new_output_config("temp");
struct output_config *result = new_output_config(name);
if (config->reloading) {
default_output_config(result, sway_output->wlr_output);
}
if (oc_id_on_name) {
// Already have an identifier on name config, use that
free(result->name);
result->name = strdup(id_on_name);
merge_output_config(result, oc_id_on_name);
} else if (oc_name && oc_id) {
// Generate a config named `<identifier> on <name>` which contains a
// merged copy of the identifier on name. This will make sure that both
// identifier and name configs are respected, with identifier getting
// priority
struct output_config *temp = new_output_config(id_on_name);
merge_output_config(temp, oc_name);
merge_output_config(temp, oc_id);
list_add(config->output_configs, temp);
free(result->name);
result->name = strdup(id_on_name);
merge_output_config(result, temp);
char id[128];
output_get_identifier(id, sizeof(id), sway_output);
sway_log(SWAY_DEBUG, "Generated output config \"%s\" (enabled: %d)"
" (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)"
" (power %d) (max render time: %d)", result->name, result->enabled,
result->width, result->height, result->refresh_rate,
result->x, result->y, result->scale, result->transform,
result->background, result->background_option, result->power,
result->max_render_time);
} else if (oc_name) {
// No identifier config, just return a copy of the name config
free(result->name);
result->name = strdup(name);
merge_output_config(result, oc_name);
} else if (oc_id) {
// No name config, just return a copy of the identifier config
free(result->name);
result->name = strdup(identifier);
merge_output_config(result, oc_id);
} else {
i = list_seq_find(config->output_configs, output_name_cmp, "*");
if (i >= 0) {
// No name or identifier config, but there is a wildcard config
free(result->name);
result->name = strdup("*");
merge_output_config(result, config->output_configs->items[i]);
} else if (!config->reloading) {
// No name, identifier, or wildcard config. Since we are not
// reloading with defaults, the output config will be empty, so
// just return NULL
free_output_config(result);
result = NULL;
}
int i;
bool match = false;
if ((i = list_seq_find(config->output_configs, output_name_cmp, "*")) >= 0) {
match = true;
oc = config->output_configs->items[i];
merge_output_config(result, oc);
}
if ((i = list_seq_find(config->output_configs, output_name_cmp, name)) >= 0) {
match = true;
oc = config->output_configs->items[i];
merge_output_config(result, oc);
}
if ((i = list_seq_find(config->output_configs, output_name_cmp, id)) >= 0) {
match = true;
oc = config->output_configs->items[i];
merge_output_config(result, oc);
}
if (!match && !config->reloading) {
// No name, identifier, or wildcard config. Since we are not
// reloading with defaults, the output config will be empty, so
// just return NULL
free_output_config(result);
return NULL;
}
free(id_on_name);
return result;
}
struct output_config *find_output_config(struct sway_output *output) {
char id[128];
output_get_identifier(id, sizeof(id), output);
return get_output_config(id, output);
}
bool apply_output_configs(struct matched_output_config *configs,
size_t configs_len, bool test_only) {
struct wlr_backend_output_state *states = calloc(configs_len, sizeof(*states));
if (!states) {
return false;
}
void apply_output_config_to_outputs(struct output_config *oc) {
// Try to find the output container and apply configuration now. If
// this is during startup then there will be no container and config
// will be applied during normal "new output" event from wlroots.
bool wildcard = strcmp(oc->name, "*") == 0;
struct sway_output *sway_output, *tmp;
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
if (output_match_name_or_id(sway_output, oc->name)) {
char id[128];
output_get_identifier(id, sizeof(id), sway_output);
struct output_config *current = get_output_config(id, sway_output);
if (!current) {
// No stored output config matched, apply oc directly
sway_log(SWAY_DEBUG, "Applying oc directly");
current = new_output_config(oc->name);
merge_output_config(current, oc);
}
apply_output_config(current, sway_output);
free_output_config(current);
sway_log(SWAY_DEBUG, "Committing %zd outputs", configs_len);
for (size_t idx = 0; idx < configs_len; idx++) {
struct matched_output_config *cfg = &configs[idx];
struct wlr_backend_output_state *backend_state = &states[idx];
if (!wildcard) {
// Stop looking if the output config isn't applicable to all
// outputs
break;
}
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);
}
struct wlr_output_swapchain_manager swapchain_mgr;
wlr_output_swapchain_manager_init(&swapchain_mgr, server.backend);
bool ok = wlr_output_swapchain_manager_prepare(&swapchain_mgr, states, configs_len);
if (!ok) {
sway_log(SWAY_ERROR, "Swapchain prepare failed");
goto out;
}
if (test_only) {
// The swapchain manager already did a test for us
goto out;
}
for (size_t idx = 0; idx < configs_len; idx++) {
struct matched_output_config *cfg = &configs[idx];
struct wlr_backend_output_state *backend_state = &states[idx];
struct wlr_scene_output_state_options opts = {
.swapchain = wlr_output_swapchain_manager_get_swapchain(
&swapchain_mgr, backend_state->output),
};
struct wlr_scene_output *scene_output = cfg->output->scene_output;
struct wlr_output_state *state = &backend_state->base;
if (!wlr_scene_output_build_state(scene_output, state, &opts)) {
sway_log(SWAY_ERROR, "Building output state for '%s' failed",
backend_state->output->name);
goto out;
}
}
ok = wlr_backend_commit(server.backend, states, configs_len);
if (!ok) {
sway_log(SWAY_ERROR, "Backend commit failed");
goto out;
}
sway_log(SWAY_DEBUG, "Commit of %zd outputs succeeded", configs_len);
wlr_output_swapchain_manager_apply(&swapchain_mgr);
for (size_t idx = 0; idx < configs_len; idx++) {
struct matched_output_config *cfg = &configs[idx];
sway_log(SWAY_DEBUG, "Finalizing config for %s",
cfg->output->wlr_output->name);
finalize_output_config(cfg->config, cfg->output);
}
out:
wlr_output_swapchain_manager_finish(&swapchain_mgr);
for (size_t idx = 0; idx < configs_len; idx++) {
struct wlr_backend_output_state *backend_state = &states[idx];
wlr_output_state_finish(&backend_state->base);
}
free(states);
// Reconfigure all devices, since input config may have been applied before
// this output came online, and some config items (like map_to_output) are
// dependent on an output being present.
input_manager_configure_all_input_mappings();
// Reconfigure the cursor images, since the scale may have changed.
input_manager_configure_xcursor();
struct sway_seat *seat;
wl_list_for_each(seat, &server.input->seats, link) {
wlr_seat_pointer_notify_clear_focus(seat->wlr_seat);
cursor_rebase(seat->cursor);
}
return ok;
}
void reset_outputs(void) {
struct output_config *oc = NULL;
int i = list_seq_find(config->output_configs, output_name_cmp, "*");
if (i >= 0) {
oc = config->output_configs->items[i];
} else {
oc = store_output_config(new_output_config("*"));
void apply_all_output_configs(void) {
size_t configs_len = wl_list_length(&root->all_outputs);
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
if (!configs) {
return;
}
apply_output_config_to_outputs(oc);
int config_idx = 0;
struct sway_output *sway_output;
wl_list_for_each(sway_output, &root->all_outputs, link) {
if (sway_output == root->fallback_output) {
configs_len--;
continue;
}
struct matched_output_config *config = &configs[config_idx++];
config->output = sway_output;
config->config = find_output_config(sway_output);
}
apply_output_configs(configs, configs_len, false);
for (size_t idx = 0; idx < configs_len; idx++) {
struct matched_output_config *cfg = &configs[idx];
free_output_config(cfg->config);
}
free(configs);
}
void free_output_config(struct output_config *oc) {

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <limits.h>
#include <stdlib.h>
#include <string.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include <wlr/types/wlr_xdg_activation_v1.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <stdlib.h>
#include <strings.h>
@ -184,7 +183,15 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer,
}
}
static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output) {
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)) {
return WLR_SCALE_FILTER_BILINEAR;
}
switch (output->scale_filter) {
case SCALE_FILTER_LINEAR:
return WLR_SCALE_FILTER_BILINEAR;
@ -213,7 +220,7 @@ static void output_configure_scene(struct sway_output *output,
// hack: don't call the scene setter because that will damage all outputs
// We don't want to damage outputs that aren't our current output that
// we're configuring
buffer->filter_mode = get_scale_filter(output);
buffer->filter_mode = get_scale_filter(output, buffer);
wlr_scene_buffer_set_opacity(buffer, opacity);
} else if (node->type == WLR_SCENE_NODE_TREE) {
@ -514,9 +521,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
sway_session_lock_add_output(server->session_lock.lock, output);
}
struct output_config *oc = find_output_config(output);
apply_output_config(oc, output);
free_output_config(oc);
apply_all_output_configs();
transaction_commit_dirty();
@ -545,63 +550,88 @@ void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
wlr_output_schedule_frame(output->wlr_output);
}
static struct output_config *output_config_for_config_head(
struct wlr_output_configuration_head_v1 *config_head,
struct sway_output *output) {
struct output_config *oc = new_output_config(output->wlr_output->name);
oc->enabled = config_head->state.enabled;
if (!oc->enabled) {
return oc;
}
if (config_head->state.mode != NULL) {
struct wlr_output_mode *mode = config_head->state.mode;
oc->width = mode->width;
oc->height = mode->height;
oc->refresh_rate = mode->refresh / 1000.f;
} else {
oc->width = config_head->state.custom_mode.width;
oc->height = config_head->state.custom_mode.height;
oc->refresh_rate =
config_head->state.custom_mode.refresh / 1000.f;
}
oc->x = config_head->state.x;
oc->y = config_head->state.y;
oc->transform = config_head->state.transform;
oc->scale = config_head->state.scale;
oc->adaptive_sync = config_head->state.adaptive_sync_enabled;
return oc;
}
static void output_manager_apply(struct sway_server *server,
struct wlr_output_configuration_v1 *config, bool test_only) {
// TODO: perform atomic tests on the whole backend atomically
size_t configs_len = wl_list_length(&root->all_outputs);
struct matched_output_config *configs = calloc(configs_len, sizeof(*configs));
if (!configs) {
return;
}
struct wlr_output_configuration_head_v1 *config_head;
// First disable outputs we need to disable
bool ok = true;
wl_list_for_each(config_head, &config->heads, link) {
struct wlr_output *wlr_output = config_head->state.output;
struct sway_output *output = wlr_output->data;
if (!output->enabled || config_head->state.enabled) {
int config_idx = 0;
struct sway_output *sway_output;
wl_list_for_each(sway_output, &root->all_outputs, link) {
if (sway_output == root->fallback_output) {
configs_len--;
continue;
}
struct output_config *oc = new_output_config(output->wlr_output->name);
oc->enabled = false;
if (test_only) {
ok &= test_output_config(oc, output);
} else {
oc = store_output_config(oc);
ok &= apply_output_config(oc, output);
struct matched_output_config *cfg = &configs[config_idx++];
cfg->output = sway_output;
struct wlr_output_configuration_head_v1 *config_head;
wl_list_for_each(config_head, &config->heads, link) {
if (config_head->state.output == sway_output->wlr_output) {
cfg->config = output_config_for_config_head(config_head, sway_output);
break;
}
}
if (!cfg->config) {
cfg->config = find_output_config(sway_output);
}
}
// Then enable outputs that need to
wl_list_for_each(config_head, &config->heads, link) {
struct wlr_output *wlr_output = config_head->state.output;
struct sway_output *output = wlr_output->data;
if (!config_head->state.enabled) {
continue;
}
struct output_config *oc = new_output_config(output->wlr_output->name);
oc->enabled = true;
if (config_head->state.mode != NULL) {
struct wlr_output_mode *mode = config_head->state.mode;
oc->width = mode->width;
oc->height = mode->height;
oc->refresh_rate = mode->refresh / 1000.f;
} else {
oc->width = config_head->state.custom_mode.width;
oc->height = config_head->state.custom_mode.height;
oc->refresh_rate =
config_head->state.custom_mode.refresh / 1000.f;
}
oc->x = config_head->state.x;
oc->y = config_head->state.y;
oc->transform = config_head->state.transform;
oc->scale = config_head->state.scale;
oc->adaptive_sync = config_head->state.adaptive_sync_enabled;
bool ok = apply_output_configs(configs, configs_len, test_only);
for (size_t idx = 0; idx < configs_len; idx++) {
struct matched_output_config *cfg = &configs[idx];
if (test_only) {
ok &= test_output_config(oc, output);
// Only store new configs for successful non-test commits. Old configs,
// test-only and failed commits just get freed.
bool store_config = false;
if (!test_only && ok) {
struct wlr_output_configuration_head_v1 *config_head;
wl_list_for_each(config_head, &config->heads, link) {
if (config_head->state.output == cfg->output->wlr_output) {
store_config = true;
break;
}
}
}
if (store_config) {
store_output_config(cfg->config);
} else {
oc = store_output_config(oc);
ok &= apply_output_config(oc, output);
free_output_config(cfg->config);
}
}
free(configs);
if (ok) {
wlr_output_configuration_v1_send_succeeded(config);
@ -645,6 +675,6 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
oc->power = 1;
break;
}
oc = store_output_config(oc);
apply_output_config(oc, output);
store_output_config(oc);
apply_all_output_configs();
}

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 199309L
#include <float.h>
#include <stdbool.h>
#include <stdlib.h>
@ -36,6 +35,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) {
wl_list_remove(&popup->new_popup.link);
wl_list_remove(&popup->destroy.link);
wl_list_remove(&popup->surface_commit.link);
wl_list_remove(&popup->reposition.link);
wlr_scene_node_destroy(&popup->scene_tree->node);
free(popup);
}
@ -71,6 +71,11 @@ static void popup_handle_surface_commit(struct wl_listener *listener, void *data
}
}
static void popup_handle_reposition(struct wl_listener *listener, void *data) {
struct sway_xdg_popup *popup = wl_container_of(listener, popup, reposition);
popup_unconstrain(popup);
}
static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup,
struct sway_view *view, struct wlr_scene_tree *parent) {
struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
@ -117,6 +122,8 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup,
popup->surface_commit.notify = popup_handle_surface_commit;
wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup);
popup->new_popup.notify = popup_handle_new_popup;
wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
popup->reposition.notify = popup_handle_reposition;
wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
popup->destroy.notify = popup_handle_destroy;
@ -282,6 +289,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
}
// XXX: https://github.com/swaywm/sway/issues/2176
wlr_xdg_surface_schedule_configure(xdg_surface);
// TODO: wlr_xdg_toplevel_set_bounds()
return;
}
@ -567,4 +575,7 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base);
xdg_toplevel->base->data = xdg_shell_view;
wlr_xdg_toplevel_set_wm_capabilities(xdg_toplevel,
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
}

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 199309L
#include <float.h>
#include <stdbool.h>
#include <stdlib.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <math.h>
#include <libevdev/libevdev.h>
@ -244,7 +243,7 @@ static enum sway_input_idle_source idle_source_from_device(
return IDLE_SOURCE_POINTER;
case WLR_INPUT_DEVICE_TOUCH:
return IDLE_SOURCE_TOUCH;
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
return IDLE_SOURCE_TABLET_TOOL;
case WLR_INPUT_DEVICE_TABLET_PAD:
return IDLE_SOURCE_TABLET_PAD;
@ -357,7 +356,7 @@ static void handle_pointer_motion_absolute(
void dispatch_cursor_button(struct sway_cursor *cursor,
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
if (time_msec == 0) {
time_msec = get_current_time_msec();
}
@ -369,7 +368,7 @@ static void handle_pointer_button(struct wl_listener *listener, void *data) {
struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
struct wlr_pointer_button_event *event = data;
if (event->state == WLR_BUTTON_PRESSED) {
if (event->state == WL_POINTER_BUTTON_STATE_PRESSED) {
cursor->pressed_button_count++;
} else {
if (cursor->pressed_button_count > 0) {
@ -431,7 +430,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
if (cursor->pointer_touch_id == cursor->seat->touch_id) {
cursor->pointer_touch_up = true;
dispatch_cursor_button(cursor, &event->touch->base,
event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
}
} else {
seatop_touch_up(seat, event);
@ -449,7 +448,7 @@ static void handle_touch_cancel(struct wl_listener *listener, void *data) {
if (cursor->pointer_touch_id == cursor->seat->touch_id) {
cursor->pointer_touch_up = true;
dispatch_cursor_button(cursor, &event->touch->base,
event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
}
} else {
seatop_touch_cancel(seat, event);
@ -519,7 +518,7 @@ static void apply_mapping_from_region(struct wlr_input_device *device,
double x1 = region->x1, x2 = region->x2;
double y1 = region->y1, y2 = region->y2;
if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET) {
struct wlr_tablet *tablet = wlr_tablet_from_input_device(device);
if (tablet->width_mm == 0 || tablet->height_mm == 0) {
return;
@ -662,7 +661,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
event->state == WLR_TABLET_TOOL_TIP_UP) {
cursor->simulating_pointer_from_tool_tip = false;
dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec,
BTN_LEFT, WLR_BUTTON_RELEASED);
BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
} else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) {
// If we started holding the tool tip down on a surface that accepts
@ -674,7 +673,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
} else {
cursor->simulating_pointer_from_tool_tip = true;
dispatch_cursor_button(cursor, &event->tablet->base,
event->time_msec, BTN_LEFT, WLR_BUTTON_PRESSED);
event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
}
} else {
@ -777,13 +776,13 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
case WLR_BUTTON_PRESSED:
if (cursor->tool_buttons == 0) {
dispatch_cursor_button(cursor, &event->tablet->base,
event->time_msec, BTN_RIGHT, event->state);
event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_PRESSED);
}
break;
case WLR_BUTTON_RELEASED:
if (cursor->tool_buttons <= 1) {
dispatch_cursor_button(cursor, &event->tablet->base,
event->time_msec, BTN_RIGHT, event->state);
event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_RELEASED);
}
break;
}

View File

@ -1,9 +1,10 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <wlr/config.h>
#include <wlr/backend/libinput.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
@ -66,8 +67,15 @@ struct sway_seat *input_manager_sway_seat_from_wlr_seat(struct wlr_seat *wlr_sea
}
char *input_device_get_identifier(struct wlr_input_device *device) {
int vendor = device->vendor;
int product = device->product;
int vendor = 0, product = 0;
#if WLR_HAS_LIBINPUT_BACKEND
if (wlr_input_device_is_libinput(device)) {
struct libinput_device *libinput_dev = wlr_libinput_get_device_handle(device);
vendor = libinput_device_get_id_vendor(libinput_dev);
product = libinput_device_get_id_product(libinput_dev);
}
#endif
char *name = strdup(device->name ? device->name : "");
strip_whitespace(name);
@ -112,7 +120,7 @@ const char *input_device_get_type(struct sway_input_device *device) {
return "keyboard";
case WLR_INPUT_DEVICE_TOUCH:
return "touch";
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
return "tablet_tool";
case WLR_INPUT_DEVICE_TABLET_PAD:
return "tablet_pad";
@ -425,6 +433,20 @@ void handle_virtual_pointer(struct wl_listener *listener, void *data) {
}
}
static void handle_transient_seat_manager_create_seat(
struct wl_listener *listener, void *data) {
struct wlr_transient_seat_v1 *transient_seat = data;
static uint64_t i;
char name[256];
snprintf(name, sizeof(name), "transient-%"PRIx64, i++);
struct sway_seat *seat = seat_create(name);
if (seat && seat->wlr_seat) {
wlr_transient_seat_v1_ready(transient_seat, seat->wlr_seat);
} else {
wlr_transient_seat_v1_deny(transient_seat);
}
}
struct sway_input_manager *input_manager_create(struct sway_server *server) {
struct sway_input_manager *input =
calloc(1, sizeof(struct sway_input_manager));
@ -460,6 +482,15 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
input->pointer_gestures = wlr_pointer_gestures_v1_create(server->wl_display);
input->transient_seat_manager =
wlr_transient_seat_manager_v1_create(server->wl_display);
assert(input->transient_seat_manager);
input->transient_seat_create.notify =
handle_transient_seat_manager_create_seat;
wl_signal_add(&input->transient_seat_manager->events.create_seat,
&input->transient_seat_create);
return input;
}

View File

@ -32,6 +32,7 @@ static struct modifier_key {
{ XKB_MOD_NAME_NUM, WLR_MODIFIER_MOD2 },
{ "Mod3", WLR_MODIFIER_MOD3 },
{ XKB_MOD_NAME_LOGO, WLR_MODIFIER_LOGO },
{ "Super", WLR_MODIFIER_LOGO },
{ "Mod5", WLR_MODIFIER_MOD5 },
};

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <linux/input-event-codes.h>
#include <string.h>
@ -68,6 +67,12 @@ static void seat_node_destroy(struct sway_seat_node *seat_node) {
}
void seat_destroy(struct sway_seat *seat) {
wlr_seat_destroy(seat->wlr_seat);
}
static void handle_seat_destroy(struct wl_listener *listener, void *data) {
struct sway_seat *seat = wl_container_of(listener, seat, destroy);
if (seat == config->handler_context.seat) {
config->handler_context.seat = input_manager_get_default_seat();
}
@ -88,7 +93,7 @@ void seat_destroy(struct sway_seat *seat) {
wl_list_remove(&seat->request_set_selection.link);
wl_list_remove(&seat->request_set_primary_selection.link);
wl_list_remove(&seat->link);
wlr_seat_destroy(seat->wlr_seat);
wl_list_remove(&seat->destroy.link);
for (int i = 0; i < seat->deferred_bindings->length; i++) {
free_sway_binding(seat->deferred_bindings->items[i]);
}
@ -535,6 +540,9 @@ struct sway_seat *seat_create(const char *seat_name) {
return NULL;
}
seat->destroy.notify = handle_seat_destroy;
wl_signal_add(&seat->wlr_seat->events.destroy, &seat->destroy);
seat->idle_inhibit_sources = seat->idle_wake_sources =
IDLE_SOURCE_KEYBOARD |
IDLE_SOURCE_POINTER |
@ -608,7 +616,7 @@ static void seat_update_capabilities(struct sway_seat *seat) {
case WLR_INPUT_DEVICE_TOUCH:
caps |= WL_SEAT_CAPABILITY_TOUCH;
break;
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
caps |= WL_SEAT_CAPABILITY_POINTER;
break;
case WLR_INPUT_DEVICE_SWITCH:
@ -666,7 +674,7 @@ static const char *get_builtin_output_name(void) {
static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) {
switch (seat_device->input_device->wlr_device->type) {
case WLR_INPUT_DEVICE_TOUCH:
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
return true;
default:
return false;
@ -681,7 +689,7 @@ static void seat_apply_input_mapping(struct sway_seat *seat,
switch (sway_device->input_device->wlr_device->type) {
case WLR_INPUT_DEVICE_POINTER:
case WLR_INPUT_DEVICE_TOUCH:
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
break;
default:
return; // these devices don't support mappings
@ -874,7 +882,7 @@ void seat_configure_device(struct sway_seat *seat,
case WLR_INPUT_DEVICE_TOUCH:
seat_configure_touch(seat, seat_device);
break;
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
seat_configure_tablet_tool(seat, seat_device);
break;
case WLR_INPUT_DEVICE_TABLET_PAD:
@ -913,7 +921,7 @@ void seat_reset_device(struct sway_seat *seat,
case WLR_INPUT_DEVICE_TOUCH:
seat_reset_input_config(seat, seat_device);
break;
case WLR_INPUT_DEVICE_TABLET_TOOL:
case WLR_INPUT_DEVICE_TABLET:
seat_reset_input_config(seat, seat_device);
break;
case WLR_INPUT_DEVICE_TABLET_PAD:
@ -1521,7 +1529,7 @@ struct seat_config *seat_get_config_by_name(const char *name) {
}
void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
uint32_t button, enum wlr_button_state state) {
uint32_t button, enum wl_pointer_button_state state) {
seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat,
time_msec, button, state);
}
@ -1558,7 +1566,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con) {
void seatop_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
if (seat->seatop_impl->button) {
seat->seatop_impl->button(seat, time_msec, device, button, state);
}

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <float.h>
#include <libevdev/libevdev.h>
#include <wlr/types/wlr_cursor.h>
@ -291,7 +290,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
static bool trigger_pointer_button_binding(struct sway_seat *seat,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state, uint32_t modifiers,
enum wl_pointer_button_state state, uint32_t modifiers,
bool on_titlebar, bool on_border, bool on_contents, bool on_workspace) {
// We can reach this for non-pointer devices if we're currently emulating
// pointer input for one. Emulated input should not trigger bindings. The
@ -305,7 +304,7 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat,
char *device_identifier = device ? input_device_get_identifier(device)
: strdup("*");
struct sway_binding *binding = NULL;
if (state == WLR_BUTTON_PRESSED) {
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
state_add_button(e, button);
binding = get_active_mouse_binding(e,
config->current_mode->mouse_bindings, modifiers, false,
@ -330,7 +329,7 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat,
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
struct sway_cursor *cursor = seat->cursor;
// Determine what's under the cursor
@ -363,7 +362,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle clicking an empty workspace
if (node && node->type == N_WORKSPACE) {
if (state == WLR_BUTTON_PRESSED) {
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
seat_set_focus(seat, node);
transaction_commit_dirty();
}
@ -378,7 +377,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
seat_set_focus_layer(seat, layer);
transaction_commit_dirty();
}
if (state == WLR_BUTTON_PRESSED) {
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
seatop_begin_down_on_surface(seat, surface, sx, sy);
}
seat_pointer_notify_button(seat, time_msec, button, state);
@ -387,7 +386,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle tiling resize via border
if (cont && resize_edge && button == BTN_LEFT &&
state == WLR_BUTTON_PRESSED && !is_floating) {
state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating) {
// If a resize is triggered on a tabbed or stacked container, change
// focus to the tab which already had inactive focus -- otherwise, we'd
// change the active tab when the user probably just wanted to resize.
@ -405,7 +404,7 @@ 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 &&
state == WLR_BUTTON_PRESSED) {
state == WL_POINTER_BUTTON_STATE_PRESSED) {
uint32_t btn_resize = config->floating_mod_inverse ?
BTN_LEFT : BTN_RIGHT;
if (button == btn_resize) {
@ -433,7 +432,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
}
// Handle changing focus when clicking on a container
if (cont && state == WLR_BUTTON_PRESSED) {
if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) {
// Default case: focus the container that was just clicked.
node = &cont->node;
@ -454,7 +453,7 @@ 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 == WLR_BUTTON_PRESSED) {
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));
@ -464,7 +463,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle beginning floating resize
if (cont && is_floating_or_child && !is_fullscreen_or_child &&
state == WLR_BUTTON_PRESSED) {
state == WL_POINTER_BUTTON_STATE_PRESSED) {
// Via border
if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) {
seat_set_focus_container(seat, cont);
@ -490,7 +489,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) &&
state == WLR_BUTTON_PRESSED && !is_floating_or_child &&
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
if (!mod_pressed && config->tiling_drag_threshold > 0) {
@ -503,14 +502,14 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
}
// Handle mousedown on a container surface
if (surface && cont && state == WLR_BUTTON_PRESSED) {
if (surface && cont && state == WL_POINTER_BUTTON_STATE_PRESSED) {
seatop_begin_down(seat, cont, sx, sy);
seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED);
seat_pointer_notify_button(seat, time_msec, button, WL_POINTER_BUTTON_STATE_PRESSED);
return;
}
// Handle clicking a container surface or decorations
if (cont && state == WLR_BUTTON_PRESSED) {
if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) {
seat_pointer_notify_button(seat, time_msec, button, state);
return;
}
@ -685,7 +684,7 @@ static void handle_touch_down(struct sway_seat *seat,
pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy,
dx, dy);
dispatch_cursor_button(cursor, &event->touch->base, event->time_msec,
BTN_LEFT, WLR_BUTTON_PRESSED);
BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
}
}
@ -695,9 +694,9 @@ static void handle_touch_down(struct sway_seat *seat,
static uint32_t wl_axis_to_button(struct wlr_pointer_axis_event *event) {
switch (event->orientation) {
case WLR_AXIS_ORIENTATION_VERTICAL:
case WL_POINTER_AXIS_VERTICAL_SCROLL:
return event->delta < 0 ? SWAY_SCROLL_UP : SWAY_SCROLL_DOWN;
case WLR_AXIS_ORIENTATION_HORIZONTAL:
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
return event->delta < 0 ? SWAY_SCROLL_LEFT : SWAY_SCROLL_RIGHT;
default:
sway_log(SWAY_DEBUG, "Unknown axis orientation");

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <float.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_tablet_v2.h>
@ -118,7 +117,11 @@ static void handle_touch_cancel(struct sway_seat *seat,
}
if (e->surface) {
wlr_seat_touch_notify_cancel(seat->wlr_seat, e->surface);
struct wl_client *client = wl_resource_get_client(e->surface->resource);
struct wlr_seat_client *seat_client = wlr_seat_client_for_wl_client(seat->wlr_seat, client);
if (seat_client != NULL) {
wlr_seat_touch_notify_cancel(seat->wlr_seat, seat_client);
}
}
if (wl_list_empty(&e->point_events)) {
@ -143,7 +146,7 @@ static void handle_pointer_axis(struct sway_seat *seat,
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
seat_pointer_notify_button(seat, time_msec, button, state);
if (seat->cursor->pressed_button_count == 0) {

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <wlr/types/wlr_cursor.h>
#include "sway/desktop/transaction.h"
#include "sway/input/cursor.h"
@ -22,7 +21,7 @@ static void finalize_move(struct sway_seat *seat) {
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
if (seat->cursor->pressed_button_count == 0) {
finalize_move(seat);
}

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <limits.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/util/edges.h>
@ -406,7 +405,7 @@ static void finalize_move(struct sway_seat *seat) {
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
if (seat->cursor->pressed_button_count == 0) {
finalize_move(seat);
}

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <limits.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xcursor_manager.h>
@ -21,7 +20,7 @@ struct seatop_resize_floating_event {
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
struct seatop_resize_floating_event *e = seat->seatop_data;
struct sway_container *con = e->con;

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <wlr/types/wlr_cursor.h>
#include <wlr/util/edges.h>
#include "sway/commands.h"
@ -46,7 +45,7 @@ static struct sway_container *container_get_resize_sibling(
static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_input_device *device, uint32_t button,
enum wlr_button_state state) {
enum wl_pointer_button_state state) {
struct seatop_resize_tiling_event *e = seat->seatop_data;
if (seat->cursor->pressed_button_count == 0) {

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <wlr/config.h>
#include <wlr/types/wlr_tablet_v2.h>

View File

@ -109,6 +109,9 @@ static void handle_im_destroy(struct wl_listener *listener, void *data) {
input_method_destroy);
struct wlr_input_method_v2 *context = data;
assert(context == relay->input_method);
wl_list_remove(&relay->input_method_commit.link);
wl_list_remove(&relay->input_method_grab_keyboard.link);
wl_list_remove(&relay->input_method_destroy.link);
wl_list_remove(&relay->input_method_new_popup_surface.link);
relay->input_method = NULL;
struct sway_text_input *text_input = relay_get_focused_text_input(relay);
@ -290,10 +293,6 @@ static void input_popup_update(struct sway_input_popup *popup) {
return;
}
wlr_scene_node_destroy(&popup->scene_tree->node);
wlr_scene_node_destroy(popup->desc.relative);
popup->scene_tree = NULL;
bool cursor_rect = text_input->input->current.features
& WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE;
struct wlr_surface *focused_surface = text_input->input->focused_surface;

View File

@ -288,6 +288,8 @@ static json_object *ipc_json_create_node(int id, const char* type, char *name,
json_object_object_add(object, "focus", focus);
json_object_object_add(object, "fullscreen_mode", json_object_new_int(0));
json_object_object_add(object, "sticky", json_object_new_boolean(false));
json_object_object_add(object, "floating", NULL);
json_object_object_add(object, "scratchpad_state", NULL);
return object;
}
@ -675,7 +677,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
static void ipc_json_describe_container(struct sway_container *c, json_object *object) {
json_object_object_add(object, "name",
c->title ? json_object_new_string(c->title) : NULL);
if (container_is_floating(c)) {
bool floating = container_is_floating(c);
if (floating) {
json_object_object_add(object, "type",
json_object_new_string("floating_con"));
}
@ -693,9 +696,17 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o
json_object_object_add(object, "urgent", json_object_new_boolean(urgent));
json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky));
// sway doesn't track the floating reason, so we can't use "auto_on" or "user_off"
json_object_object_add(object, "floating",
json_object_new_string(floating ? "user_on" : "auto_off"));
json_object_object_add(object, "fullscreen_mode",
json_object_new_int(c->pending.fullscreen_mode));
// sway doesn't track if window was resized in scratchpad, so we can't use "changed"
json_object_object_add(object, "scratchpad_state",
json_object_new_string(!c->scratchpad ? "none" : "fresh"));
struct sway_node *parent = node_get_parent(&c->node);
struct wlr_box parent_box = {0, 0, 0, 0};
@ -1086,10 +1097,6 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
json_object_new_string(device->identifier));
json_object_object_add(object, "name",
json_object_new_string(device->wlr_device->name));
json_object_object_add(object, "vendor",
json_object_new_int(device->wlr_device->vendor));
json_object_object_add(object, "product",
json_object_new_int(device->wlr_device->product));
json_object_object_add(object, "type",
json_object_new_string(
input_device_get_type(device)));
@ -1143,6 +1150,10 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
libinput_dev = wlr_libinput_get_device_handle(device->wlr_device);
json_object_object_add(object, "libinput",
describe_libinput_device(libinput_dev));
json_object_object_add(object, "vendor",
json_object_new_int(libinput_device_get_id_vendor(libinput_dev)));
json_object_object_add(object, "product",
json_object_new_int(libinput_device_get_id_product(libinput_dev)));
}
#endif

View File

@ -1,5 +1,4 @@
// See https://i3wm.org/docs/ipc.html for protocol information
#define _POSIX_C_SOURCE 200112L
#include <linux/input-event-codes.h>
#include <assert.h>
#include <errno.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_session_lock_v1.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <getopt.h>
#include <pango/pangocairo.h>
#include <signal.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
@ -66,7 +65,7 @@
#include <wlr/types/wlr_drm_lease_v1.h>
#endif
#define SWAY_XDG_SHELL_VERSION 2
#define SWAY_XDG_SHELL_VERSION 5
#define SWAY_LAYER_SHELL_VERSION 4
#define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1
@ -113,7 +112,8 @@ static bool is_privileged(const struct wl_global *global) {
global == server.session_lock.manager->global ||
global == server.input->keyboard_shortcuts_inhibit->global ||
global == server.input->virtual_keyboard->global ||
global == server.input->virtual_pointer->global;
global == server.input->virtual_pointer->global ||
global == server.input->transient_seat_manager->global;
}
static bool filter_global(const struct wl_client *client,
@ -173,6 +173,45 @@ static void detect_proprietary(struct wlr_backend *backend, void *data) {
drmFreeVersion(version);
}
static void handle_renderer_lost(struct wl_listener *listener, void *data) {
struct sway_server *server = wl_container_of(listener, server, renderer_lost);
sway_log(SWAY_INFO, "Re-creating renderer after GPU reset");
struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend);
if (renderer == NULL) {
sway_log(SWAY_ERROR, "Unable to create renderer");
return;
}
struct wlr_allocator *allocator =
wlr_allocator_autocreate(server->backend, renderer);
if (allocator == NULL) {
sway_log(SWAY_ERROR, "Unable to create allocator");
wlr_renderer_destroy(renderer);
return;
}
struct wlr_renderer *old_renderer = server->renderer;
struct wlr_allocator *old_allocator = server->allocator;
server->renderer = renderer;
server->allocator = allocator;
wl_list_remove(&server->renderer_lost.link);
wl_signal_add(&server->renderer->events.lost, &server->renderer_lost);
wlr_compositor_set_renderer(server->compositor, renderer);
for (int i = 0; i < root->outputs->length; ++i) {
struct sway_output *output = root->outputs->items[i];
wlr_output_init_render(output->wlr_output,
server->allocator, server->renderer);
}
wlr_allocator_destroy(old_allocator);
wlr_renderer_destroy(old_renderer);
}
bool server_init(struct sway_server *server) {
sway_log(SWAY_DEBUG, "Initializing Wayland server");
server->wl_display = wl_display_create();
@ -196,15 +235,17 @@ bool server_init(struct sway_server *server) {
return false;
}
server->renderer_lost.notify = handle_renderer_lost;
wl_signal_add(&server->renderer->events.lost, &server->renderer_lost);
wlr_renderer_init_wl_shm(server->renderer, server->wl_display);
if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL) {
if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF) != NULL) {
server->linux_dmabuf_v1 = wlr_linux_dmabuf_v1_create_with_renderer(
server->wl_display, 4, server->renderer);
}
if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL &&
debug.legacy_wl_drm) {
wlr_drm_create(server->wl_display, server->renderer);
if (debug.legacy_wl_drm) {
wlr_drm_create(server->wl_display, server->renderer);
}
}
server->allocator = wlr_allocator_autocreate(server->backend,
@ -400,6 +441,7 @@ void server_fini(struct sway_server *server) {
wlr_xwayland_destroy(server->xwayland.wlr_xwayland);
#endif
wl_display_destroy_clients(server->wl_display);
wlr_backend_destroy(server->backend);
wl_display_destroy(server->wl_display);
list_free(server->dirty_nodes);
}

View File

@ -376,6 +376,12 @@ node and will have the following properties:
: integer
: (Only containers and views) The fullscreen mode of the node. 0 means none, 1 means
full workspace, and 2 means global fullscreen
|- floating
: string
: Floating state of container. Can be either "auto_off" or "user_on"
|- scratchpad_state
: string
: Whether the window is in the scratchpad. Can be either "none" or "fresh"
|- app_id
: string
: (Only views) For an xdg-shell view, the name of the application, if set.
@ -1040,7 +1046,7 @@ An object with a single string property containing the contents of the config
*Example Reply:*
```
{
"config": "set $mod Mod4\nbindsym $mod+q exit\n"
"config": "set $mod Mod4\\nbindsym $mod+q exit\\n"
}
```

View File

@ -72,13 +72,11 @@ must be separated by one space. For example:
*output* <name> scale <factor>
Scales the specified output by the specified scale _factor_. An integer is
recommended, but fractional values are also supported. If a fractional
value are specified, be warned that it is not possible to faithfully
represent the contents of your windows - they will be rendered at the next
highest integer scale factor and downscaled. You may be better served by
setting an integer scale factor and adjusting the font size of your
applications to taste. HiDPI isn't supported with Xwayland clients (windows
will blur).
recommended, but fractional values are also supported. You may be better
served by setting an integer scale factor and adjusting the font size of
your applications to taste. HiDPI isn't supported with Xwayland clients
(windows will blur). A fractional scale may be slightly adjusted to match
requirements of the protocol.
*output* <name> scale_filter linear|nearest|smart
Indicates how to scale application buffers that are rendered at a scale

View File

@ -400,6 +400,12 @@ runtime.
only be available for that group. By default, if you overwrite a binding,
swaynag will give you a warning. To silence this, use the _--no-warn_ flag.
For specifying modifier keys, you can use the XKB modifier names _Shift_,
_Lock_ (for Caps Lock), _Control_, _Mod1_ (for Alt), _Mod2_ (for Num Lock),
_Mod3_ (for XKB modifier Mod3), _Mod4_ (for the Logo key), and _Mod5_ (for
AltGr). In addition, you can use the aliases _Ctrl_ (for Control), _Alt_
(for Alt), and _Super_ (for the Logo key).
Unless the flag _--locked_ is set, the command will not be run when a
screen locking program is active. If there is a matching binding with
and without _--locked_, the one with will be preferred when locked and the

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <drm_fourcc.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <drm_fourcc.h>
#include <stdint.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/container.h"

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <ctype.h>
#include <string.h>

View File

@ -1,4 +1,3 @@
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

Some files were not shown because too many files have changed in this diff Show More