---
doc/kanshi.5.scd | 3 ++-
include/config.h | 1 +
main.c | 33 +++++++++++++++++++--------------
parser.c | 4 ++++
4 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/doc/kanshi.5.scd b/doc/kanshi.5.scd
index e14a77b..b007d07 100644
--- a/doc/kanshi.5.scd
+++ b/doc/kanshi.5.scd
@@ -82,7 +82,7 @@ quoted (with *"*) if they contain spaces.
*enable*|*disable*
Enables or disables the specified output.
-*mode* <width>x<height>[@<rate>[Hz]]
+*mode* [--custom] <width>x<height>[@<rate>[Hz]]
Configures the specified output to use the specified mode. Modes are a
combination of width and height (in pixels) and a refresh rate (in Hz) that
your display can be configured to use.
@@ -92,6 +92,7 @@ quoted (with *"*) if they contain spaces.
```
output HDMI-A-1 mode 1920x1080
output HDMI-A-1 mode 1920x1080@60Hz
+ output HDMI-A-1 mode --custom 1280x720@60Hz
```
*position* <x>,<y>
diff --git a/include/config.h b/include/config.h
index be01748..09ac2cd 100644
--- a/include/config.h
+++ b/include/config.h
@@ -22,6 +22,7 @@ struct kanshi_profile_output {
struct {
int width, height;
int refresh; // mHz
+ bool custom;
} mode;
struct {
int x, y;
diff --git a/main.c b/main.c
index f21f46c..d4fd500 100644
--- a/main.c
+++ b/main.c
@@ -287,20 +287,25 @@ static bool apply_profile(struct kanshi_state *state,
struct zwlr_output_configuration_head_v1 *config_head =
zwlr_output_configuration_v1_enable_head(config, head->wlr_head);
if (profile_output->fields & KANSHI_OUTPUT_MODE) {
- // TODO: support custom modes
- struct kanshi_mode *mode = match_mode(head,
- profile_output->mode.width, profile_output->mode.height,
- profile_output->mode.refresh);
- if (mode == NULL) {
- fprintf(stderr,
- "output '%s' doesn't support mode '%dx%d@%fHz'\n",
- head->name,
- profile_output->mode.width, profile_output->mode.height,
- (float)profile_output->mode.refresh / 1000);
- goto error;
- }
- zwlr_output_configuration_head_v1_set_mode(config_head,
- mode->wlr_mode);
+ if (profile_output->mode.custom) {
+ fprintf(stderr, "applying the custom mode %s\n", profile_output->name);
+ zwlr_output_configuration_head_v1_set_custom_mode(config_head,
+ profile_output->mode.width, profile_output->mode.height, profile_output->mode.refresh);
+ } else {
+ struct kanshi_mode *mode = match_mode(head,
+ profile_output->mode.width, profile_output->mode.height,
+ profile_output->mode.refresh);
+ if (mode == NULL) {
+ fprintf(stderr,
+ "output '%s' doesn't support mode '%dx%d@%fHz'\n",
+ head->name,
+ profile_output->mode.width, profile_output->mode.height,
+ (float)profile_output->mode.refresh / 1000);
+ goto error;
+ }
+ zwlr_output_configuration_head_v1_set_mode(config_head,
+ mode->wlr_mode);
+ }
}
if (profile_output->fields & KANSHI_OUTPUT_POSITION) {
zwlr_output_configuration_head_v1_set_position(config_head,
diff --git a/parser.c b/parser.c
index ac22c00..c1b8964 100644
--- a/parser.c
+++ b/parser.c
@@ -322,6 +322,10 @@ static struct kanshi_profile_output *parse_profile_output(
char *value = parser->tok_str;
switch (key) {
case KANSHI_OUTPUT_MODE:
+ if (strcmp(value, "--custom") == 0) {
+ output->mode.custom = true;
+ continue;
+ }
if (!parse_mode(output, value)) {
return NULL;
}
--
2.43.0