diff --git a/include/sway/config.h b/include/sway/config.h
index 3c380933e..16b822fea 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -267,6 +267,12 @@ enum render_bit_depth {
RENDER_BIT_DEPTH_10,
};
+enum color_profile {
+ COLOR_PROFILE_DEFAULT, // default is Transform with NULL color_transform
+ COLOR_PROFILE_TRANSFORM, // use color_transform from output_config
+ COLOR_PROFILE_TRANSFORM_WITH_DEVICE_PRIMARIES, // create transform from wlr_output
+};
+
/**
* Size and position configuration for a particular output.
*
@@ -288,7 +294,7 @@ struct output_config {
int max_render_time; // In milliseconds
int adaptive_sync;
enum render_bit_depth render_bit_depth;
- bool set_color_transform;
+ enum color_profile color_profile;
struct wlr_color_transform *color_transform;
int allow_tearing;
int hdr;
diff --git a/include/sway/server.h b/include/sway/server.h
index a5b6d3320..61cb08586 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -160,7 +160,7 @@ struct sway_debug {
extern struct sway_debug debug;
-extern bool allow_unsupported_gpu;
+extern bool unsupported_gpu_detected;
void sway_terminate(int exit_code);
diff --git a/protocols/idle.xml b/protocols/idle.xml
deleted file mode 100644
index 92d9989c7..000000000
--- a/protocols/idle.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
- .
- ]]>
-
-
- This interface allows to monitor user idle time on a given seat. The interface
- allows to register timers which trigger after no user activity was registered
- on the seat for a given interval. It notifies when user activity resumes.
-
- This is useful for applications wanting to perform actions when the user is not
- interacting with the system, e.g. chat applications setting the user as away, power
- management features to dim screen, etc..
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/protocols/meson.build b/protocols/meson.build
index e7ada59b8..a1cb35344 100644
--- a/protocols/meson.build
+++ b/protocols/meson.build
@@ -12,7 +12,6 @@ protocols = [
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
'wlr-layer-shell-unstable-v1.xml',
- 'idle.xml',
'wlr-output-power-management-unstable-v1.xml',
]
diff --git a/sway/commands/bar/colors.c b/sway/commands/bar/colors.c
index 275fa3c64..da606c1b8 100644
--- a/sway/commands/bar/colors.c
+++ b/sway/commands/bar/colors.c
@@ -72,6 +72,10 @@ static struct cmd_results *parse_three_colors(char ***colors,
}
struct cmd_results *bar_cmd_colors(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "colors", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
return config_subcommand(argv, argc, bar_colors_handlers,
sizeof(bar_colors_handlers));
}
diff --git a/sway/commands/layout.c b/sway/commands/layout.c
index a32c908b8..22dfdf3d7 100644
--- a/sway/commands/layout.c
+++ b/sway/commands/layout.c
@@ -137,11 +137,15 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
// If parent has only a singe child operate on its parent and
// flatten once, like i3
if (container && container->pending.children->length == 1) {
- struct sway_container *child = container->pending.children->items[0];
+ // Also check grandparent to avoid restricting layouts
struct sway_container *parent = container->pending.parent;
- container_replace(container, child);
- container_begin_destroy(container);
- container = parent;
+ if (parent && parent->pending.children->length == 1) {
+ struct sway_container *child = container->pending.children->items[0];
+ struct sway_container *parent = container->pending.parent;
+ container_replace(container, child);
+ container_begin_destroy(container);
+ container = parent;
+ }
}
}
diff --git a/sway/commands/output/color_profile.c b/sway/commands/output/color_profile.c
index 98481329b..0456b19b7 100644
--- a/sway/commands/output/color_profile.c
+++ b/sway/commands/output/color_profile.c
@@ -55,14 +55,30 @@ struct cmd_results *output_cmd_color_profile(int argc, char **argv) {
if (!config->handler_context.output_config) {
return cmd_results_new(CMD_FAILURE, "Missing output config");
}
+
+ enum color_profile new_mode = COLOR_PROFILE_TRANSFORM;
+ if (argc >= 2 && strcmp(*argv, "--device-primaries") == 0) {
+ new_mode = COLOR_PROFILE_TRANSFORM_WITH_DEVICE_PRIMARIES;
+ argc--;
+ argv++;
+ }
+
if (!argc) {
return cmd_results_new(CMD_INVALID, "Missing color_profile first argument.");
}
- if (strcmp(*argv, "srgb") == 0) {
+ if (strcmp(*argv, "gamma22") == 0) {
wlr_color_transform_unref(config->handler_context.output_config->color_transform);
config->handler_context.output_config->color_transform = NULL;
- config->handler_context.output_config->set_color_transform = true;
+ config->handler_context.output_config->color_profile = new_mode;
+
+ config->handler_context.leftovers.argc = argc - 1;
+ config->handler_context.leftovers.argv = argv + 1;
+ } else if (strcmp(*argv, "srgb") == 0) {
+ wlr_color_transform_unref(config->handler_context.output_config->color_transform);
+ config->handler_context.output_config->color_transform =
+ wlr_color_transform_init_linear_to_inverse_eotf(WLR_COLOR_TRANSFER_FUNCTION_SRGB);
+ config->handler_context.output_config->color_profile = new_mode;
config->handler_context.leftovers.argc = argc - 1;
config->handler_context.leftovers.argv = argv + 1;
@@ -71,6 +87,10 @@ struct cmd_results *output_cmd_color_profile(int argc, char **argv) {
return cmd_results_new(CMD_INVALID,
"Invalid color profile specification: icc type requires a file");
}
+ if (new_mode != COLOR_PROFILE_TRANSFORM) {
+ return cmd_results_new(CMD_INVALID,
+ "Invalid color profile specification: --device-primaries cannot be used with icc");
+ }
char *icc_path = strdup(argv[1]);
if (!expand_path(&icc_path)) {
@@ -100,13 +120,14 @@ struct cmd_results *output_cmd_color_profile(int argc, char **argv) {
wlr_color_transform_unref(config->handler_context.output_config->color_transform);
config->handler_context.output_config->color_transform = tmp;
- config->handler_context.output_config->set_color_transform = true;
+ config->handler_context.output_config->color_profile = COLOR_PROFILE_TRANSFORM;
config->handler_context.leftovers.argc = argc - 2;
config->handler_context.leftovers.argv = argv + 2;
} else {
return cmd_results_new(CMD_INVALID,
- "Invalid color profile specification: first argument should be icc|srgb");
+ "Invalid color profile specification: "
+ "first argument should be gamma22|icc|srgb");
}
return NULL;
diff --git a/sway/config/output.c b/sway/config/output.c
index ed8147b8b..3d25b46c7 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -75,7 +75,7 @@ struct output_config *new_output_config(const char *name) {
oc->max_render_time = -1;
oc->adaptive_sync = -1;
oc->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
- oc->set_color_transform = false;
+ oc->color_profile = COLOR_PROFILE_DEFAULT;
oc->color_transform = NULL;
oc->power = -1;
oc->allow_tearing = -1;
@@ -130,12 +130,12 @@ static void supersede_output_config(struct output_config *dst, struct output_con
if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
dst->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
}
- if (src->set_color_transform) {
+ if (src->color_profile != COLOR_PROFILE_DEFAULT) {
if (dst->color_transform) {
wlr_color_transform_unref(dst->color_transform);
dst->color_transform = NULL;
}
- dst->set_color_transform = false;
+ dst->color_profile = COLOR_PROFILE_DEFAULT;
}
if (src->background) {
free(dst->background);
@@ -207,12 +207,12 @@ static void merge_output_config(struct output_config *dst, struct output_config
if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
dst->render_bit_depth = src->render_bit_depth;
}
- if (src->set_color_transform) {
+ if (src->color_profile != COLOR_PROFILE_DEFAULT) {
if (src->color_transform) {
wlr_color_transform_ref(src->color_transform);
}
wlr_color_transform_unref(dst->color_transform);
- dst->set_color_transform = true;
+ dst->color_profile = src->color_profile;
dst->color_transform = src->color_transform;
}
if (src->background) {
@@ -562,8 +562,75 @@ static void queue_output_config(struct output_config *oc,
set_hdr(wlr_output, pending, hdr);
}
+struct config_output_state {
+ struct wlr_color_transform *color_transform;
+};
+
+static void config_output_state_finish(struct config_output_state *state) {
+ wlr_color_transform_unref(state->color_transform);
+}
+
+static struct wlr_color_transform *color_profile_from_device(struct wlr_output *wlr_output,
+ struct wlr_color_transform *transfer_function) {
+ struct wlr_color_primaries srgb_primaries;
+ wlr_color_primaries_from_named(&srgb_primaries, WLR_COLOR_NAMED_PRIMARIES_SRGB);
+
+ const struct wlr_color_primaries *primaries = wlr_output->default_primaries;
+ if (primaries == NULL) {
+ sway_log(SWAY_INFO, "output has no reported color information");
+ if (transfer_function) {
+ wlr_color_transform_ref(transfer_function);
+ }
+ return transfer_function;
+ } else if (memcmp(primaries, &srgb_primaries, sizeof(*primaries)) == 0) {
+ sway_log(SWAY_INFO, "output reports sRGB colors, no correction needed");
+ if (transfer_function) {
+ wlr_color_transform_ref(transfer_function);
+ }
+ return transfer_function;
+ } else {
+ sway_log(SWAY_INFO, "Creating color profile from reported color primaries: "
+ "R(%f, %f) G(%f, %f) B(%f, %f) W(%f, %f)",
+ primaries->red.x, primaries->red.y, primaries->green.x, primaries->green.y,
+ primaries->blue.x, primaries->blue.y, primaries->white.x, primaries->white.y);
+ float matrix[9];
+ wlr_color_primaries_transform_absolute_colorimetric(&srgb_primaries, primaries, matrix);
+ struct wlr_color_transform *matrix_transform = wlr_color_transform_init_matrix(matrix);
+ if (matrix_transform == NULL) {
+ return NULL;
+ }
+ struct wlr_color_transform *resolved_tf = transfer_function ?
+ wlr_color_transform_ref(transfer_function) :
+ wlr_color_transform_init_linear_to_inverse_eotf(WLR_COLOR_TRANSFER_FUNCTION_GAMMA22);
+ if (resolved_tf == NULL) {
+ wlr_color_transform_unref(matrix_transform);
+ return NULL;
+ }
+ struct wlr_color_transform *transforms[] = { matrix_transform, resolved_tf };
+ size_t transforms_len = sizeof(transforms) / sizeof(transforms[0]);
+ struct wlr_color_transform *result = wlr_color_transform_init_pipeline(transforms, transforms_len);
+ wlr_color_transform_unref(matrix_transform);
+ wlr_color_transform_unref(resolved_tf);
+ return result;
+ }
+}
+
+static struct wlr_color_transform *get_color_profile(struct wlr_output *output,
+ struct output_config *oc) {
+ if (oc && oc->color_profile == COLOR_PROFILE_TRANSFORM) {
+ if (oc->color_transform) {
+ wlr_color_transform_ref(oc->color_transform);
+ }
+ return oc->color_transform;
+ } else if (oc && oc->color_profile == COLOR_PROFILE_TRANSFORM_WITH_DEVICE_PRIMARIES) {
+ return color_profile_from_device(output, oc->color_transform);
+ } else {
+ return NULL;
+ }
+}
+
static bool finalize_output_config(struct output_config *oc, struct sway_output *output,
- const struct wlr_output_state *applied) {
+ const struct wlr_output_state *applied, const struct config_output_state *config_applied) {
if (output == root->fallback_output) {
return false;
}
@@ -609,16 +676,11 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
output_enable(output);
}
- 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;
+ wlr_color_transform_unref(output->color_transform);
+ if (config_applied->color_transform != NULL) {
+ wlr_color_transform_ref(config_applied->color_transform);
}
+ output->color_transform = config_applied->color_transform;
output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0;
output->allow_tearing = oc && oc->allow_tearing > 0;
@@ -935,17 +997,25 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
if (!states) {
return false;
}
+ struct config_output_state *config_states = calloc(configs_len, sizeof(*config_states));
+ if (!config_states) {
+ free(states);
+ return false;
+ }
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];
+ struct config_output_state *config_state = &config_states[idx];
backend_state->output = cfg->output->wlr_output;
wlr_output_state_init(&backend_state->base);
queue_output_config(cfg->config, cfg->output, &backend_state->base);
dump_output_state(cfg->output->wlr_output, &backend_state->base);
+
+ config_state->color_transform = get_color_profile(cfg->output->wlr_output, cfg->config);
}
struct wlr_output_swapchain_manager swapchain_mgr;
@@ -975,11 +1045,12 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
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 config_output_state *config_state = &config_states[idx];
struct wlr_scene_output_state_options opts = {
.swapchain = wlr_output_swapchain_manager_get_swapchain(
&swapchain_mgr, backend_state->output),
- .color_transform = cfg->output->color_transform,
+ .color_transform = config_state->color_transform,
};
struct wlr_scene_output *scene_output = cfg->output->scene_output;
struct wlr_output_state *state = &backend_state->base;
@@ -1003,9 +1074,10 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
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 config_output_state *config_state = &config_states[idx];
sway_log(SWAY_DEBUG, "Finalizing config for %s",
cfg->output->wlr_output->name);
- finalize_output_config(cfg->config, cfg->output, &backend_state->base);
+ finalize_output_config(cfg->config, cfg->output, &backend_state->base, config_state);
}
// Output layout being applied in finalize_output_config can shift outputs
@@ -1026,8 +1098,10 @@ out:
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);
+ config_output_state_finish(&config_states[idx]);
}
free(states);
+ free(config_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
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index 696a45ada..7217e1369 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -354,6 +354,7 @@ static void handle_set_title(struct wl_listener *listener, void *data) {
struct sway_view *view = &xdg_shell_view->view;
view_update_title(view, false);
view_execute_criteria(view);
+ transaction_commit_dirty();
}
static void handle_set_app_id(struct wl_listener *listener, void *data) {
@@ -362,6 +363,7 @@ static void handle_set_app_id(struct wl_listener *listener, void *data) {
struct sway_view *view = &xdg_shell_view->view;
view_update_app_id(view);
view_execute_criteria(view);
+ transaction_commit_dirty();
}
static void handle_new_popup(struct wl_listener *listener, void *data) {
@@ -384,6 +386,9 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, request_maximize);
struct wlr_xdg_toplevel *toplevel = xdg_shell_view->view.wlr_xdg_toplevel;
+ if (!toplevel->base->surface->mapped) {
+ return;
+ }
wlr_xdg_surface_schedule_configure(toplevel->base);
}
@@ -594,4 +599,5 @@ void xdg_toplevel_tag_manager_v1_handle_set_tag(struct wl_listener *listener, vo
free(xdg_shell_view->tag);
xdg_shell_view->tag = strdup(event->tag);
view_execute_criteria(view);
+ transaction_commit_dirty();
}
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 76e63ce1f..65016b3b1 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -689,6 +689,7 @@ static void handle_set_title(struct wl_listener *listener, void *data) {
}
view_update_title(view, false);
view_execute_criteria(view);
+ transaction_commit_dirty();
}
static void handle_set_class(struct wl_listener *listener, void *data) {
@@ -700,6 +701,7 @@ static void handle_set_class(struct wl_listener *listener, void *data) {
return;
}
view_execute_criteria(view);
+ transaction_commit_dirty();
}
static void handle_set_role(struct wl_listener *listener, void *data) {
@@ -711,6 +713,7 @@ static void handle_set_role(struct wl_listener *listener, void *data) {
return;
}
view_execute_criteria(view);
+ transaction_commit_dirty();
}
static void handle_set_startup_id(struct wl_listener *listener, void *data) {
@@ -747,6 +750,7 @@ static void handle_set_window_type(struct wl_listener *listener, void *data) {
return;
}
view_execute_criteria(view);
+ transaction_commit_dirty();
}
static void handle_set_hints(struct wl_listener *listener, void *data) {
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index df62ef41b..fc0f11fd8 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -644,6 +644,11 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
cursor_handle_activity_from_device(cursor, &event->tablet->base);
struct sway_tablet_tool *sway_tool = event->tool->data;
+ if (!sway_tool) {
+ sway_log(SWAY_DEBUG, "tool tip before proximity");
+ return;
+ }
+
struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2;
struct sway_seat *seat = cursor->seat;
diff --git a/sway/input/seat.c b/sway/input/seat.c
index ba64babe3..d275c5f8d 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1015,9 +1015,9 @@ void seat_configure_xcursor(struct sway_seat *seat) {
server.xwayland.xcursor_manager, "default", 1);
if (xcursor != NULL) {
struct wlr_xcursor_image *image = xcursor->images[0];
+ struct wlr_buffer *buffer = wlr_xcursor_image_get_buffer(image);
wlr_xwayland_set_cursor(
- server.xwayland.wlr_xwayland, image->buffer,
- image->width * 4, image->width, image->height,
+ server.xwayland.wlr_xwayland, buffer,
image->hotspot_x, image->hotspot_y);
}
}
diff --git a/sway/input/seatop_resize_tiling.c b/sway/input/seatop_resize_tiling.c
index 15fd333b3..be7b3c128 100644
--- a/sway/input/seatop_resize_tiling.c
+++ b/sway/input/seatop_resize_tiling.c
@@ -105,10 +105,7 @@ static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
static void handle_unref(struct sway_seat *seat, struct sway_container *con) {
struct seatop_resize_tiling_event *e = seat->seatop_data;
- if (e->con == con) {
- seatop_begin_default(seat);
- }
- if (e->h_sib == con || e->v_sib == con) {
+ if (e->con == con || e->h_sib == con || e->v_sib == con) {
seatop_begin_default(seat);
}
}
diff --git a/sway/main.c b/sway/main.c
index 44d07679e..a94389266 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -224,7 +224,7 @@ static const char usage[] =
"\n";
int main(int argc, char **argv) {
- static bool verbose = false, debug = false, validate = false;
+ bool verbose = false, debug = false, validate = false, allow_unsupported_gpu = false;
char *config_path = NULL;
@@ -286,6 +286,12 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
+ char *unsupported_gpu_env = getenv("SWAY_UNSUPPORTED_GPU");
+ // we let the flag override the environment variable
+ if (!allow_unsupported_gpu && unsupported_gpu_env) {
+ allow_unsupported_gpu = parse_boolean(unsupported_gpu_env, false);
+ }
+
// As the 'callback' function for wlr_log is equivalent to that for
// sway, we do not need to override it.
if (debug) {
@@ -373,6 +379,20 @@ int main(int argc, char **argv) {
swaynag_show(&config->swaynag_config_errors);
}
+ struct swaynag_instance nag_gpu = (struct swaynag_instance){
+ .args = "--type error "
+ "--message 'Proprietary GPU drivers are not supported by sway. Do not report issues.' "
+ "--detailed-message",
+ .detailed = true,
+ };
+
+ if (unsupported_gpu_detected && !allow_unsupported_gpu) {
+ swaynag_log(config->swaynag_command, &nag_gpu,
+ "To remove this message, launch sway with --unsupported-gpu "
+ "or set the environment variable SWAY_UNSUPPORTED_GPU=true.");
+ swaynag_show(&nag_gpu);
+ }
+
server_run(&server);
shutdown:
@@ -385,6 +405,10 @@ shutdown:
free(config_path);
free_config(config);
+ if (nag_gpu.client != NULL) {
+ wl_client_destroy(nag_gpu.client);
+ }
+
pango_cairo_font_map_set_default(NULL);
return exit_value;
diff --git a/sway/server.c b/sway/server.c
index 4e606a391..aef0d0b0c 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -77,7 +78,7 @@
#define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1
#define SWAY_PRESENTATION_VERSION 2
-bool allow_unsupported_gpu = false;
+bool unsupported_gpu_detected = false;
#if WLR_HAS_DRM_BACKEND
static void handle_drm_lease_request(struct wl_listener *listener, void *data) {
@@ -160,27 +161,16 @@ static void detect_proprietary(struct wlr_backend *backend, void *data) {
return;
}
- bool is_unsupported = false;
if (strcmp(version->name, "nvidia-drm") == 0) {
- is_unsupported = true;
+ unsupported_gpu_detected = true;
sway_log(SWAY_ERROR, "!!! Proprietary Nvidia drivers are in use !!!");
- if (!allow_unsupported_gpu) {
- sway_log(SWAY_ERROR, "Use Nouveau instead");
- }
}
if (strcmp(version->name, "evdi") == 0) {
- is_unsupported = true;
+ unsupported_gpu_detected = true;
sway_log(SWAY_ERROR, "!!! Proprietary DisplayLink drivers are in use !!!");
}
- if (!allow_unsupported_gpu && is_unsupported) {
- sway_log(SWAY_ERROR,
- "Proprietary drivers are NOT supported. To launch sway anyway, "
- "launch with --unsupported-gpu and DO NOT report issues.");
- exit(EXIT_FAILURE);
- }
-
drmFreeVersion(version);
}
@@ -458,17 +448,14 @@ bool server_init(struct sway_server *server) {
const enum wp_color_manager_v1_render_intent render_intents[] = {
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL,
};
- const enum wp_color_manager_v1_transfer_function transfer_functions[] = {
- WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB,
- WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ,
- WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_LINEAR,
- };
- const enum wp_color_manager_v1_primaries primaries[] = {
- WP_COLOR_MANAGER_V1_PRIMARIES_SRGB,
- WP_COLOR_MANAGER_V1_PRIMARIES_BT2020,
- };
+ size_t transfer_functions_len = 0;
+ enum wp_color_manager_v1_transfer_function *transfer_functions =
+ wlr_color_manager_v1_transfer_function_list_from_renderer(server->renderer, &transfer_functions_len);
+ size_t primaries_len = 0;
+ enum wp_color_manager_v1_primaries *primaries =
+ wlr_color_manager_v1_primaries_list_from_renderer(server->renderer, &primaries_len);
struct wlr_color_manager_v1 *cm = wlr_color_manager_v1_create(
- server->wl_display, 1, &(struct wlr_color_manager_v1_options){
+ server->wl_display, 2, &(struct wlr_color_manager_v1_options){
.features = {
.parametric = true,
.set_mastering_display_primaries = true,
@@ -476,13 +463,18 @@ bool server_init(struct sway_server *server) {
.render_intents = render_intents,
.render_intents_len = sizeof(render_intents) / sizeof(render_intents[0]),
.transfer_functions = transfer_functions,
- .transfer_functions_len = sizeof(transfer_functions) / sizeof(transfer_functions[0]),
+ .transfer_functions_len = transfer_functions_len,
.primaries = primaries,
- .primaries_len = sizeof(primaries) / sizeof(primaries[0]),
+ .primaries_len = primaries_len,
});
+ free(transfer_functions);
+ free(primaries);
wlr_scene_set_color_manager_v1(root->root_scene, cm);
}
+ wlr_color_representation_manager_v1_create_with_renderer(
+ server->wl_display, 1, server->renderer);
+
wl_list_init(&server->pending_launcher_ctxs);
// Avoid using "wayland-0" as display socket
diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd
index 4b0d5c962..2658228a1 100644
--- a/sway/sway-ipc.7.scd
+++ b/sway/sway-ipc.7.scd
@@ -1116,7 +1116,7 @@ Returns the currently active binding mode.
A single object that contains the property _name_, which is set to the
currently active binding mode as a string.
-*Exact Reply:*
+*Example Reply:*
```
{
"name": "default"
diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd
index cc48589c3..faf59a1f2 100644
--- a/sway/sway-output.5.scd
+++ b/sway/sway-output.5.scd
@@ -178,9 +178,19 @@ must be separated by one space. For example:
updated to work with different bit depths. This command is experimental,
and may be removed or changed in the future.
-*output* color_profile srgb|[icc ]
- Sets the color profile for an output. The default is _srgb_. should be a
- path to a display ICC profile.
+*output* color_profile [--device-primaries] gamma22|srgb
+ Sets the color profile for an output. The default is _gamma22_.
+
+ _--device-primaries_ will use the output's self-reported color primaries
+ when available (e.g. from display EDID).
+
+ Not all renderers support this feature; currently it only works with the
+ the Vulkan renderer. It is not compatible with HDR support features.
+
+*output* color_profile icc
+ Sets the color profile for an output.
+
+ should be a path to a display ICC profile.
Not all renderers support this feature; currently it only works with the
the Vulkan renderer. Even where supported, the application of the color
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 3d6211249..eab2a5e2b 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -43,21 +43,19 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
bool failed = false;
view->scene_tree = alloc_scene_tree(root->staging, &failed);
view->content_tree = alloc_scene_tree(view->scene_tree, &failed);
+ if (failed) {
+ goto err;
+ }
- if (!failed && !scene_descriptor_assign(&view->scene_tree->node,
- SWAY_SCENE_DESC_VIEW, view)) {
- failed = true;
+ if (!scene_descriptor_assign(&view->scene_tree->node, SWAY_SCENE_DESC_VIEW, view)) {
+ goto err;
}
view->image_capture_scene = wlr_scene_create();
if (view->image_capture_scene == NULL) {
- failed = true;
- }
-
- if (failed) {
- wlr_scene_node_destroy(&view->scene_tree->node);
- return false;
+ goto err;
}
+ view->image_capture_scene->restack_xwayland_surfaces = false;
view->type = type;
view->impl = impl;
@@ -67,6 +65,10 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
view->tearing_mode = TEARING_WINDOW_HINT;
wl_signal_init(&view->events.unmap);
return true;
+
+err:
+ wlr_scene_node_destroy(&view->scene_tree->node);
+ return false;
}
void view_destroy(struct sway_view *view) {
@@ -307,7 +309,7 @@ void view_autoconfigure(struct sway_view *view) {
}
struct sway_output *output = ws ? ws->output : NULL;
- if (con->pending.fullscreen_mode == FULLSCREEN_WORKSPACE) {
+ if (output && con->pending.fullscreen_mode == FULLSCREEN_WORKSPACE) {
con->pending.content_x = output->lx;
con->pending.content_y = output->ly;
con->pending.content_width = output->width;
diff --git a/swaynag/main.c b/swaynag/main.c
index b68157ff2..53c2203ff 100644
--- a/swaynag/main.c
+++ b/swaynag/main.c
@@ -45,6 +45,7 @@ int main(int argc, char **argv) {
if (config_path) {
sway_log(SWAY_DEBUG, "Loading config file: %s", config_path);
status = swaynag_load_config(config_path, &swaynag, types);
+ free(config_path);
if (status != 0) {
goto cleanup;
}