Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output/background: parse background mode into enum #8564

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mstoeckl
Copy link
Contributor

@mstoeckl mstoeckl commented Feb 9, 2025

This change parses the background mode in the output ... background ... command instead of validating the mode string and then copying it around. Doing so avoids a number of strdup() calls and associated free()s, making the logic and failure handling paths in output_cmd_background() somewhat easier to follow.

It turns out this change also fixes a mismatch between the way the background subcommand parsed modes (case insensitively) and the way swaybg does (exact match). Previously both

swaymsg output '*' background ~/Sway_Tree.png center
swaymsg output '*' background ~/Sway_Tree.png CENTER

would be accepted by sway, but swaybg would only use the centering mode on the first image, and would print a warning on the second.

Notes:

  • The commit keeps the case insensitive parsing behavior, even though it did not work properly before, because many Sway commands already accept keywords case-insensitively. (Some do, some don't; I'm not sure which should be preferred.)
  • enum background_mode is AFAIK the first enum without a real _DEFAULT behavior, so I've named the null case _UNSET. Is there an existing convention for this?
  • The background_mode_names table is used in sway/commands/output/background.c (for parsing) and sway/config/output.c (debug output and spawn_swaybg()); I've put it in the former file, but am not certain about the right place for it.
  • A similar "parse-instead-of-validating" change may be worth doing for the background color, but most approaches would complicate spawn_swaybg(), which currently allocates an array of pointers to strings with a longer lifespan -- parsing and then reprinting colors would require temporary allocations or per-output_config scratch space to hold the colors. There are other solutions, but none I've found to be clean and simple so far.

Edit: looks like there are compile werrors because execvp takes char *const argv[], not const char *const argv[]; I may need to rethink this, depending on what execvp does. Edit 2: fixed, execvp does not modify its input and its signature is constrained by history per Rationale section of man 3p execvp.

This simplifies the logic in `output_cmd_background` by avoiding
strdup() calls (and their error handling paths) for the background mode.

It also fixes a mismatch between the "background" subcommand (which
accepts mode names case-insensitively) and swaybg (which does not,
requiring lowercase).
@mstoeckl mstoeckl force-pushed the simplify-background-mode branch from 524ad00 to 6914a71 Compare February 9, 2025 22:24
Copy link
Member

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me!

The commit keeps the case insensitive parsing behavior, even though it did not work properly before, because many Sway commands already accept keywords case-insensitively. (Some do, some don't; I'm not sure which should be preferred.)

Sounds safer to keep previous behavior (even though if I had to start from scratch I'd probably lean on rejecting strings with a different case).

enum background_mode is AFAIK the first enum without a real _DEFAULT behavior, so I've named the null case _UNSET. Is there an existing convention for this?

I think we use NONE elsewhere, not sure it's exactly the same case? UNSET sounds fine to me regardless.

The background_mode_names table is used in sway/commands/output/background.c (for parsing) and sway/config/output.c (debug output and spawn_swaybg()); I've put it in the former file, but am not certain about the right place for it.

That sounds fine to me.

A similar "parse-instead-of-validating" change may be worth doing for the background color, but most approaches would complicate spawn_swaybg(), which currently allocates an array of pointers to strings with a longer lifespan -- parsing and then reprinting colors would require temporary allocations or per-output_config scratch space to hold the colors. There are other solutions, but none I've found to be clean and simple so far.

We could maybe use a buffer on the stack for the color?

@mstoeckl
Copy link
Contributor Author

We could maybe use a buffer on the stack for the color?

There can be many output_configs and many colors that get passed to swaybg, so storing them all on the stack can potentially overflow it.

@emersion
Copy link
Member

Oh, right, didn't notice the loop! Maybe not worth the trouble then…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants