diff options
-rw-r--r-- | common/util.c | 21 | ||||
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | include/sway/output.h | 1 | ||||
-rw-r--r-- | include/util.h | 3 | ||||
-rw-r--r-- | sway/commands/output.c | 1 | ||||
-rw-r--r-- | sway/commands/output/subpixel.c | 36 | ||||
-rw-r--r-- | sway/config/output.c | 23 | ||||
-rw-r--r-- | sway/ipc-server.c | 2 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway-ipc.7.scd | 4 | ||||
-rw-r--r-- | sway/sway-output.5.scd | 7 | ||||
-rw-r--r-- | sway/tree/output.c | 1 | ||||
-rw-r--r-- | swaymsg/main.c | 5 |
14 files changed, 102 insertions, 5 deletions
diff --git a/common/util.c b/common/util.c index edbbf3f7..c43c5ddf 100644 --- a/common/util.c +++ b/common/util.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <string.h> | 5 | #include <string.h> |
6 | #include <strings.h> | 6 | #include <strings.h> |
7 | #include <wayland-server-protocol.h> | ||
7 | #include "log.h" | 8 | #include "log.h" |
8 | #include "util.h" | 9 | #include "util.h" |
9 | 10 | ||
@@ -54,3 +55,23 @@ float parse_float(const char *value) { | |||
54 | } | 55 | } |
55 | return flt; | 56 | return flt; |
56 | } | 57 | } |
58 | |||
59 | |||
60 | const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel) { | ||
61 | switch (subpixel) { | ||
62 | case WL_OUTPUT_SUBPIXEL_UNKNOWN: | ||
63 | return "unknown"; | ||
64 | case WL_OUTPUT_SUBPIXEL_NONE: | ||
65 | return "none"; | ||
66 | case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB: | ||
67 | return "rgb"; | ||
68 | case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR: | ||
69 | return "bgr"; | ||
70 | case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB: | ||
71 | return "vrgb"; | ||
72 | case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR: | ||
73 | return "vbgr"; | ||
74 | } | ||
75 | sway_assert(false, "Unknown value for wl_output_subpixel."); | ||
76 | return NULL; | ||
77 | } | ||
diff --git a/include/sway/commands.h b/include/sway/commands.h index 1c147c5a..7533a14d 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -261,6 +261,7 @@ sway_cmd output_cmd_enable; | |||
261 | sway_cmd output_cmd_mode; | 261 | sway_cmd output_cmd_mode; |
262 | sway_cmd output_cmd_position; | 262 | sway_cmd output_cmd_position; |
263 | sway_cmd output_cmd_scale; | 263 | sway_cmd output_cmd_scale; |
264 | sway_cmd output_cmd_subpixel; | ||
264 | sway_cmd output_cmd_transform; | 265 | sway_cmd output_cmd_transform; |
265 | 266 | ||
266 | sway_cmd seat_cmd_attach; | 267 | sway_cmd seat_cmd_attach; |
diff --git a/include/sway/config.h b/include/sway/config.h index 8970696c..d49120a0 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -184,6 +184,7 @@ struct output_config { | |||
184 | int x, y; | 184 | int x, y; |
185 | float scale; | 185 | float scale; |
186 | int32_t transform; | 186 | int32_t transform; |
187 | enum wl_output_subpixel subpixel; | ||
187 | 188 | ||
188 | char *background; | 189 | char *background; |
189 | char *background_option; | 190 | char *background_option; |
diff --git a/include/sway/output.h b/include/sway/output.h index 8015f211..c336c559 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -31,6 +31,7 @@ struct sway_output { | |||
31 | 31 | ||
32 | int lx, ly; // layout coords | 32 | int lx, ly; // layout coords |
33 | int width, height; // transformed buffer size | 33 | int width, height; // transformed buffer size |
34 | enum wl_output_subpixel detected_subpixel; | ||
34 | 35 | ||
35 | bool enabled, configured; | 36 | bool enabled, configured; |
36 | list_t *workspaces; | 37 | list_t *workspaces; |
diff --git a/include/util.h b/include/util.h index 1fd772c0..6a668fd6 100644 --- a/include/util.h +++ b/include/util.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | #include <wayland-server-protocol.h> | ||
6 | 7 | ||
7 | /** | 8 | /** |
8 | * Wrap i into the range [0, max[ | 9 | * Wrap i into the range [0, max[ |
@@ -29,4 +30,6 @@ bool parse_boolean(const char *boolean, bool current); | |||
29 | */ | 30 | */ |
30 | float parse_float(const char *value); | 31 | float parse_float(const char *value); |
31 | 32 | ||
33 | const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel); | ||
34 | |||
32 | #endif | 35 | #endif |
diff --git a/sway/commands/output.c b/sway/commands/output.c index 40dbf3ca..44e28512 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c | |||
@@ -18,6 +18,7 @@ static struct cmd_handler output_handlers[] = { | |||
18 | { "res", output_cmd_mode }, | 18 | { "res", output_cmd_mode }, |
19 | { "resolution", output_cmd_mode }, | 19 | { "resolution", output_cmd_mode }, |
20 | { "scale", output_cmd_scale }, | 20 | { "scale", output_cmd_scale }, |
21 | { "subpixel", output_cmd_subpixel }, | ||
21 | { "transform", output_cmd_transform }, | 22 | { "transform", output_cmd_transform }, |
22 | }; | 23 | }; |
23 | 24 | ||
diff --git a/sway/commands/output/subpixel.c b/sway/commands/output/subpixel.c new file mode 100644 index 00000000..63191ee6 --- /dev/null +++ b/sway/commands/output/subpixel.c | |||
@@ -0,0 +1,36 @@ | |||
1 | #include <string.h> | ||
2 | #include "log.h" | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/output.h" | ||
6 | |||
7 | struct cmd_results *output_cmd_subpixel(int argc, char **argv) { | ||
8 | if (!config->handler_context.output_config) { | ||
9 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
10 | } | ||
11 | if (!argc) { | ||
12 | return cmd_results_new(CMD_INVALID, "Missing subpixel argument."); | ||
13 | } | ||
14 | enum wl_output_subpixel subpixel; | ||
15 | |||
16 | if (strcmp(*argv, "rgb") == 0) { | ||
17 | subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB; | ||
18 | } else if (strcmp(*argv, "bgr") == 0) { | ||
19 | subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR; | ||
20 | } else if (strcmp(*argv, "vrgb") == 0) { | ||
21 | subpixel = WL_OUTPUT_SUBPIXEL_VERTICAL_RGB; | ||
22 | } else if (strcmp(*argv, "vbgr") == 0) { | ||
23 | subpixel = WL_OUTPUT_SUBPIXEL_VERTICAL_BGR; | ||
24 | } else if (strcmp(*argv, "none") == 0) { | ||
25 | subpixel = WL_OUTPUT_SUBPIXEL_NONE; | ||
26 | } else { | ||
27 | return cmd_results_new(CMD_INVALID, "Invalid output subpixel."); | ||
28 | } | ||
29 | |||
30 | struct output_config *oc = config->handler_context.output_config; | ||
31 | config->handler_context.leftovers.argc = argc - 1; | ||
32 | config->handler_context.leftovers.argv = argv + 1; | ||
33 | |||
34 | oc->subpixel = subpixel; | ||
35 | return NULL; | ||
36 | } | ||
diff --git a/sway/config/output.c b/sway/config/output.c index 44aae03a..d06051b3 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -8,10 +8,11 @@ | |||
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | #include <wlr/types/wlr_output_layout.h> | 9 | #include <wlr/types/wlr_output_layout.h> |
10 | #include <wlr/types/wlr_output.h> | 10 | #include <wlr/types/wlr_output.h> |
11 | #include "log.h" | ||
12 | #include "sway/config.h" | 11 | #include "sway/config.h" |
13 | #include "sway/output.h" | 12 | #include "sway/output.h" |
14 | #include "sway/tree/root.h" | 13 | #include "sway/tree/root.h" |
14 | #include "log.h" | ||
15 | #include "util.h" | ||
15 | 16 | ||
16 | int output_name_cmp(const void *item, const void *data) { | 17 | int output_name_cmp(const void *item, const void *data) { |
17 | const struct output_config *output = item; | 18 | const struct output_config *output = item; |
@@ -43,6 +44,7 @@ struct output_config *new_output_config(const char *name) { | |||
43 | oc->x = oc->y = -1; | 44 | oc->x = oc->y = -1; |
44 | oc->scale = -1; | 45 | oc->scale = -1; |
45 | oc->transform = -1; | 46 | oc->transform = -1; |
47 | oc->subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; | ||
46 | return oc; | 48 | return oc; |
47 | } | 49 | } |
48 | 50 | ||
@@ -65,6 +67,9 @@ void merge_output_config(struct output_config *dst, struct output_config *src) { | |||
65 | if (src->scale != -1) { | 67 | if (src->scale != -1) { |
66 | dst->scale = src->scale; | 68 | dst->scale = src->scale; |
67 | } | 69 | } |
70 | if (src->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN) { | ||
71 | dst->subpixel = src->subpixel; | ||
72 | } | ||
68 | if (src->refresh_rate != -1) { | 73 | if (src->refresh_rate != -1) { |
69 | dst->refresh_rate = src->refresh_rate; | 74 | dst->refresh_rate = src->refresh_rate; |
70 | } | 75 | } |
@@ -187,10 +192,10 @@ struct output_config *store_output_config(struct output_config *oc) { | |||
187 | } | 192 | } |
188 | 193 | ||
189 | sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " | 194 | sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " |
190 | "position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)", | 195 | "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (dpms %d)", |
191 | oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, | 196 | oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, |
192 | oc->x, oc->y, oc->scale, oc->transform, oc->background, | 197 | oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel), |
193 | oc->background_option, oc->dpms_state); | 198 | oc->transform, oc->background, oc->background_option, oc->dpms_state); |
194 | 199 | ||
195 | return oc; | 200 | return oc; |
196 | } | 201 | } |
@@ -363,6 +368,14 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
363 | sway_log(SWAY_DEBUG, "Set %s scale to %f", oc->name, oc->scale); | 368 | sway_log(SWAY_DEBUG, "Set %s scale to %f", oc->name, oc->scale); |
364 | wlr_output_set_scale(wlr_output, oc->scale); | 369 | wlr_output_set_scale(wlr_output, oc->scale); |
365 | } | 370 | } |
371 | |||
372 | if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) { | ||
373 | sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name, | ||
374 | sway_wl_output_subpixel_to_string(oc->subpixel)); | ||
375 | wlr_output_set_subpixel(wlr_output, oc->subpixel); | ||
376 | output_damage_whole(output); | ||
377 | } | ||
378 | |||
366 | if (oc && oc->transform >= 0) { | 379 | if (oc && oc->transform >= 0) { |
367 | sway_log(SWAY_DEBUG, "Set %s transform to %d", oc->name, oc->transform); | 380 | sway_log(SWAY_DEBUG, "Set %s transform to %d", oc->name, oc->transform); |
368 | wlr_output_set_transform(wlr_output, oc->transform); | 381 | wlr_output_set_transform(wlr_output, oc->transform); |
@@ -424,6 +437,8 @@ static void default_output_config(struct output_config *oc, | |||
424 | } | 437 | } |
425 | oc->x = oc->y = -1; | 438 | oc->x = oc->y = -1; |
426 | oc->scale = 1; | 439 | oc->scale = 1; |
440 | struct sway_output *output = wlr_output->data; | ||
441 | oc->subpixel = output->detected_subpixel; | ||
427 | oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; | 442 | oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; |
428 | oc->dpms_state = DPMS_ON; | 443 | oc->dpms_state = DPMS_ON; |
429 | } | 444 | } |
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index df57cba5..e133a5bf 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -644,6 +644,8 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
644 | json_object_object_add(output_json, "focused", | 644 | json_object_object_add(output_json, "focused", |
645 | json_object_new_boolean(focused)); | 645 | json_object_new_boolean(focused)); |
646 | 646 | ||
647 | const char *subpixel = sway_wl_output_subpixel_to_string(output->wlr_output->subpixel); | ||
648 | json_object_object_add(output_json, "subpixel_hinting", json_object_new_string(subpixel)); | ||
647 | json_object_array_add(outputs, output_json); | 649 | json_object_array_add(outputs, output_json); |
648 | } | 650 | } |
649 | struct sway_output *output; | 651 | struct sway_output *output; |
diff --git a/sway/meson.build b/sway/meson.build index 66876bdc..9f79fb6c 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -169,6 +169,7 @@ sway_sources = files( | |||
169 | 'commands/output/mode.c', | 169 | 'commands/output/mode.c', |
170 | 'commands/output/position.c', | 170 | 'commands/output/position.c', |
171 | 'commands/output/scale.c', | 171 | 'commands/output/scale.c', |
172 | 'commands/output/subpixel.c', | ||
172 | 'commands/output/transform.c', | 173 | 'commands/output/transform.c', |
173 | 174 | ||
174 | 'tree/arrange.c', | 175 | 'tree/arrange.c', |
diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index b43b3030..3d22008e 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd | |||
@@ -211,6 +211,9 @@ following properties: | |||
211 | |- scale | 211 | |- scale |
212 | : float | 212 | : float |
213 | : The scale currently in use on the output or _-1_ for disabled outputs | 213 | : The scale currently in use on the output or _-1_ for disabled outputs |
214 | |- subpixel_hinting | ||
215 | : string | ||
216 | : The subpixel hinting current in use on the output. This can be _rgb_, _bgr_, _vrgb_, _vbgr_, or _none_ | ||
214 | |- transform | 217 | |- transform |
215 | : string | 218 | : string |
216 | : The transform currently in use for the output. This can be _normal_, _90_, | 219 | : The transform currently in use for the output. This can be _normal_, _90_, |
@@ -242,6 +245,7 @@ following properties: | |||
242 | "active": true, | 245 | "active": true, |
243 | "primary": false, | 246 | "primary": false, |
244 | "scale": 1.0, | 247 | "scale": 1.0, |
248 | "subpixel_hinting": "rgb", | ||
245 | "transform": "normal", | 249 | "transform": "normal", |
246 | "current_workspace": "1", | 250 | "current_workspace": "1", |
247 | "modes": [ | 251 | "modes": [ |
diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index bb3745f3..1efe2f7b 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd | |||
@@ -64,6 +64,13 @@ must be separated by one space. For example: | |||
64 | applications to taste. HiDPI isn't supported with Xwayland clients (windows | 64 | applications to taste. HiDPI isn't supported with Xwayland clients (windows |
65 | will blur). | 65 | will blur). |
66 | 66 | ||
67 | *output* <name> subpixel rgb|bgr|vrgb|vbgr|none | ||
68 | Manually sets the subpixel hinting for the specified output. This value is | ||
69 | usually auto-detected, but some displays may misreport their subpixel | ||
70 | geometry. Using the correct subpixel hinting allows for sharper text. | ||
71 | Incorrect values will result in blurrier text. When changing this via | ||
72 | *swaymsg*, some applications may need to be restarted to use the new value. | ||
73 | |||
67 | *output* <name> background|bg <file> <mode> [<fallback_color>] | 74 | *output* <name> background|bg <file> <mode> [<fallback_color>] |
68 | Sets the wallpaper for the given output to the specified file, using the | 75 | Sets the wallpaper for the given output to the specified file, using the |
69 | given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). If | 76 | given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). If |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 7867c6bc..28303652 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -92,6 +92,7 @@ struct sway_output *output_create(struct wlr_output *wlr_output) { | |||
92 | node_init(&output->node, N_OUTPUT, output); | 92 | node_init(&output->node, N_OUTPUT, output); |
93 | output->wlr_output = wlr_output; | 93 | output->wlr_output = wlr_output; |
94 | wlr_output->data = output; | 94 | wlr_output->data = output; |
95 | output->detected_subpixel = wlr_output->subpixel; | ||
95 | 96 | ||
96 | wl_signal_init(&output->events.destroy); | 97 | wl_signal_init(&output->events.destroy); |
97 | 98 | ||
diff --git a/swaymsg/main.c b/swaymsg/main.c index 65cc4bbb..f86000a4 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c | |||
@@ -186,11 +186,12 @@ static void pretty_print_output(json_object *o) { | |||
186 | json_object_object_get_ex(o, "focused", &focused); | 186 | json_object_object_get_ex(o, "focused", &focused); |
187 | json_object_object_get_ex(o, "active", &active); | 187 | json_object_object_get_ex(o, "active", &active); |
188 | json_object_object_get_ex(o, "current_workspace", &ws); | 188 | json_object_object_get_ex(o, "current_workspace", &ws); |
189 | json_object *make, *model, *serial, *scale, *transform; | 189 | json_object *make, *model, *serial, *scale, *subpixel, *transform; |
190 | json_object_object_get_ex(o, "make", &make); | 190 | json_object_object_get_ex(o, "make", &make); |
191 | json_object_object_get_ex(o, "model", &model); | 191 | json_object_object_get_ex(o, "model", &model); |
192 | json_object_object_get_ex(o, "serial", &serial); | 192 | json_object_object_get_ex(o, "serial", &serial); |
193 | json_object_object_get_ex(o, "scale", &scale); | 193 | json_object_object_get_ex(o, "scale", &scale); |
194 | json_object_object_get_ex(o, "subpixel_hinting", &subpixel); | ||
194 | json_object_object_get_ex(o, "transform", &transform); | 195 | json_object_object_get_ex(o, "transform", &transform); |
195 | json_object *x, *y; | 196 | json_object *x, *y; |
196 | json_object_object_get_ex(rect, "x", &x); | 197 | json_object_object_get_ex(rect, "x", &x); |
@@ -209,6 +210,7 @@ static void pretty_print_output(json_object *o) { | |||
209 | " Current mode: %dx%d @ %f Hz\n" | 210 | " Current mode: %dx%d @ %f Hz\n" |
210 | " Position: %d,%d\n" | 211 | " Position: %d,%d\n" |
211 | " Scale factor: %f\n" | 212 | " Scale factor: %f\n" |
213 | " Subpixel hinting: %s\n" | ||
212 | " Transform: %s\n" | 214 | " Transform: %s\n" |
213 | " Workspace: %s\n", | 215 | " Workspace: %s\n", |
214 | json_object_get_string(name), | 216 | json_object_get_string(name), |
@@ -221,6 +223,7 @@ static void pretty_print_output(json_object *o) { | |||
221 | (float)json_object_get_int(refresh) / 1000, | 223 | (float)json_object_get_int(refresh) / 1000, |
222 | json_object_get_int(x), json_object_get_int(y), | 224 | json_object_get_int(x), json_object_get_int(y), |
223 | json_object_get_double(scale), | 225 | json_object_get_double(scale), |
226 | json_object_get_string(subpixel), | ||
224 | json_object_get_string(transform), | 227 | json_object_get_string(transform), |
225 | json_object_get_string(ws) | 228 | json_object_get_string(ws) |
226 | ); | 229 | ); |