From: Jakub Janků <jjanku@xxxxxxxxxx> This code using Xlib was removed by commit "x11: retrieve _NET_WM_NAME using GDK" a4f5c7dcb6579f61434a443e537641f91da6cb8c. Bring it back to make GTK+ optional for now. --- src/vdagent/vdagent.c | 6 ++-- src/vdagent/x11.c | 85 +++++++++++++++++++++++++++++++++++++++++++++------ src/vdagent/x11.h | 2 +- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c index 6bd52fa..6a20429 100644 --- a/src/vdagent/vdagent.c +++ b/src/vdagent/vdagent.c @@ -111,7 +111,7 @@ static const gchar *xfer_get_download_directory(VDAgent *agent) return fx_dir; } - return g_get_user_special_dir(vdagent_x11_has_icons_on_desktop() ? + return g_get_user_special_dir(vdagent_x11_has_icons_on_desktop(agent->x11) ? G_USER_DIRECTORY_DESKTOP : G_USER_DIRECTORY_DOWNLOAD); } @@ -140,7 +140,9 @@ static gboolean vdagent_init_file_xfer(VDAgent *agent) return FALSE; } - open_dir = fx_open_dir == -1 ? !vdagent_x11_has_icons_on_desktop() : fx_open_dir; + open_dir = fx_open_dir == -1 ? + !vdagent_x11_has_icons_on_desktop(agent->x11) : + fx_open_dir; agent->xfers = vdagent_file_xfers_create(agent->conn, xfer_dir, open_dir, debug); diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c index e6c3e9e..ee148ae 100644 --- a/src/vdagent/x11.c +++ b/src/vdagent/x11.c @@ -121,15 +121,77 @@ int vdagent_x11_restore_error_handler(struct vdagent_x11 *x11) return error; } -static const gchar *vdagent_x11_get_wm_name() +static gchar *vdagent_x11_get_wm_name(struct vdagent_x11 *x11) { #ifdef GDK_WINDOWING_X11 GdkDisplay *display = gdk_display_get_default(); if (GDK_IS_X11_DISPLAY(display)) - return gdk_x11_screen_get_window_manager_name( - gdk_display_get_default_screen(display)); + return g_strdup(gdk_x11_screen_get_window_manager_name( + gdk_display_get_default_screen(display))); + return g_strdup("unsupported"); +#else + Atom type_ret; + int format_ret; + unsigned long len, remain; + unsigned char *data = NULL; + Window sup_window = None; + gchar *net_wm_name = NULL; + + /* XGetWindowProperty can throw a BadWindow error. One way we can trigger + this is when the display-manager (ie gdm) has set, and not cleared the + _NET_SUPPORTING_WM_CHECK property, and the window manager running in + the user session has not yet updated it to point to its window, so its + pointing to a nonexistent window. */ + vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler); + + /* Get the window manager SUPPORTING_WM_CHECK window */ + if (XGetWindowProperty(x11->display, x11->root_window[0], + XInternAtom(x11->display, "_NET_SUPPORTING_WM_CHECK", False), 0, + LONG_MAX, False, XA_WINDOW, &type_ret, &format_ret, &len, + &remain, &data) == Success) { + if (type_ret == XA_WINDOW) + sup_window = *((Window *)data); + XFree(data); + } + if (sup_window == None && + XGetWindowProperty(x11->display, x11->root_window[0], + XInternAtom(x11->display, "_WIN_SUPPORTING_WM_CHECK", False), 0, + LONG_MAX, False, XA_CARDINAL, &type_ret, &format_ret, &len, + &remain, &data) == Success) { + if (type_ret == XA_CARDINAL) + sup_window = *((Window *)data); + XFree(data); + } + /* So that we can get the net_wm_name */ + if (sup_window != None) { + Atom utf8 = XInternAtom(x11->display, "UTF8_STRING", False); + if (XGetWindowProperty(x11->display, sup_window, + XInternAtom(x11->display, "_NET_WM_NAME", False), 0, + LONG_MAX, False, utf8, &type_ret, &format_ret, &len, + &remain, &data) == Success) { + if (type_ret == utf8) { + net_wm_name = g_strndup((char *)data, (format_ret / 8) * len); + } + XFree(data); + } + if (net_wm_name == NULL && + XGetWindowProperty(x11->display, sup_window, + XInternAtom(x11->display, "_NET_WM_NAME", False), 0, + LONG_MAX, False, XA_STRING, &type_ret, &format_ret, &len, + &remain, &data) == Success) { + if (type_ret == XA_STRING) { + net_wm_name = g_strndup((char *)data, (format_ret / 8) * len); + } + XFree(data); + } + } + + vdagent_x11_restore_error_handler(x11); + + if (net_wm_name == NULL) + return g_strdup("unknown"); + return net_wm_name; #endif - return "unsupported"; } struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd, @@ -138,7 +200,7 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd, struct vdagent_x11 *x11; XWindowAttributes attrib; int i, j, major, minor; - const gchar *net_wm_name; + gchar *net_wm_name = NULL; x11 = calloc(1, sizeof(*x11)); if (!x11) { @@ -238,7 +300,8 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd, /* Since we are started at the same time as the wm, sometimes we need to wait a bit for the _NET_WM_NAME to show up. */ for (i = 0; i < 9; i++) { - net_wm_name = vdagent_x11_get_wm_name(); + g_free(net_wm_name); + net_wm_name = vdagent_x11_get_wm_name(x11); if (strcmp(net_wm_name, "unknown")) break; usleep(100000); @@ -246,6 +309,7 @@ struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd, if (x11->debug) syslog(LOG_DEBUG, "%s: net_wm_name=\"%s\", has icons=%d", __func__, net_wm_name, vdagent_x11_has_icons_on_desktop(x11)); + g_free(net_wm_name); /* Flush output buffers and consume any pending events */ vdagent_x11_do_read(x11); @@ -1296,7 +1360,7 @@ void vdagent_x11_client_disconnected(struct vdagent_x11 *x11) whitelist approach, so any unknown desktop will end up with saving file-xfers to the xdg download dir, and opening the xdg download dir with xdg-open when the file-xfer completes. */ -int vdagent_x11_has_icons_on_desktop() +int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11) { const char * const wms_with_icons_on_desktop[] = { "Metacity", /* GNOME-2 or GNOME-3 fallback */ @@ -1305,12 +1369,15 @@ int vdagent_x11_has_icons_on_desktop() "Metacity (Marco)", /* Mate, newer */ NULL }; - const gchar *net_wm_name = vdagent_x11_get_wm_name(); + gchar *net_wm_name = vdagent_x11_get_wm_name(x11); int i; for (i = 0; wms_with_icons_on_desktop[i]; i++) - if (!strcmp(net_wm_name, wms_with_icons_on_desktop[i])) + if (!strcmp(net_wm_name, wms_with_icons_on_desktop[i])) { + g_free(net_wm_name); return 1; + } + g_free(net_wm_name); return 0; } diff --git a/src/vdagent/x11.h b/src/vdagent/x11.h index a8ceb08..4fd0380 100644 --- a/src/vdagent/x11.h +++ b/src/vdagent/x11.h @@ -48,6 +48,6 @@ void vdagent_x11_clipboard_release(struct vdagent_x11 *x11, uint8_t selection); void vdagent_x11_client_disconnected(struct vdagent_x11 *x11); -int vdagent_x11_has_icons_on_desktop(); +int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11); #endif -- 2.14.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel