From 46a97e1f2c7d9564804f8bb9f88a17d837b5b0e0 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 7 May 2019 17:10:52 +0100 Subject: [PATCH] Linux: Recreate mouse cursors when showing them on a different display to the one that they were originally created on --- .../mouse/juce_MouseCursor.cpp | 12 ++++++--- .../native/juce_linux_X11_Windowing.cpp | 27 ++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp index 80e90c14f8..dd93e90eb9 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp @@ -53,7 +53,8 @@ public: } SharedCursorHandle (const Image& image, Point hotSpot, float scaleFactor) - : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()), + : info (new CustomMouseCursorInfo (image, hotSpot, scaleFactor)), + handle (info->create()), standardType (MouseCursor::NormalCursor), isStandard (false) { @@ -106,10 +107,15 @@ public: } } - void* getHandle() const noexcept { return handle; } + void* getHandle() const noexcept { return handle; } + void setHandle (void* newHandle) { handle = newHandle; } + + MouseCursor::StandardCursorType getType() const noexcept { return standardType; } + CustomMouseCursorInfo* getCustomInfo() const noexcept { return info.get(); } private: - void* const handle; + std::unique_ptr info; + void* handle; Atomic refCount { 1 }; const MouseCursor::StandardCursorType standardType; const bool isStandard; diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp index 42826ba5f7..8176b7cc30 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp @@ -3790,6 +3790,7 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType ico } //============================== X11 - MouseCursor ============================= +std::map cursorMap; void* CustomMouseCursorInfo::create() const { @@ -3852,7 +3853,10 @@ void* CustomMouseCursorInfo::create() const xcursorImageDestroy (xcImage); if (result != nullptr) + { + cursorMap[(Cursor) result] = display; return result; + } } } } @@ -3916,6 +3920,7 @@ void* CustomMouseCursorInfo::create() const XFreePixmap (display, sourcePixmap); XFreePixmap (display, maskPixmap); + cursorMap[(Cursor) result] = display; return result; } @@ -3983,13 +3988,33 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty } ScopedXLock xlock (display); - return (void*) XCreateFontCursor (display, shape); + + auto* result = (void*) XCreateFontCursor (display, shape); + cursorMap[(Cursor) result] = display; + + return result; } void MouseCursor::showInWindow (ComponentPeer* peer) const { if (auto* lp = dynamic_cast (peer)) + { + ScopedXDisplay xDisplay; + + if (cursorHandle != nullptr && xDisplay.display != cursorMap[(Cursor) getHandle()]) + { + auto oldHandle = (Cursor) getHandle(); + + if (auto* customInfo = cursorHandle->getCustomInfo()) + cursorHandle->setHandle (customInfo->create()); + else + cursorHandle->setHandle (createStandardMouseCursor (cursorHandle->getType())); + + cursorMap.erase (oldHandle); + } + lp->showMouseCursor ((Cursor) getHandle()); + } } //=================================== X11 - DND ================================