From 8013f3bef9dda1d169a4a02bab83b710d7a83e3e Mon Sep 17 00:00:00 2001 From: noskb <63541981+noskb@users.noreply.github.com> Date: Tue, 3 Feb 2026 21:20:41 +0000 Subject: [PATCH 1/2] Remove duplicate buttons using xfconf-query In the gnome-based template, xsettingsd was used to remove duplicate buttons. However, since xfce-based templates use xfsettingsd, xfconf-query is called at session startup to perform the same configuration. --- Makefile | 2 ++ .../xdgautostart/qubes-set-xsettings-xfconf-query.desktop | 8 ++++++++ debian/qubes-gui-agent-xfce.install | 3 ++- rpm_spec/gui-agent.spec.in | 1 + 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 appvm-scripts/etc/xdgautostart/qubes-set-xsettings-xfconf-query.desktop diff --git a/Makefile b/Makefile index 582a14fd..df0e0015 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,8 @@ endif $(DESTDIR)/etc/xdg/autostart/qubes-keymap.desktop install -m 0644 -D appvm-scripts/etc/xdgautostart/qubes-gtk4-workarounds.desktop \ $(DESTDIR)/etc/xdg/autostart/qubes-gtk4-workarounds.desktop + install -m 0644 -D appvm-scripts/etc/xdgautostart/qubes-set-xsettings-xfconf-query.desktop \ + $(DESTDIR)/etc/xdg/autostart/qubes-set-xsettings-xfconf-query.desktop install -D -m 0644 appvm-scripts/usr/lib/sysctl.d/30-qubes-gui-agent.conf \ $(DESTDIR)/usr/lib/sysctl.d/30-qubes-gui-agent.conf install -D -m 0644 appvm-scripts/lib/udev/rules.d/70-master-of-seat.rules \ diff --git a/appvm-scripts/etc/xdgautostart/qubes-set-xsettings-xfconf-query.desktop b/appvm-scripts/etc/xdgautostart/qubes-set-xsettings-xfconf-query.desktop new file mode 100644 index 00000000..d126aa12 --- /dev/null +++ b/appvm-scripts/etc/xdgautostart/qubes-set-xsettings-xfconf-query.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Name=xfconf-query for Xfce-based QubesVM +Exec=/usr/bin/xfconf-query --channel xsettings --property /Gtk/DecorationLayout --set "" +Terminal=false +Type=Application +OnlyShowIn=X-QUBES; diff --git a/debian/qubes-gui-agent-xfce.install b/debian/qubes-gui-agent-xfce.install index b701d8c7..089bdd60 100644 --- a/debian/qubes-gui-agent-xfce.install +++ b/debian/qubes-gui-agent-xfce.install @@ -1 +1,2 @@ -etc/X11/Xsession.d/60xfce-desktop \ No newline at end of file +etc/X11/Xsession.d/60xfce-desktop +etc/xdg/autostart/qubes-set-xsettings-xfconf-query.desktop diff --git a/rpm_spec/gui-agent.spec.in b/rpm_spec/gui-agent.spec.in index ac95d997..d158791a 100644 --- a/rpm_spec/gui-agent.spec.in +++ b/rpm_spec/gui-agent.spec.in @@ -364,6 +364,7 @@ rm -f %{name}-%{version} %files xfce %{xinitrc_dir}/60xfce-desktop.sh +/etc/xdg/autostart/qubes-set-xsettings-xfconf-query.desktop %files -n qubes-gui-vnc #/lib/systemd/system/qubes-gui-vncserver.service From 8a86d126da0f48405d9e4101298a2f4c10052422 Mon Sep 17 00:00:00 2001 From: noskb <63541981+noskb@users.noreply.github.com> Date: Sun, 7 Jun 2026 21:05:25 +0000 Subject: [PATCH 2/2] Revert "Merge branch 'QubesOS:main' into qubes-xfconf" This reverts commit 2ed98d0b48923b7b9701297e7cb2100ff3c02d06, reversing changes made to 8013f3bef9dda1d169a4a02bab83b710d7a83e3e. --- Makefile | 4 - .../post-install.d/20-qubes-gui-agent.sh | 4 - appvm-scripts/qubes-gui-agent.service | 1 - appvm-scripts/usrbin/qubes-run-xorg | 9 +- appvm-scripts/usrbin/qubes-session | 4 - appvm-scripts/usrbin/qubes-start-xephyr | 22 +- archlinux/PKGBUILD.in | 1 - debian/changelog | 20 -- debian/control | 2 - debian/qubes-gui-agent.install | 2 - gui-agent/Makefile | 2 +- gui-agent/vmside.c | 222 ++++-------------- rpm_spec/gui-agent.spec.in | 7 - selinux/qubes-gui-agent.fc | 1 - selinux/qubes-gui-agent.te | 8 - version | 2 +- 16 files changed, 52 insertions(+), 259 deletions(-) delete mode 100644 appvm-scripts/etc/qubes/post-install.d/20-qubes-gui-agent.sh diff --git a/Makefile b/Makefile index f6ab267e..df0e0015 100644 --- a/Makefile +++ b/Makefile @@ -168,8 +168,6 @@ install-common: install -d $(DESTDIR)/etc/qubes/post-install.d install -m 0755 appvm-scripts/etc/qubes/post-install.d/20-qubes-guivm-gui-agent.sh \ $(DESTDIR)/etc/qubes/post-install.d/20-qubes-guivm-gui-agent.sh - install -m 0755 appvm-scripts/etc/qubes/post-install.d/20-qubes-gui-agent.sh \ - $(DESTDIR)/etc/qubes/post-install.d/20-qubes-gui-agent.sh install -D appvm-scripts/usrbin/qubes-session \ $(DESTDIR)/usr/bin/qubes-session install -D appvm-scripts/usrbin/qubes-run-xorg \ @@ -213,8 +211,6 @@ endif $(DESTDIR)/etc/qubes-rpc/qubes.SetMonitorLayout ln -sf ../../usr/bin/qubes-start-xephyr \ $(DESTDIR)/etc/qubes-rpc/qubes.GuiVMSession - install -d $(DESTDIR)/etc/qubes/rpc-config - echo "force-user='root'" > $(DESTDIR)/etc/qubes/rpc-config/qubes.GuiVMSession install -D window-icon-updater/icon-sender \ $(DESTDIR)/usr/lib/qubes/icon-sender install -m 0644 -D window-icon-updater/qubes-icon-sender.desktop \ diff --git a/appvm-scripts/etc/qubes/post-install.d/20-qubes-gui-agent.sh b/appvm-scripts/etc/qubes/post-install.d/20-qubes-gui-agent.sh deleted file mode 100644 index e45fd8a2..00000000 --- a/appvm-scripts/etc/qubes/post-install.d/20-qubes-gui-agent.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# announce support for late gui-daemon connection -qvm-features-request supported-feature.late-gui-daemon=1 diff --git a/appvm-scripts/qubes-gui-agent.service b/appvm-scripts/qubes-gui-agent.service index c3684fc8..e7a8db18 100644 --- a/appvm-scripts/qubes-gui-agent.service +++ b/appvm-scripts/qubes-gui-agent.service @@ -9,7 +9,6 @@ TTYPath=/dev/tty7 # custom PATH for X session can be set with ENV_PATH; otherwise service's PATH # is inherited #Environment=ENV_PATH=/usr/local/bin:/usr/bin:/bin -ExecCondition=/bin/sh -c 'test "$(qubesdb-read --default=True /qubes-gui-enabled)" = "True"' ExecStartPre=/bin/sh -c /usr/lib/qubes/qubes-gui-agent-pre.sh ExecStart=/usr/bin/qubes-gui $GUI_OPTS # clean env diff --git a/appvm-scripts/usrbin/qubes-run-xorg b/appvm-scripts/usrbin/qubes-run-xorg index e5ca772f..04a4f828 100755 --- a/appvm-scripts/usrbin/qubes-run-xorg +++ b/appvm-scripts/usrbin/qubes-run-xorg @@ -26,14 +26,7 @@ ## This script is triggered by qubes-gui-agent systemd service. -#expects W, H, MEM and DEPTH env vars to be set by invoker, but use default -# values if they aren't - -[ -n "$W" ] || W=1920 -[ -n "$H" ] || H=1080 -[ -n "$MEM" ] || MEM=$(( W * H * 4 / 1024 )) -[ -n "$DEPTH" ] || DEPTH=24 - +#expects W, H, MEM and DEPTH env vars to be set by invoker DUMMY_MAX_CLOCK=300 #hardcoded in dummy_drv PREFERRED_HSYNC=50 RES="$W"x"$H" diff --git a/appvm-scripts/usrbin/qubes-session b/appvm-scripts/usrbin/qubes-session index 6412e8c7..933520e8 100755 --- a/appvm-scripts/usrbin/qubes-session +++ b/appvm-scripts/usrbin/qubes-session @@ -51,10 +51,6 @@ VMTYPE=$(/usr/bin/qubesdb-read /qubes-vm-type) UPDTYPE=$(/usr/bin/qubesdb-read /qubes-vm-updateable) [[ $UPDTYPE == 'True' ]] && UPDTYPE="UpdateableVM" || UPDTYPE="NonUpdateableVM" -# Sync environment variables from the user session into the systemd user -# manager and dbus-daemon -dbus-update-activation-environment --systemd --all - # process /etc/xdg/autostart and friends (according to Desktop Application # Autostart Specification) /usr/bin/qubes-session-autostart QUBES X-QUBES "X-$VMTYPE" "X-$UPDTYPE" diff --git a/appvm-scripts/usrbin/qubes-start-xephyr b/appvm-scripts/usrbin/qubes-start-xephyr index 884075f8..7911f01b 100644 --- a/appvm-scripts/usrbin/qubes-start-xephyr +++ b/appvm-scripts/usrbin/qubes-start-xephyr @@ -1,15 +1,8 @@ #!/bin/sh -# Start under new service unit, to detach from the current non-gui logind -# session -if [ -z "$INVOCATION_ID" ]; then - exec systemd-run --system \ - --unit=qubes-gui-agent-session.service \ - --description="Start GUI session via Xephyr" \ - --property=TTYPath=/dev/tty8 \ - --property=StandardInput=tty \ - --wait \ - -- "$0" "$@" +if [ $(whoami) == "root" ]; then + echo "Should be run as normal user!" + exit 1 fi # do not let child processes believe they are running as qrexec service @@ -36,11 +29,6 @@ if ! timeout 30s sh -c "while ! xdpyinfo -display $DISPLAY_XORG > /dev/null 2>&1 exit 1 fi -# parameters for logind session -export DISPLAY=$DISPLAY_XEPHYR -export XDG_SEAT=seat0 -export XDG_SESSION_CLASS=user - # Run xsession into Xephyr -user=$(qubesdb-read --default=user /default-user) -exec /usr/bin/qubes-gui-runuser $user /usr/bin/env env DISPLAY=$DISPLAY_XORG /usr/bin/xinit $XSESSION -- /usr/bin/qubes-run-xephyr $DISPLAY_XEPHYR > ~/.xsession-errors 2>&1 +export DISPLAY=$DISPLAY_XORG +exec /usr/bin/xinit $XSESSION -- /usr/bin/qubes-run-xephyr $DISPLAY_XEPHYR > ~/.xsession-errors 2>&1 diff --git a/archlinux/PKGBUILD.in b/archlinux/PKGBUILD.in index fc9b105d..465dc2a3 100644 --- a/archlinux/PKGBUILD.in +++ b/archlinux/PKGBUILD.in @@ -22,7 +22,6 @@ makedepends=( xorg-util-macros libxcomposite libxt - libxcursor libxdamage libunistring pixman diff --git a/debian/changelog b/debian/changelog index 09cc4576..cf483bb2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,23 +1,3 @@ -qubes-gui-agent (4.4.1-1) unstable; urgency=medium - - [ Aaron Rainbolt ] - * Sync environment variables from the user session into systemd and - dbus - - -- Marek Marczykowski-Górecki Fri, 01 May 2026 14:55:53 +0200 - -qubes-gui-agent (4.4.0-1) unstable; urgency=medium - - [ Marek Marczykowski-Górecki ] - * archlinux: relax runtime pulseaudio dependency too - * Delay connecting with gui-daemon until after starting Xorg - * Create status file with info about gui-daemon connection - - [ Ben Grande ] - * Allow preloading without graphics - - -- Marek Marczykowski-Górecki Mon, 16 Mar 2026 18:55:26 +0100 - qubes-gui-agent (4.3.15-1) unstable; urgency=medium * debian: install cvt tool diff --git a/debian/control b/debian/control index 6cf1995c..fba36d9b 100644 --- a/debian/control +++ b/debian/control @@ -14,7 +14,6 @@ Build-Depends: libx11-dev, libgbm-dev, libxcomposite-dev, - libxcursor-dev, libxdamage-dev, libxfixes-dev, x11proto-xf86dga-dev, @@ -43,7 +42,6 @@ Depends: qubesdb-vm (>= 4.1.4), libxdamage1, libxcomposite1, - libxcursor1, libxfixes3, libxt6, libx11-6, diff --git a/debian/qubes-gui-agent.install b/debian/qubes-gui-agent.install index 196c427c..f51cb023 100644 --- a/debian/qubes-gui-agent.install +++ b/debian/qubes-gui-agent.install @@ -10,8 +10,6 @@ etc/security/limits.d/90-qubes-gui.conf etc/qubes-rpc/qubes.SetMonitorLayout etc/qubes-rpc/qubes.GuiVMSession etc/qubes/post-install.d/20-qubes-guivm-gui-agent.sh -etc/qubes/post-install.d/20-qubes-gui-agent.sh -etc/qubes/rpc-config/qubes.GuiVMSession etc/xdg/autostart/qubes-gtk4-workarounds.desktop etc/xdg/autostart/qubes-icon-sender.desktop etc/xdg/autostart/qubes-qrexec-fork-server.desktop diff --git a/gui-agent/Makefile b/gui-agent/Makefile index 4b7b731a..7d270b66 100644 --- a/gui-agent/Makefile +++ b/gui-agent/Makefile @@ -25,7 +25,7 @@ CFLAGS += -I../include/ `pkg-config --cflags vchan` \ -Wmissing-prototypes -Wstrict-prototypes -Wold-style-declaration \ -Wold-style-definition OBJS = vmside.o txrx-vchan.o error.o list.o encoding.o -LIBS = -lX11 -lXdamage -lXcomposite -lXcursor -lXfixes `pkg-config --libs vchan` -lqubesdb \ +LIBS = -lX11 -lXdamage -lXcomposite -lXfixes `pkg-config --libs vchan` -lqubesdb \ -lunistring diff --git a/gui-agent/vmside.c b/gui-agent/vmside.c index 5b8b5c5f..09286c5b 100644 --- a/gui-agent/vmside.c +++ b/gui-agent/vmside.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include "xdriver-shm-cmd.h" @@ -74,8 +73,6 @@ }) + sizeof(x)/sizeof((x)[0])) #define SOCKET_ADDRESS "/var/run/xf86-qubes-socket" -#define STATUS_FILE_PATH "/run/qubes/gui-agent.status" - /* Supported protocol version */ #define PROTOCOL_VERSION_MAJOR 1 @@ -320,14 +317,6 @@ static struct supported_cursor supported_cursors[] = { #define NUM_SUPPORTED_CURSORS (QUBES_ARRAY_SIZE(supported_cursors)) -struct hashed_cursor { - uint64_t hash; - uint32_t cursor_id; -}; - -static struct hashed_cursor *hashed_cursors = NULL; -static size_t num_hashed_cursors = 0; - static int compare_supported_cursors(const void *a, const void *b) { return strcmp(((const struct supported_cursor *)a)->name, ((const struct supported_cursor *)b)->name); @@ -429,94 +418,6 @@ static uint32_t find_cursor(Ghandles *g, Atom atom) return CURSOR_DEFAULT; } -/* - * Some applications don't set cursor names properly when sending XfixesDisplayCursorNotify events, notably Chromium and derivatives. - * Before falling back to CURSOR_DEFAULT, we'll try to match (quick hashes of) the live cursor's bitmap with each supported cursor's bitmap. -**/ - -// Generic Fowler-Noll-Vo quick hash function (FNV-1a), magic mix number from WikiPedia's entry -static uint64_t fnv1a64(const void *data, size_t len, uint64_t seed) { - const uint8_t *p = data; - uint64_t hash = seed; - for (size_t i = 0; i < len; i++) { - hash ^= p[i]; - hash *= 1099511628211ULL; - } - - return hash; -} - -// Specialized FNV-1a hash of a cursor, magic seed number from WikiPedia's entry -static uint64_t hash_cursor(uint32_t w, uint32_t h, - uint32_t xhot, uint32_t yhot, - const uint32_t *pixels) { - uint64_t hash = 14695981039346656037ULL; - - uint32_t hdr[4] = { w, h, xhot, yhot }; - hash = fnv1a64(hdr, sizeof(hdr), hash); - hash = fnv1a64(pixels, (size_t)(w * h * sizeof(uint32_t)), hash); - - return hash; -} - -// Precompute a table of cursor hashes (for a given cursor size) to accelerate matching unnamed cursors -static void precompute_hashed_cursors(Ghandles *g, uint32_t cursor_size) { - char *theme = XcursorGetTheme(g->display); - - free(hashed_cursors); - hashed_cursors = NULL; - num_hashed_cursors = 0; - - hashed_cursors = calloc(NUM_SUPPORTED_CURSORS, sizeof(*hashed_cursors)); - if (!hashed_cursors) return; - - for (size_t i = 0; i < NUM_SUPPORTED_CURSORS; i++) { - XcursorImage *img = XcursorLibraryLoadImage(supported_cursors[i].name, theme, (int)cursor_size); - if (!img) continue; - - hashed_cursors[num_hashed_cursors].hash = hash_cursor(img->width, img->height, img->xhot, img->yhot, img->pixels); - hashed_cursors[num_hashed_cursors].cursor_id = supported_cursors[i].cursor_id; - num_hashed_cursors++; - XcursorImageDestroy(img); - } -} - -// Fallback function to lookup an unnamed cursor by its bitmap -static uint32_t find_cursor_by_image(Ghandles *g) { - XFixesCursorImage *live_img = XFixesGetCursorImage(g->display); - if (!live_img) return CURSOR_DEFAULT; - - // SEC: Abort immediately on suspiciously huge cursors to avoid mallocating too much RAM - if (live_img->width > 512 || live_img->height > 512) { - return CURSOR_DEFAULT; - } - - /* Narrow unsigned long pixels to uint32_t */ - size_t npx = (size_t)live_img->width * live_img->height; - uint32_t *live_px = malloc(npx * sizeof(uint32_t)); - if (!live_px) { - XFree(live_img); - return CURSOR_DEFAULT; - } - for (size_t i = 0; i < npx; i++) live_px[i] = (uint32_t)live_img->pixels[i]; - - uint64_t live_hash = hash_cursor(live_img->width, live_img->height, live_img->xhot, live_img->yhot, live_px); - free(live_px); - XFree(live_img); - - for (size_t i = 0; i < num_hashed_cursors; i++) { - if (hashed_cursors[i].hash == live_hash) { - uint32_t found = CURSOR_X11 + hashed_cursors[i].cursor_id; - if (found >= CURSOR_X11_MAX) { - return CURSOR_DEFAULT; - } - return found; - } - } - - return CURSOR_DEFAULT; -} - static void process_xevent_cursor(Ghandles *g, XFixesCursorNotifyEvent *ev) { if (ev->subtype == XFixesDisplayCursorNotify) { @@ -527,6 +428,7 @@ static void process_xevent_cursor(Ghandles *g, XFixesCursorNotifyEvent *ev) int root_x, root_y, win_x, win_y; unsigned int mask; Bool ret; + int cursor; ret = XQueryPointer(g->display, ev->window, &root, &window_under_pointer, @@ -537,24 +439,7 @@ static void process_xevent_cursor(Ghandles *g, XFixesCursorNotifyEvent *ev) if (!lookup_window(g, windows_list, window_under_pointer, __func__)) return; - uint32_t cursor; - if (ev->cursor_name != None) { - cursor = find_cursor(g, ev->cursor_name); - } else { - // Precompute the table of hashed cursors based on the actual cursor size - if (num_hashed_cursors == 0) { - XFixesCursorImage *live_img = XFixesGetCursorImage(g->display); - if (live_img) { - uint32_t size = (live_img->width > live_img->height) ? live_img->width : live_img->height; - XFree(live_img); - fprintf(stderr, "Precomputing hashed cursors to accelerate subsequent lookups"); - precompute_hashed_cursors(g, size); - } - } - - cursor = find_cursor_by_image(g); - } - + cursor = find_cursor(g, ev->cursor_name); send_cursor(g, window_under_pointer, cursor); } } @@ -2291,11 +2176,12 @@ static void handle_close(Ghandles * g, XID winid) /* start X server, returns its PID */ -static pid_t do_execute_xorg(Ghandles *g) +static pid_t do_execute_xorg( + char *w_str, char *h_str, char *mem_str, char *depth_str, + char *gui_domid_str) { pid_t pid; int fd; - char gui_domid_str[12]; pid = fork(); switch (pid) { @@ -2303,7 +2189,10 @@ static pid_t do_execute_xorg(Ghandles *g) perror("fork"); return -1; case 0: - snprintf(gui_domid_str, sizeof(gui_domid_str), "%u", g->domid); + setenv("W", w_str, 1); + setenv("H", h_str, 1); + setenv("MEM", mem_str, 1); + setenv("DEPTH", depth_str, 1); setenv("GUI_DOMID", gui_domid_str, 1); /* don't leak other FDs */ for (fd = 3; fd < 256; fd++) @@ -2485,11 +2374,27 @@ static void handle_message(Ghandles * g) } } -static void handshake(Ghandles *g) +static pid_t get_xconf_and_run_x(Ghandles *g) { - uint32_t version = PROTOCOL_VERSION; struct msg_xconf xconf; + char w_str[12], h_str[12], mem_str[12], depth_str[12], gui_domid_str[12]; + pid_t x_pid; + read_struct(g->vchan, xconf); + snprintf(w_str, sizeof(w_str), "%d", xconf.w); + snprintf(h_str, sizeof(h_str), "%d", xconf.h); + snprintf(mem_str, sizeof(mem_str), "%d", xconf.mem); + snprintf(depth_str, sizeof(depth_str), "%d", xconf.depth); + snprintf(gui_domid_str, sizeof(gui_domid_str), "%u", g->domid); + x_pid = do_execute_xorg(w_str, h_str, mem_str, depth_str, gui_domid_str); + if (x_pid == (pid_t)-1) { + errx(1, "X server startup failed"); + } + return x_pid; +} +static void handshake(Ghandles *g) +{ + uint32_t version = PROTOCOL_VERSION; write_struct(g->vchan, version); version = 0; read_struct(g->vchan, version); @@ -2502,54 +2407,27 @@ static void handshake(Ghandles *g) PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR, major_version, minor_version); g->protocol_version = version; - - /* discard */ - read_struct(g->vchan, xconf); -} - -static void write_status_file(const char *status) -{ - int fd = open(STATUS_FILE_PATH, O_CREAT | O_WRONLY | O_NOFOLLOW | O_TRUNC, 0644); - if (fd < 0) { - perror("open status file"); - return; - } - FILE *f = fdopen(fd, "w"); - if (!f) { - perror("fdopen status file"); - close(fd); - return; - } - if (fwrite(status, strlen(status), 1, f) != 1) { - perror("write error"); - } - fclose(f); - close(fd); -} - -static void cleanup_status_file(void) -{ - unlink(STATUS_FILE_PATH); } static void handle_guid_disconnect(void) { Ghandles *g = ghandles_for_vchan_reinitialize; + struct msg_xconf xconf; if (!ghandles_for_vchan_reinitialize) { fprintf(stderr, "gui-daemon disconnected before fully initialized, " "cannot reconnect, exiting!\n"); exit(1); } - write_status_file("started\n"); libvchan_close(g->vchan); g->vchan = libvchan_server_init(g->domid, 6000, 4096, 4096); /* wait for gui daemon */ while (libvchan_is_open(g->vchan) == VCHAN_WAITING) libvchan_wait(g->vchan); handshake(g); + /* discard */ + read_struct(g->vchan, xconf); send_all_windows_info(g); - write_status_file("connected\n"); } static _Noreturn void handle_sigterm(int UNUSED(sig), @@ -2640,9 +2518,6 @@ int main(int argc, char **argv) int xfd; Ghandles g = { .x_pid = -1 }; - write_status_file("starting\n"); - atexit(cleanup_status_file); - g.created_input_device = access("/run/qubes-service/gui-agent-virtual-input-device", F_OK) == 0; if(g.created_input_device) { @@ -2696,6 +2571,7 @@ int main(int argc, char **argv) g.last_known_modifier_states = 0; } + parse_args(&g, argc, argv); /* Clipboard wipe functionality is controlled by the @@ -2704,8 +2580,18 @@ int main(int argc, char **argv) g.clipboard_wipe = access("/run/qubes-service/gui-agent-clipboard-wipe", F_OK) == 0; - ghandles_for_vchan_reinitialize = &g; + g.vchan = libvchan_server_init(g.domid, 6000, 4096, 4096); + if (!g.vchan) { + fprintf(stderr, "vchan initialization failed\n"); + exit(1); + } + /* wait for gui daemon */ + while (libvchan_is_open(g.vchan) == VCHAN_WAITING) + libvchan_wait(g.vchan); + saved_argv = argv; + vchan_register_at_eof(handle_guid_disconnect); + ghandles_for_vchan_reinitialize = &g; struct sigaction sigchld_handler = { .sa_sigaction = handle_sigchld, .sa_flags = SA_SIGINFO, @@ -2721,10 +2607,8 @@ int main(int argc, char **argv) if (sigaction(SIGTERM, &sigterm_handler, NULL)) err(1, "sigaction"); - g.x_pid = do_execute_xorg(&g); - if (g.x_pid == (pid_t)-1) { - errx(1, "X server startup failed"); - } + handshake(&g); + g.x_pid = get_xconf_and_run_x(&g); mkghandles(&g); /* Turn on Composite for all children of root window. This way X server @@ -2793,24 +2677,6 @@ int main(int argc, char **argv) fprintf(stderr, "Acquired MANAGER selection for tray\n"); } - - write_status_file("started\n"); - - g.vchan = libvchan_server_init(g.domid, 6000, 4096, 4096); - if (!g.vchan) { - fprintf(stderr, "vchan initialization failed\n"); - exit(1); - } - /* wait for gui daemon */ - while (libvchan_is_open(g.vchan) == VCHAN_WAITING) - libvchan_wait(g.vchan); - saved_argv = argv; - vchan_register_at_eof(handle_guid_disconnect); - - handshake(&g); - - write_status_file("connected\n"); - xfd = ConnectionNumber(g.display); struct pollfd fds[] = { { .fd = -1, .events = POLLIN | POLLHUP, .revents = 0 }, diff --git a/rpm_spec/gui-agent.spec.in b/rpm_spec/gui-agent.spec.in index 8bbe0606..d158791a 100644 --- a/rpm_spec/gui-agent.spec.in +++ b/rpm_spec/gui-agent.spec.in @@ -54,7 +54,6 @@ URL: https://www.qubes-os.org BuildRequires: gcc BuildRequires: libX11-devel BuildRequires: libXcomposite-devel -BuildRequires: libXcursor-devel BuildRequires: libXdamage-devel BuildRequires: libXfixes-devel BuildRequires: libXt-devel @@ -77,11 +76,7 @@ BuildRequires: qubes-db-devel BuildRequires: xen-devel BuildRequires: systemd-rpm-macros BuildRequires: libunistring-devel -%if 0%{?is_opensuse} -BuildRequires: dbus-1-devel -%else BuildRequires: dbus-devel -%endif %if 0%{?is_opensuse} # for directory ownership BuildRequires: xinit @@ -320,8 +315,6 @@ rm -f %{name}-%{version} /etc/qubes-rpc/qubes.SetMonitorLayout /etc/qubes-rpc/qubes.GuiVMSession /etc/qubes/post-install.d/20-qubes-guivm-gui-agent.sh -/etc/qubes/post-install.d/20-qubes-gui-agent.sh -/etc/qubes/rpc-config/qubes.GuiVMSession %if 0%{?is_opensuse} %{_fillupdir}/desktop.qubes-gui-agent %else diff --git a/selinux/qubes-gui-agent.fc b/selinux/qubes-gui-agent.fc index afc9da47..04ab6504 100644 --- a/selinux/qubes-gui-agent.fc +++ b/selinux/qubes-gui-agent.fc @@ -2,4 +2,3 @@ /usr/bin/qubes-gui-runuser -- gen_context(system_u:object_r:xdm_exec_t,s0) /usr/lib/qubes/qubes-xorg-wrapper -- gen_context(system_u:object_r:xserver_exec_t,s0) /usr/bin/qubes-run-xephyr -- gen_context(system_u:object_r:xserver_exec_t,s0) -/run/qubes/gui-agent.status -- gen_context(system_u:object_r:qubes_gui_agent_state_file_t,s0) diff --git a/selinux/qubes-gui-agent.te b/selinux/qubes-gui-agent.te index dca69509..7b1755c6 100644 --- a/selinux/qubes-gui-agent.te +++ b/selinux/qubes-gui-agent.te @@ -7,9 +7,6 @@ require { class tcp_socket name_connect; } -type qubes_gui_agent_state_file_t; -files_type(qubes_gui_agent_state_file_t) - allow xdm_t etc_t:file { create write }; allow xdm_t self:passwd rootok; allow domain local_login_t:unix_stream_socket { rw_inherited_sock_file_perms ioctl }; @@ -19,11 +16,6 @@ init_domtrans_script(xdm_t) type_transition xdm_t qubes_var_run_t:sock_file qubes_qrexec_socket_t; manage_sock_files_pattern(xdm_t, qubes_var_run_t, qubes_qrexec_socket_t) write_sock_files_pattern(xdm_t, qubes_var_run_t, qubes_var_run_t) - -allow xdm_t qubes_gui_agent_state_file_t:file { create_file_perms write_file_perms delete_file_perms }; -allow xdm_t qubes_var_run_t:dir { add_entry_dir_perms del_entry_dir_perms }; -filetrans_pattern(xdm_t, qubes_var_run_t, qubes_gui_agent_state_file_t, file, "gui-agent.status") - optional { pulseaudio_domtrans(xdm_t) dev_rw_xen(pulseaudio_t) diff --git a/version b/version index cca25a93..68a3729d 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.4.1 +4.3.15