aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/util.c21
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h1
-rw-r--r--include/sway/output.h1
-rw-r--r--include/util.h3
-rw-r--r--sway/commands/output.c1
-rw-r--r--sway/commands/output/subpixel.c36
-rw-r--r--sway/config/output.c23
-rw-r--r--sway/ipc-server.c2
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway-ipc.7.scd4
-rw-r--r--sway/sway-output.5.scd7
-rw-r--r--sway/tree/output.c1
-rw-r--r--swaymsg/main.c5
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
60const 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;
261sway_cmd output_cmd_mode; 261sway_cmd output_cmd_mode;
262sway_cmd output_cmd_position; 262sway_cmd output_cmd_position;
263sway_cmd output_cmd_scale; 263sway_cmd output_cmd_scale;
264sway_cmd output_cmd_subpixel;
264sway_cmd output_cmd_transform; 265sway_cmd output_cmd_transform;
265 266
266sway_cmd seat_cmd_attach; 267sway_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 */
30float parse_float(const char *value); 31float parse_float(const char *value);
31 32
33const 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
7struct 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
16int output_name_cmp(const void *item, const void *data) { 17int 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 );