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

Add window_background_color config setting #144

Merged
merged 2 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions gui-daemon/guid.conf
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ global: {
#
# trayicon_mode = "border1";

# Set the fill color to be shown in a window when content is pending or
# unavailable. This is rarely visible except very briefly. Possible values are
# a color name (see: /etc/X11/rgb.txt) or a specification in format 0xRRGGBB.
# When running a dark-styled desktop theme, "black" is recommended.
#
# window_background_color = "white";

# Timeout when waiting for qubes-gui-agent
#
# startup_timeout = 45;
Expand Down
75 changes: 58 additions & 17 deletions gui-daemon/xside.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,27 +283,59 @@ static int x11_io_error_handler(Display * dpy)
exit(1);
}

/*
* Infer a color value from the provided string using strtoul for
* hex-like input or for a name Xlib by way of /etc/X11/rgb.txt.
*/
static XColor parse_color(const char *str, Display *dpy, int screen)
{
XColor xcolor;
Status status;
char *trimmed = (char *) str;
while (trimmed[0] == ' ') { /* skip any leading spaces */
trimmed++;
}
if (trimmed[0] == '0' && (trimmed[1] == 'x' || trimmed[1] == 'X')) {
char *endptr;
unsigned int rgb;
errno = 0;
rgb = strtoul(trimmed, &endptr, 16);
if (errno) {
perror("strtoul");
fprintf(stderr, "Failed to parse color '%s'\n", trimmed);
exit(1);
} else if (endptr == trimmed ||
/* Note: this check incorrectly rejects the
specific case of trailing space on hex black,
i.e. '0x000000 ' */
(endptr[0] != '\0' && rgb == 0)) {
fprintf(stderr, "Failed to parse color '%s'\n", trimmed);
exit(1);
}
xcolor.blue = (rgb & 0xff) * 257;
rgb >>= 8;
xcolor.green = (rgb & 0xff) * 257;
rgb >>= 8;
xcolor.red = (rgb & 0xff) * 257;
status = XAllocColor(dpy, XDefaultColormap(dpy, screen), &xcolor);
} else {
XColor dummy;
status = XAllocNamedColor(dpy, XDefaultColormap(dpy, screen), trimmed,
&xcolor, &dummy);
}
if (status == 0) {
fprintf(stderr, "Failed to allocate color when parsing '%s'\n", trimmed);
exit(1);
}
return xcolor;
}

/* prepare graphic context for painting colorful frame and set RGB value of the
* color */
static void get_frame_gc(Ghandles * g, const char *name)
{
XGCValues values;
XColor fcolor, dummy;
if (name[0] == '0' && (name[1] == 'x' || name[1] == 'X')) {
unsigned int rgb = strtoul(name, 0, 16);
fcolor.blue = (rgb & 0xff) * 257;
rgb >>= 8;
fcolor.green = (rgb & 0xff) * 257;
rgb >>= 8;
fcolor.red = (rgb & 0xff) * 257;
XAllocColor(g->display,
XDefaultColormap(g->display, g->screen),
&fcolor);
} else
XAllocNamedColor(g->display,
XDefaultColormap(g->display, g->screen),
name, &fcolor, &dummy);
XColor fcolor = parse_color(name, g->display, g->screen);
g->label_color_rgb =
(fcolor.red >> 8) << 16 |
(fcolor.green >> 8) << 8 |
Expand All @@ -329,7 +361,7 @@ static Window mkwindow(Ghandles * g, struct windowdata *vm_window)
my_size_hints.height = vm_window->height;

attr.override_redirect = vm_window->override_redirect;
attr.background_pixel = WhitePixel(g->display, DefaultScreen(g->display));
attr.background_pixel = g->window_background_pixel;
child_win = XCreateWindow(g->display, g->root_win,
vm_window->x, vm_window->y,
vm_window->width,
Expand Down Expand Up @@ -658,6 +690,9 @@ static void mkghandles(Ghandles * g)
else if (g->trayicon_mode == TRAY_TINT)
init_tray_tint(g);
/* nothing extra needed for TRAY_BORDER */
/* parse window background color */
g->window_background_pixel = parse_color(g->window_background_color_pre_parse,
g->display, g->screen).pixel;
/* parse -p arguments now, as we have X server connection */
parse_cmdline_prop(g);
/* init window lists */
Expand Down Expand Up @@ -3759,7 +3794,7 @@ static void usage(FILE *stream)
fprintf(stream, " --domid=ID, -d ID\tdomain ID running GUI agent\n");
fprintf(stream, " --target-domid=ID, -t ID\tdomain ID of actual VM (may be different from --domid in case of stubdomain)\n");
fprintf(stream, " --name=NAME, -N NAME\tVM name\n");
fprintf(stream, " --color=COLOR, -c COLOR\tVM color (in format 0xRRGGBB)\n");
fprintf(stream, " --color=COLOR, -c COLOR\tVM color (format 0xRRGGBB or color name)\n");
fprintf(stream, " --label=LABEL_INDEX, -l LABEL_INDEX\tVM label index\n");
fprintf(stream, " --icon=ICON, -i ICON\tIcon name (without suffix), or full icon path\n");
fprintf(stream, " --qrexec-for-clipboard, -Q\tforce usage of Qrexec for clipboard operations\n");
Expand Down Expand Up @@ -4091,6 +4126,7 @@ static void load_default_config_values(Ghandles * g)
g->trayicon_border = 0;
g->trayicon_tint_reduce_saturation = 0;
g->trayicon_tint_whitehack = 0;
g->window_background_color_pre_parse = "white";
}

// parse string describing key sequence like Ctrl-Alt-c
Expand Down Expand Up @@ -4179,6 +4215,11 @@ static void parse_vm_config(Ghandles * g, config_setting_t * group)
parse_trayicon_mode(g, config_setting_get_string(setting));
}

if ((setting =
config_setting_get_member(group, "window_background_color"))) {
g->window_background_color_pre_parse = config_setting_get_string(setting);
}

if ((setting =
config_setting_get_member(group, "startup_timeout"))) {
g->startup_timeout = config_setting_get_int(setting);
Expand Down
2 changes: 2 additions & 0 deletions gui-daemon/xside.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ struct _global_handles {
int trayicon_border; /* position of trayicon border - 0 - no border, 1 - at the edges, 2 - 1px from the edges */
bool trayicon_tint_reduce_saturation; /* reduce trayicon saturation by 50% (available only for "tint" mode) */
bool trayicon_tint_whitehack; /* replace white pixels with almost-white 0xfefefe (available only for "tint" mode) */
const char *window_background_color_pre_parse; /* user-provided description of window background pixel */
unsigned long window_background_pixel; /* parsed version of the above */
bool disable_override_redirect; /* Disable “override redirect” windows */
char *screensaver_names[MAX_SCREENSAVER_NAMES]; /* WM_CLASS names for windows detected as screensavers */
Cursor *cursors; /* preloaded cursors (using XCreateFontCursor) */
Expand Down