From: Oliver Kurth Date: Tue, 5 Jun 2018 22:47:35 +0000 (-0700) Subject: [Wayland DnD] Part3: Update the Drag Detection Window and Use UInput in DnDUIX11 X-Git-Tag: stable-11.0.0~562 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f00ecc833139a651edf936d7b4c01bfd1504908f;p=thirdparty%2Fopen-vm-tools.git [Wayland DnD] Part3: Update the Drag Detection Window and Use UInput in DnDUIX11 Two changes in this patch: 1. Changes the class DragDetWnd to template class. Currently the DragDetWnd inherits from Gtk::Invisible, but Gtk::Invisible doesn't work for Wayland, it seems this is a bug for Wayland and maybe it will be fixed sometime. So, changes the DragDetWnd to template class, and it will inherit from Gtk::Invisible for X11 and inherit from Gtk::Window for Wayland. 2. Uses UInput to simulate mouse motion in class DuDUIX11. This patch is part of the new feature 'Wayland support in Linux guest'. --- diff --git a/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp b/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp index 21387b85d..d74092459 100644 --- a/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp +++ b/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2009-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2009-2018 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -47,6 +47,7 @@ extern "C" { #include "rpcout.h" } +#include "fakeMouseWayland/fakeMouseWayland.h" #include "dnd.h" #include "dndMsg.h" #include "hostinfo.h" @@ -89,7 +90,8 @@ DnDUIX11::DnDUIX11(ToolsAppCtx *ctx) mNumPendingRequest(0), mDestDropTime(0), mTotalFileSize(0), - mOrigin(0, 0) + mOrigin(0, 0), + mUseUInput(false) { TRACE_CALL(); @@ -103,6 +105,17 @@ DnDUIX11::DnDUIX11(ToolsAppCtx *ctx) * corners for now. */ OnWorkAreaChanged(Gdk::Screen::get_default()); + + //Initialize the uinput device if available + if (ctx->uinputFD != -1) { + Screen * scrn = DefaultScreenOfDisplay(XOpenDisplay(NULL)); + if (FakeMouse_Init(ctx->uinputFD, scrn->width, scrn->height)) { + mUseUInput = true; + mScreenWidth = scrn->width; + mScreenHeight = scrn->height; + } + } + g_debug("%s: Use UInput? %d.\n", __FUNCTION__, mUseUInput); } @@ -202,19 +215,19 @@ DnDUIX11::Init() CONNECT_SIGNAL(mDnD, updateUnityDetWndChanged, OnUpdateUnityDetWnd); /* Set Gtk+ callbacks for source. */ - CONNECT_SIGNAL(mDetWnd, signal_drag_begin(), OnGtkDragBegin); - CONNECT_SIGNAL(mDetWnd, signal_drag_data_get(), OnGtkDragDataGet); - CONNECT_SIGNAL(mDetWnd, signal_drag_end(), OnGtkDragEnd); - CONNECT_SIGNAL(mDetWnd, signal_enter_notify_event(), GtkEnterEventCB); - CONNECT_SIGNAL(mDetWnd, signal_leave_notify_event(), GtkLeaveEventCB); - CONNECT_SIGNAL(mDetWnd, signal_map_event(), GtkMapEventCB); - CONNECT_SIGNAL(mDetWnd, signal_unmap_event(), GtkUnmapEventCB); - CONNECT_SIGNAL(mDetWnd, signal_realize(), GtkRealizeEventCB); - CONNECT_SIGNAL(mDetWnd, signal_unrealize(), GtkUnrealizeEventCB); - CONNECT_SIGNAL(mDetWnd, signal_motion_notify_event(), GtkMotionNotifyEventCB); - CONNECT_SIGNAL(mDetWnd, signal_configure_event(), GtkConfigureEventCB); - CONNECT_SIGNAL(mDetWnd, signal_button_press_event(), GtkButtonPressEventCB); - CONNECT_SIGNAL(mDetWnd, signal_button_release_event(), GtkButtonReleaseEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_drag_begin(), OnGtkDragBegin); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_drag_data_get(), OnGtkDragDataGet); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_drag_end(), OnGtkDragEnd); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_enter_notify_event(), GtkEnterEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_leave_notify_event(), GtkLeaveEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_map_event(), GtkMapEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_unmap_event(), GtkUnmapEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_realize(), GtkRealizeEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_unrealize(), GtkUnrealizeEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_motion_notify_event(), GtkMotionNotifyEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_configure_event(), GtkConfigureEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_button_press_event(), GtkButtonPressEventCB); + CONNECT_SIGNAL(mDetWnd->GetWnd(), signal_button_release_event(), GtkButtonReleaseEventCB); #undef CONNECT_SIGNAL @@ -281,16 +294,16 @@ DnDUIX11::InitGtk() * but in our case, we will call drag_get_data during DragMotion, and * will cause X dead with DEST_DEFAULT_ALL. The reason is unclear. */ - mDetWnd->drag_dest_set(targets, Gtk::DEST_DEFAULT_MOTION, - Gdk::ACTION_COPY | Gdk::ACTION_MOVE); + mDetWnd->GetWnd()->drag_dest_set(targets, Gtk::DEST_DEFAULT_MOTION, + Gdk::ACTION_COPY | Gdk::ACTION_MOVE); - mDetWnd->signal_drag_leave().connect( + mDetWnd->GetWnd()->signal_drag_leave().connect( sigc::mem_fun(this, &DnDUIX11::OnGtkDragLeave)); - mDetWnd->signal_drag_motion().connect( + mDetWnd->GetWnd()->signal_drag_motion().connect( sigc::mem_fun(this, &DnDUIX11::OnGtkDragMotion)); - mDetWnd->signal_drag_drop().connect( + mDetWnd->GetWnd()->signal_drag_drop().connect( sigc::mem_fun(this, &DnDUIX11::OnGtkDragDrop)); - mDetWnd->signal_drag_data_received().connect( + mDetWnd->GetWnd()->signal_drag_data_received().connect( sigc::mem_fun(this, &DnDUIX11::OnGtkDragDataReceived)); } @@ -351,19 +364,42 @@ DnDUIX11::OnSrcDragBegin(const CPClipboard *clip, // IN Glib::RefPtr targets; Gdk::DragAction actions; GdkEventMotion event; + int mouseX = mOrigin.get_x() + DRAG_DET_WINDOW_WIDTH / 2; + int mouseY = mOrigin.get_y() + DRAG_DET_WINDOW_WIDTH / 2; TRACE_CALL(); CPClipboard_Clear(&mClipboard); CPClipboard_Copy(&mClipboard, clip); + if (mUseUInput) { + /* + * Check if the screen size changes, if so then update the + * uinput device. + */ + Screen * scrn = DefaultScreenOfDisplay(XOpenDisplay(NULL)); + if ( (scrn->width != mScreenWidth) + || (scrn->height != mScreenHeight)) { + g_debug("%s: Update uinput device. prew:%d, preh:%d, w:%d, h:%d\n", + __FUNCTION__, + mScreenWidth, + mScreenHeight, + scrn->width, + scrn->height); + mScreenWidth = scrn->width; + mScreenHeight = scrn->height; + FakeMouse_Update(mScreenWidth, mScreenHeight); + } + } + /* * Before the DnD, we should make sure that the mouse is released * otherwise it may be another DnD, not ours. Send a release, then * a press here to cover this case. */ - SendFakeXEvents(false, true, false, false, false, 0, 0); - SendFakeXEvents(true, true, true, true, true, mOrigin.get_x(), mOrigin.get_y()); + + SendFakeXEvents(true, true, false, true, true, mouseX, mouseY); + SendFakeXEvents(false, true, true, false, true, mouseX, mouseY); /* * Construct the target and action list, as well as a fake motion notify @@ -409,7 +445,7 @@ DnDUIX11::OnSrcDragBegin(const CPClipboard *clip, // IN /* TODO set the x/y coords to the actual drag initialization point. */ event.type = GDK_MOTION_NOTIFY; - event.window = mDetWnd->get_window()->gobj(); + event.window = mDetWnd->GetWnd()->get_window()->gobj(); event.send_event = false; event.time = GDK_CURRENT_TIME; event.x = 10; @@ -427,7 +463,7 @@ DnDUIX11::OnSrcDragBegin(const CPClipboard *clip, // IN event.y_root = mOrigin.get_y(); /* Tell Gtk that a drag should be started from this widget. */ - mDetWnd->drag_begin(targets, actions, 1, (GdkEvent *)&event); + mDetWnd->GetWnd()->drag_begin(targets, actions, 1, (GdkEvent *)&event); mBlockAdded = false; mHGGetFileStatus = DND_FILE_TRANSFER_NOT_STARTED; SourceDragStartDone(); @@ -464,9 +500,14 @@ DnDUIX11::OnSrcCancel() * flybacks when we cancel as user moves mouse in and out of destination * window in a H->G DnD. */ - OnUpdateDetWnd(true, 0, 0); - SendFakeXEvents(true, true, false, true, true, mOrigin.get_x(), mOrigin.get_y()); + OnUpdateDetWnd(true, mOrigin.get_x(), mOrigin.get_y()); + SendFakeXEvents(true, true, false, true, true, + mOrigin.get_x() + DRAG_DET_WINDOW_WIDTH / 2, + mOrigin.get_y() + DRAG_DET_WINDOW_WIDTH / 2); OnUpdateDetWnd(false, 0, 0); + SendFakeXEvents(false, false, false, false, true, + mMousePosX, + mMousePosY); mInHGDrag = false; mHGGetFileStatus = DND_FILE_TRANSFER_NOT_STARTED; mEffect = DROP_NONE; @@ -636,12 +677,12 @@ DnDUIX11::OnUpdateDetWnd(bool show, // IN: show (true) or hide (false) { g_debug("%s: enter 0x%lx show %d x %d y %d\n", __FUNCTION__, - (unsigned long) mDetWnd->get_window()->gobj(), show, x, y); + (unsigned long) mDetWnd->GetWnd()->get_window()->gobj(), show, x, y); /* If the window is being shown, move it to the right place. */ if (show) { - x = MAX(x - DRAG_DET_WINDOW_WIDTH / 2, 0); - y = MAX(y - DRAG_DET_WINDOW_WIDTH / 2, 0); + x = MAX(x - DRAG_DET_WINDOW_WIDTH / 2, mOrigin.get_x()); + y = MAX(y - DRAG_DET_WINDOW_WIDTH / 2, mOrigin.get_y()); mDetWnd->Show(); mDetWnd->Raise(); @@ -686,7 +727,7 @@ DnDUIX11::OnUpdateUnityDetWnd(bool show, // IN: show (true) or hide (fal { g_debug("%s: enter 0x%lx unityID 0x%x\n", __FUNCTION__, - (unsigned long) mDetWnd->get_window()->gobj(), + (unsigned long) mDetWnd->GetWnd()->get_window()->gobj(), unityWndId); if (show && ((unityWndId > 0) || bottom)) { @@ -848,7 +889,7 @@ DnDUIX11::OnGtkDragMotion( Gdk::DragAction srcActions; Gdk::DragAction suggestedAction; Gdk::DragAction dndAction = (Gdk::DragAction)0; - Glib::ustring target = mDetWnd->drag_dest_find_target(dc); + Glib::ustring target = mDetWnd->GetWnd()->drag_dest_find_target(dc); if (!mDnD->IsDnDAllowed()) { g_debug("%s: No dnd allowed!\n", __FUNCTION__); @@ -1322,7 +1363,7 @@ DnDUIX11::OnGtkDragDrop( Glib::ustring target; - target = mDetWnd->drag_dest_find_target(dc); + target = mDetWnd->GetWnd()->drag_dest_find_target(dc); g_debug("%s: calling drag_finish\n", __FUNCTION__); dc->drag_finish(true, false, time); @@ -1536,10 +1577,10 @@ DnDUIX11::RequestData( * be ignored. */ targets->add(Glib::ustring(DRAG_TARGET_NAME_URI_LIST)); - Glib::ustring target = mDetWnd->drag_dest_find_target(dc, targets); + Glib::ustring target = mDetWnd->GetWnd()->drag_dest_find_target(dc, targets); targets->remove(Glib::ustring(DRAG_TARGET_NAME_URI_LIST)); if (target != "") { - mDetWnd->drag_get_data(dc, target, time); + mDetWnd->GetWnd()->drag_get_data(dc, target, time); mNumPendingRequest++; return true; } @@ -1549,13 +1590,13 @@ DnDUIX11::RequestData( targets->add(Glib::ustring(TARGET_NAME_STRING)); targets->add(Glib::ustring(TARGET_NAME_TEXT_PLAIN)); targets->add(Glib::ustring(TARGET_NAME_COMPOUND_TEXT)); - target = mDetWnd->drag_dest_find_target(dc, targets); + target = mDetWnd->GetWnd()->drag_dest_find_target(dc, targets); targets->remove(Glib::ustring(TARGET_NAME_STRING)); targets->remove(Glib::ustring(TARGET_NAME_TEXT_PLAIN)); targets->remove(Glib::ustring(TARGET_NAME_UTF8_STRING)); targets->remove(Glib::ustring(TARGET_NAME_COMPOUND_TEXT)); if (target != "") { - mDetWnd->drag_get_data(dc, target, time); + mDetWnd->GetWnd()->drag_get_data(dc, target, time); mNumPendingRequest++; } @@ -1563,12 +1604,12 @@ DnDUIX11::RequestData( targets->add(Glib::ustring(TARGET_NAME_APPLICATION_RTF)); targets->add(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT)); targets->add(Glib::ustring(TARGET_NAME_TEXT_RTF)); - target = mDetWnd->drag_dest_find_target(dc, targets); + target = mDetWnd->GetWnd()->drag_dest_find_target(dc, targets); targets->remove(Glib::ustring(TARGET_NAME_APPLICATION_RTF)); targets->remove(Glib::ustring(TARGET_NAME_TEXT_RICHTEXT)); targets->remove(Glib::ustring(TARGET_NAME_TEXT_RTF)); if (target != "") { - mDetWnd->drag_get_data(dc, target, time); + mDetWnd->GetWnd()->drag_get_data(dc, target, time); mNumPendingRequest++; } return (mNumPendingRequest > 0); @@ -1865,24 +1906,43 @@ DnDUIX11::SendFakeXEvents( * is okay since the window is invisible and hidden on cancels and DnD * finish. */ - XMoveResizeWindow(dndXDisplay, dndXWindow, x - 5 , y - 5, 25, 25); + XMoveResizeWindow(dndXDisplay, + dndXWindow, + x - DRAG_DET_WINDOW_WIDTH / 2 , + y - DRAG_DET_WINDOW_WIDTH / 2, + DRAG_DET_WINDOW_WIDTH, + DRAG_DET_WINDOW_WIDTH); XRaiseWindow(dndXDisplay, dndXWindow); - g_debug("%s: move wnd to (%d, %d, %d, %d)\n", __FUNCTION__, x - 5, y - 5 , x + 25, y + 25); + g_debug("%s: move wnd to (%d, %d, %d, %d)\n", + __FUNCTION__, + x - DRAG_DET_WINDOW_WIDTH / 2 , + y - DRAG_DET_WINDOW_WIDTH / 2, + DRAG_DET_WINDOW_WIDTH, + DRAG_DET_WINDOW_WIDTH); } /* * Generate mouse movements over the window. The second one makes ungrabs * happen more reliably on KDE, but isn't necessary on GNOME. */ - XTestFakeMotionEvent(dndXDisplay, -1, x, y, CurrentTime); - XTestFakeMotionEvent(dndXDisplay, -1, x + 1, y + 1, CurrentTime); + if (mUseUInput) { + FakeMouse_Move(x, y); + FakeMouse_Move(x + 1, y + 1); + } else { + XTestFakeMotionEvent(dndXDisplay, -1, x, y, CurrentTime); + XTestFakeMotionEvent(dndXDisplay, -1, x + 1, y + 1, CurrentTime); + } g_debug("%s: move mouse to (%d, %d) and (%d, %d)\n", __FUNCTION__, x, y, x + 1, y + 1); if (buttonEvent) { g_debug("%s: faking left mouse button %s\n", __FUNCTION__, buttonPress ? "press" : "release"); - XTestFakeButtonEvent(dndXDisplay, 1, buttonPress, CurrentTime); - XSync(dndXDisplay, False); + if (mUseUInput) { + FakeMouse_Click(buttonPress); + } else { + XTestFakeButtonEvent(dndXDisplay, 1, buttonPress, CurrentTime); + XSync(dndXDisplay, False); + } if (!buttonPress) { /* @@ -2039,15 +2099,14 @@ DnDUIX11::TryXTestFakeDeviceButtonEvent() GtkWidget * DnDUIX11::GetDetWndAsWidget() { - GtkInvisible *window; GtkWidget *widget = NULL; if (!mDetWnd) { return NULL; } - window = mDetWnd->gobj(); - if (window) { - widget = GTK_WIDGET(window); + + if (mDetWnd->GetWnd()->gobj()) { + widget = GTK_WIDGET(mDetWnd->GetWnd()->gobj()); } return widget; } diff --git a/open-vm-tools/services/plugins/dndcp/dndUIX11.h b/open-vm-tools/services/plugins/dndcp/dndUIX11.h index d4fda4c0e..8740e1750 100644 --- a/open-vm-tools/services/plugins/dndcp/dndUIX11.h +++ b/open-vm-tools/services/plugins/dndcp/dndUIX11.h @@ -231,6 +231,10 @@ private: * composite overlay window. */ Gdk::Point mOrigin; + + bool mUseUInput; + int mScreenWidth; + int mScreenHeight; }; #endif // __DND_UI_X11_H__ diff --git a/open-vm-tools/services/plugins/dndcp/dragDetWndX11.cpp b/open-vm-tools/services/plugins/dndcp/dragDetWndX11.cpp index 11094ff3f..501e52ae5 100644 --- a/open-vm-tools/services/plugins/dndcp/dragDetWndX11.cpp +++ b/open-vm-tools/services/plugins/dndcp/dragDetWndX11.cpp @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2009-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2009-2018 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -40,6 +40,32 @@ DragDetWnd::DragDetWnd() : #if defined(DETWNDDEBUG) DebugSetAttributes(); #endif + + bool useInvisible = true; + +#ifdef GTK3 + char *xdgSessionType = getenv("XDG_SESSION_TYPE"); + if ( (xdgSessionType != NULL) + && (strstr(xdgSessionType, "wayland") != NULL)) { + useInvisible = false; + } +#endif + + if (useInvisible) { + mWnd = new DragDetWndImpl(); + } else { + DragDetWndImpl *win = new DragDetWndImpl(); + win->set_accept_focus(false); + win->set_decorated(false); + win->set_keep_above(); + // Makes this window transparent because we don't want user to see it. + win->set_opacity(0.01); + // Calls 'Show' to create the Gtk::Window object. + win->show(); + win->hide(); + + mWnd = win; + } } @@ -53,6 +79,17 @@ DragDetWnd::~DragDetWnd() } +/** + * Get the actual widget. + */ + +Gtk::Widget * +DragDetWnd::GetWnd() +{ + return mWnd; +} + + /** * Flush the X connection. */ @@ -76,7 +113,7 @@ DragDetWnd::Flush() void DragDetWnd::Show(void) { - show(); + GetWnd()->show_now(); Flush(); } @@ -89,7 +126,7 @@ DragDetWnd::Show(void) void DragDetWnd::Hide(void) { - hide(); + GetWnd()->hide(); Flush(); } @@ -102,7 +139,7 @@ DragDetWnd::Hide(void) void DragDetWnd::Raise(void) { - Glib::RefPtr gdkwin = get_window(); + Glib::RefPtr gdkwin = GetWnd()->get_window(); if (gdkwin) { gdkwin->raise(); } @@ -118,7 +155,7 @@ DragDetWnd::Raise(void) void DragDetWnd::Lower(void) { - Glib::RefPtr gdkwin = get_window(); + Glib::RefPtr gdkwin = GetWnd()->get_window(); if (gdkwin) { gdkwin->lower(); } @@ -136,7 +173,7 @@ DragDetWnd::Lower(void) int DragDetWnd::GetScreenWidth(void) { - Glib::RefPtr gdkscreen = get_screen(); + Glib::RefPtr gdkscreen = GetWnd()->get_screen(); return gdkscreen->get_width(); } @@ -151,7 +188,7 @@ DragDetWnd::GetScreenWidth(void) int DragDetWnd::GetScreenHeight(void) { - Glib::RefPtr gdkscreen = get_screen(); + Glib::RefPtr gdkscreen = GetWnd()->get_screen(); return gdkscreen->get_height(); } @@ -168,10 +205,10 @@ DragDetWnd::GetScreenHeight(void) void DragDetWnd::DebugSetAttributes(void) { - set_default_size(1, 1); - set_resizable(true); - set_decorated(false); - set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK); + GetWnd()->set_default_size(1, 1); + GetWnd()->set_resizable(true); + GetWnd()->set_decorated(false); + GetWnd()->set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK); } #endif @@ -192,7 +229,7 @@ DragDetWnd::SetGeometry(const int x, const int width, const int height) { - Glib::RefPtr gdkwin = get_window(); + Glib::RefPtr gdkwin = GetWnd()->get_window(); if (gdkwin) { gdkwin->move_resize(x, y, width, height); @@ -219,7 +256,7 @@ DragDetWnd::SetGeometry(const int x, void DragDetWnd::GetGeometry(int &x, int &y, int &width, int &height) { - Glib::RefPtr gdkwin = get_window(); + Glib::RefPtr gdkwin = GetWnd()->get_window(); if (gdkwin) { #ifndef GTK3 int dummy; diff --git a/open-vm-tools/services/plugins/dndcp/dragDetWndX11.h b/open-vm-tools/services/plugins/dndcp/dragDetWndX11.h index afdcf33a8..a35a17c03 100644 --- a/open-vm-tools/services/plugins/dndcp/dragDetWndX11.h +++ b/open-vm-tools/services/plugins/dndcp/dragDetWndX11.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2009-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2009-2018 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -33,12 +33,35 @@ class DnDUI; -class DragDetWnd : public Gtk::Invisible +/* + * DragDetWnd is an invisible window, there are two ways to create an + * invisible window: + * 1. inherits from class Gtk::Invisible; + * 2. inherits from class Gtk::Window and set the opacity to 1%; + * Class Gtk::Invisible cannot be used for Wayland because + * the Gtk::Invisible cannot receive the mouse event with Wayland, + * it seems this is a bug of Wayland. + * So two drag detection windows are created, one inherits from + * Gtk::Invisible which is used for the X11, and another window + * inherits from Gtk::Window which is used for the Wayland. + * After Wayland fixes the bug of Gtk::Invisible, the window + * inherits from Gtk::Window will be removed. + */ +template +class DragDetWndImpl : public TBase +{ +public: + DragDetWndImpl() {} + virtual ~DragDetWndImpl() {} +}; + +class DragDetWnd { public: DragDetWnd(); virtual ~DragDetWnd(); + Gtk::Widget *GetWnd(); void Show(); void Hide(); void Raise(); @@ -56,6 +79,7 @@ public: private: void Flush(); bool m_isVisible; + Gtk::Widget *mWnd; }; #if defined(DETWNDTEST) diff --git a/open-vm-tools/services/plugins/dndcp/fakeMouseWayland/fakeMouseWayland.cpp b/open-vm-tools/services/plugins/dndcp/fakeMouseWayland/fakeMouseWayland.cpp index 2f30cd2ac..ee675a9d7 100644 --- a/open-vm-tools/services/plugins/dndcp/fakeMouseWayland/fakeMouseWayland.cpp +++ b/open-vm-tools/services/plugins/dndcp/fakeMouseWayland/fakeMouseWayland.cpp @@ -219,6 +219,7 @@ FakeMouse_Destory() if (ioctl(uinput_fd, UI_DEV_DESTROY, 0) < 0) { g_debug("%s: Failed to destroy uinput device\n", __FUNCTION__); } + isInit = false; } @@ -327,6 +328,6 @@ FakeMouse_Click(bool down) // IN * Insert a pause here so that userspace has time to detect this event, * otherwise it will not notice the event we are about to send. */ - usleep(10 * 1000); + usleep(100 * 1000); return retValue; }