--- src/vdagent/x11-priv.h | 1 + src/vdagent/x11-seamless-mode.c | 33 ++++++++++++++++++++++++++++++++- src/vdagent/x11.c | 13 +++++++++---- src/vdagentd-proto-strings.h | 1 + src/vdagentd-proto.h | 1 + src/vdagentd/vdagentd.c | 5 +++++ 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/vdagent/x11-priv.h b/src/vdagent/x11-priv.h index c264dd3..dc8d119 100644 --- a/src/vdagent/x11-priv.h +++ b/src/vdagent/x11-priv.h @@ -157,5 +157,6 @@ int vdagent_x11_debug_error_handler(Display *display, XErrorEvent *error); int vdagent_x11_ignore_bad_window_handler(Display *display, XErrorEvent *error); void vdagent_x11_seamless_mode_send_list(struct vdagent_x11 *x11); +void vdagent_x11_seamless_mode_send_change(struct vdagent_x11 *x11, Window window); #endif // VDAGENT_X11_PRIV diff --git a/src/vdagent/x11-seamless-mode.c b/src/vdagent/x11-seamless-mode.c index a664c6a..9c4deba 100644 --- a/src/vdagent/x11-seamless-mode.c +++ b/src/vdagent/x11-seamless-mode.c @@ -204,7 +204,7 @@ get_window_list(struct vdagent_x11 *x11, Window window) g_free(spice_window); continue; } - + spice_window->id = (uint64_t)list[i]; window_list = g_list_append(window_list, spice_window); } @@ -245,6 +245,7 @@ vdagent_x11_seamless_mode_send_list(struct vdagent_x11 *x11) list->windows[list->num_of_windows].y = window->y; list->windows[list->num_of_windows].w = window->w; list->windows[list->num_of_windows].h = window->h; + list->windows[list->num_of_windows].id = window->id; list->num_of_windows++; } @@ -254,3 +255,33 @@ vdagent_x11_seamless_mode_send_list(struct vdagent_x11 *x11) udscs_write(x11->vdagentd, VDAGENTD_SEAMLESS_MODE_LIST, 0, 0, (uint8_t *)list, size); } + +void vdagent_x11_seamless_mode_send_change(struct vdagent_x11 *x11, Window window) +{ + VDAgentSeamlessModeWindow win; + GList *window_list, *l; + + if (!x11->seamless_mode) + return; + + if (is_visible(x11->display, window)) { + get_geometry(x11->display, window, &win); + + if (vdagent_x11_restore_error_handler(x11) != 0) { + vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler); + return; + } + + win.id = (uint64_t)window; + udscs_write(x11->vdagentd, VDAGENTD_SEAMLESS_MODE_CHANGE, 0, 0, + (uint8_t *)&win, sizeof(VDAgentSeamlessModeWindow)); + + } else { + window_list = get_window_list(x11, window); + for (l = window_list; l != NULL; l = l->next) { + udscs_write(x11->vdagentd, VDAGENTD_SEAMLESS_MODE_CHANGE, 0, 0, + (uint8_t *)l->data, sizeof(VDAgentSeamlessModeWindow)); + } + g_list_free_full(window_list, (GDestroyNotify)g_free); + } +} diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c index 5441792..f8d0fff 100644 --- a/src/vdagent/x11.c +++ b/src/vdagent/x11.c @@ -521,20 +521,25 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) event.xconfigure.width, event.xconfigure.height); } - vdagent_x11_seamless_mode_send_list(x11); + vdagent_x11_seamless_mode_send_change(x11, event.xconfigure.window); handled = 1; break; case MappingNotify: + vdagent_x11_seamless_mode_send_list(x11); + handled = 1; + break; case CreateNotify: case CirculateNotify: - case DestroyNotify: case GravityNotify: case MapNotify: case ReparentNotify: case UnmapNotify: + vdagent_x11_seamless_mode_send_change(x11, event.xany.window); + handled = 1; + break; + case DestroyNotify: vdagent_x11_seamless_mode_send_list(x11); - handled = 1; break; case ClientMessage: @@ -561,7 +566,7 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) /* Always mark as handled, since we cannot unselect input for property notifications once we are done with handling the incr transfer. */ - vdagent_x11_seamless_mode_send_list(x11); + vdagent_x11_seamless_mode_send_change(x11, event.xproperty.window); handled = 1; break; diff --git a/src/vdagentd-proto-strings.h b/src/vdagentd-proto-strings.h index 8f8a58b..24fa3e8 100644 --- a/src/vdagentd-proto-strings.h +++ b/src/vdagentd-proto-strings.h @@ -37,6 +37,7 @@ static const char * const vdagentd_messages[] = { "file xfer disable", "seamless mode", "seamless mode list", + "seamless mode change", "client disconnected", }; diff --git a/src/vdagentd-proto.h b/src/vdagentd-proto.h index 4657a19..1d734d3 100644 --- a/src/vdagentd-proto.h +++ b/src/vdagentd-proto.h @@ -45,6 +45,7 @@ enum { VDAGENTD_FILE_XFER_DISABLE, VDAGENTD_SEAMLESS_MODE, VDAGENTD_SEAMLESS_MODE_LIST, + VDAGENTD_SEAMLESS_MODE_CHANGE, VDAGENTD_CLIENT_DISCONNECTED, /* daemon -> client */ VDAGENTD_NO_MESSAGES /* Must always be last */ }; diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c index 14d15b5..9a39696 100644 --- a/src/vdagentd/vdagentd.c +++ b/src/vdagentd/vdagentd.c @@ -943,6 +943,11 @@ static void agent_read_complete(struct udscs_connection **connp, VD_AGENT_SEAMLESS_MODE_LIST, 0, data, header->size); break; + case VDAGENTD_SEAMLESS_MODE_CHANGE: + vdagent_virtio_port_write(virtio_port, VDP_CLIENT_PORT, + VD_AGENT_SEAMLESS_MODE_CHANGE, 0, + data, header->size); + break; default: syslog(LOG_ERR, "unknown message from vdagent: %u, ignoring", -- 2.13.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel