commit 9b228b0c5b741917aaf60989d46d5ffcaa5fce73
parent cc1db59a5be2fd1c8418df5e3432f0ced37329ba
Author: falkTX <falktx@falktx.com>
Date: Fri, 27 May 2022 23:14:30 +0100
Adjust clipboard API following latest pugl changes
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
13 files changed, 179 insertions(+), 71 deletions(-)
diff --git a/dgl/Base.hpp b/dgl/Base.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
+ * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -159,15 +159,15 @@ enum MouseButton {
This is a portable subset of mouse cursors that exist on X11, MacOS, and Windows.
*/
enum MouseCursor {
- kMouseCursorArrow, ///< Default pointing arrow
- kMouseCursorCaret, ///< Caret (I-Beam) for text entry
- kMouseCursorCrosshair, ///< Cross-hair
- kMouseCursorHand, ///< Hand with a pointing finger
- kMouseCursorNotAllowed, ///< Operation not allowed
- kMouseCursorLeftRight, ///< Left/right arrow for horizontal resize
- kMouseCursorUpDown, ///< Up/down arrow for vertical resize
- kMouseCursorDiagonal, ///< Top-left to bottom-right arrow for diagonal resize
- kMouseCursorAntiDiagonal ///< Bottom-left to top-right arrow for diagonal resize
+ kMouseCursorArrow, ///< Default pointing arrow
+ kMouseCursorCaret, ///< Caret (I-Beam) for text entry
+ kMouseCursorCrosshair, ///< Cross-hair
+ kMouseCursorHand, ///< Hand with a pointing finger
+ kMouseCursorNotAllowed, ///< Operation not allowed
+ kMouseCursorLeftRight, ///< Left/right arrow for horizontal resize
+ kMouseCursorUpDown, ///< Up/down arrow for vertical resize
+ kMouseCursorDiagonal, ///< Top-left to bottom-right arrow for diagonal resize
+ kMouseCursorAntiDiagonal ///< Bottom-left to top-right arrow for diagonal resize
};
/**
@@ -178,11 +178,29 @@ enum MouseCursor {
while a smooth scroll is for those with arbitrary scroll direction freedom, like some touchpads.
*/
enum ScrollDirection {
- kScrollUp, ///< Scroll up
- kScrollDown, ///< Scroll down
- kScrollLeft, ///< Scroll left
- kScrollRight, ///< Scroll right
- kScrollSmooth ///< Smooth scroll in any direction
+ kScrollUp, ///< Scroll up
+ kScrollDown, ///< Scroll down
+ kScrollLeft, ///< Scroll left
+ kScrollRight, ///< Scroll right
+ kScrollSmooth ///< Smooth scroll in any direction
+};
+
+/**
+ A clipboard data offer.
+ @see Window::onClipboardDataOffer
+*/
+struct ClipboardDataOffer {
+ /**
+ The id of this data offer.
+ @note The value 0 is reserved for null/invalid.
+ */
+ uint32_t id;
+
+ /**
+ The type of this data offer.
+ Usually a MIME type, but may also be another platform-specific type identifier.
+ */
+ const char* type;
};
// --------------------------------------------------------------------------------------------------------------------
diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp
@@ -101,8 +101,8 @@ public:
void repaint(const Rectangle<uint>& rect) noexcept;
// TODO group stuff after here, convenience functions present in Window class
+ const void* getClipboard(size_t& dataSize);
bool setClipboard(const char* mimeType, const void* data, size_t dataSize);
- const void* getClipboard(const char*& mimeType, size_t& dataSize);
bool setCursor(MouseCursor cursor);
bool addIdleCallback(IdleCallback* callback, uint timerFrequencyInMs = 0);
bool removeIdleCallback(IdleCallback* callback);
diff --git a/dgl/Window.hpp b/dgl/Window.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
+ * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -23,6 +23,8 @@
# include "../distrho/extra/FileBrowserDialog.hpp"
#endif
+#include <vector>
+
START_NAMESPACE_DGL
class Application;
@@ -299,6 +301,16 @@ public:
void setIgnoringKeyRepeat(bool ignore) noexcept;
/**
+ Get the clipboard contents.
+
+ This gets the system clipboard contents,
+ which may have been set with setClipboard() or copied from another application.
+
+ returns the clipboard contents, or null.
+ */
+ const void* getClipboard(size_t& dataSize);
+
+ /**
Set the clipboard contents.
This sets the system clipboard contents,
@@ -310,16 +322,6 @@ public:
bool setClipboard(const char* mimeType, const void* data, size_t dataSize);
/**
- Get the clipboard contents.
-
- This gets the system clipboard contents,
- which may have been set with setClipboard() or copied from another application.
-
- returns the clipboard contents, or null.
- */
- const void* getClipboard(const char*& mimeType, size_t& dataSize);
-
- /**
Set the mouse cursor.
This changes the system cursor that is displayed when the pointer is inside the window.
@@ -451,6 +453,23 @@ public:
protected:
/**
+ Get the types available for the data in a clipboard.
+ Must only be called within the context of onClipboardDataOffer.
+ */
+ std::vector<ClipboardDataOffer> getClipboardDataOfferTypes();
+
+ /**
+ A function called when clipboard has data present, possibly with several datatypes.
+ While handling this event, the data types can be investigated with getClipboardDataOfferTypes() to decide whether to accept the offer.
+
+ Reimplement and return a non-zero id to accept the clipboard data offer for a particular type.
+ Applications must ignore any type they do not recognize.
+
+ The default implementation does nothing.
+ */
+ virtual uint32_t onClipboardDataOffer();
+
+ /**
A function called when the window is attempted to be closed.
Returning true closes the window, which is the default behaviour.
Override this method and return false to prevent the window from being closed by the user.
diff --git a/dgl/src/TopLevelWidget.cpp b/dgl/src/TopLevelWidget.cpp
@@ -60,14 +60,14 @@ void TopLevelWidget::setSize(const Size<uint>& size)
pData->window.setSize(size);
}
-bool TopLevelWidget::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
+const void* TopLevelWidget::getClipboard(size_t& dataSize)
{
- return pData->window.setClipboard(mimeType, data, dataSize);
+ return pData->window.getClipboard(dataSize);
}
-const void* TopLevelWidget::getClipboard(const char*& mimeType, size_t& dataSize)
+bool TopLevelWidget::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
{
- return pData->window.getClipboard(mimeType, dataSize);
+ return pData->window.setClipboard(mimeType, data, dataSize);
}
bool TopLevelWidget::setCursor(const MouseCursor cursor)
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
@@ -319,15 +319,20 @@ void Window::setIgnoringKeyRepeat(const bool ignore) noexcept
puglSetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT, ignore);
}
-bool Window::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
+const void* Window::getClipboard(size_t& dataSize)
{
- return puglSetClipboard(pData->view, mimeType, data, dataSize) == PUGL_SUCCESS;
+ if (pData->clipboardTypeIndex == 0)
+ {
+ dataSize = 0;
+ return nullptr;
+ }
+
+ return puglGetClipboard(pData->view, pData->clipboardTypeIndex, &dataSize);
}
-const void* Window::getClipboard(const char*& mimeType, size_t& dataSize)
+bool Window::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
{
- const void* const clipboard = nullptr; // puglGetClipboard(pData->view, &mimeType, &dataSize);
- return clipboard;
+ return puglSetClipboard(pData->view, mimeType, data, dataSize) == PUGL_SUCCESS;
}
bool Window::setCursor(const MouseCursor cursor)
@@ -466,6 +471,29 @@ void Window::setGeometryConstraints(uint minimumWidth,
}
}
+std::vector<ClipboardDataOffer> Window::getClipboardDataOfferTypes()
+{
+ std::vector<ClipboardDataOffer> offerTypes;
+
+ if (const uint32_t numTypes = puglGetNumClipboardTypes(pData->view))
+ {
+ offerTypes.reserve(numTypes);
+
+ for (uint32_t i=0; i<numTypes; ++i)
+ {
+ const ClipboardDataOffer offer = { i + 1, puglGetClipboardType(pData->view, i) };
+ offerTypes.push_back(offer);
+ }
+ }
+
+ return offerTypes;
+}
+
+uint32_t Window::onClipboardDataOffer()
+{
+ return 0;
+}
+
bool Window::onClose()
{
return true;
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -109,6 +109,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s)
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
+ clipboardTypeIndex(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -135,6 +136,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
+ clipboardTypeIndex(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -163,6 +165,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
+ clipboardTypeIndex(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -192,6 +195,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
+ clipboardTypeIndex(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -753,6 +757,13 @@ void Window::PrivateData::onPuglScroll(const Widget::ScrollEvent& ev)
#endif
}
+uint32_t Window::PrivateData::onClipboardDataOffer()
+{
+ DGL_DBG("onClipboardDataOffer\n");
+
+ return clipboardTypeIndex = self->onClipboardDataOffer();
+}
+
#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS)
static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose);
#endif
@@ -933,6 +944,8 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
///< Data offered from clipboard, a #PuglDataOfferEvent
case PUGL_DATA_OFFER:
+ if (const uint32_t offerId = pData->onClipboardDataOffer())
+ puglAcceptOffer(view, &event->offer, offerId - 1);
break;
///< Data available from clipboard, a #PuglDataEvent
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -80,6 +80,9 @@ struct Window::PrivateData : IdleCallback {
/** Whether to ignore idle callback requests, useful for temporary windows. */
bool ignoreIdleCallbacks;
+ /** The type index returned by the last onClipboardDataOffer call. */
+ uint32_t clipboardTypeIndex;
+
/** Render to a picture file when non-null, automatically free+unset after saving. */
char* filenameToRenderInto;
@@ -182,6 +185,7 @@ struct Window::PrivateData : IdleCallback {
void onPuglMouse(const Widget::MouseEvent& ev);
void onPuglMotion(const Widget::MotionEvent& ev);
void onPuglScroll(const Widget::ScrollEvent& ev);
+ uint32_t onClipboardDataOffer();
// Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);
diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp
@@ -476,8 +476,8 @@ void puglMacOSShowCentered(PuglView* const view)
const NSRect ourFrame = [view->impl->window frame];
const NSRect transientFrame = [transientWindow frame];
- const int x = transientFrame.origin.x + transientFrame.size.width / 2 - ourFrame.size.width / 2;
- const int y = transientFrame.origin.y + transientFrame.size.height / 2 + ourFrame.size.height / 2;
+ const int x = transientFrame.origin.x + (transientFrame.size.width - ourFrame.size.width) / 2;
+ const int y = transientFrame.origin.y + (transientFrame.size.height - ourFrame.size.height) / 2;
[view->impl->window setFrameTopLeftPoint:NSMakePoint(x, y)];
}
@@ -543,8 +543,8 @@ void puglWin32ShowCentered(PuglView* const view)
if (GetMonitorInfo(MonitorFromWindow(impl->hwnd, MONITOR_DEFAULTTOPRIMARY), &mInfo))
SetWindowPos(impl->hwnd,
HWND_TOP,
- mInfo.rcWork.left + (mInfo.rcWork.right - view->frame.width) / 2,
- mInfo.rcWork.top + (mInfo.rcWork.bottom - view->frame.height) / 2,
+ mInfo.rcWork.left + (mInfo.rcWork.right - mInfo.rcWork.left - view->frame.width) / 2,
+ mInfo.rcWork.top + (mInfo.rcWork.bottom - mInfo.rcWork.top - view->frame.height) / 2,
0, 0, SWP_SHOWWINDOW|SWP_NOSIZE);
else
ShowWindow(impl->hwnd, SW_NORMAL);
diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp
@@ -35,20 +35,12 @@
#define PUGL_NO_INCLUDE_GL_H
#define PUGL_NO_INCLUDE_GLU_H
-// do not set extern "C"
-// #define __cplusplus_backup __cplusplus
-// #undef __cplusplus
-
-// give warning if defined as something else
-// #define PUGL_BEGIN_DECLS
-// #define PUGL_END_DECLS
-
-// --------------------------------------------------------------------------------------------------------------------
-
START_NAMESPACE_DGL
#include "pugl-upstream/include/pugl/pugl.h"
+// --------------------------------------------------------------------------------------------------------------------
+
// DGL specific, expose backend enter
bool puglBackendEnter(PuglView* view);
@@ -85,30 +77,24 @@ void puglFallbackOnResize(PuglView* view);
#if defined(DISTRHO_OS_MAC)
// macOS specific, allow standalone window to gain focus
-PUGL_API void
-puglMacOSActivateApp();
+void puglMacOSActivateApp();
// macOS specific, add another view's window as child
-PUGL_API PuglStatus
-puglMacOSAddChildWindow(PuglView* view, PuglView* child);
+PuglStatus puglMacOSAddChildWindow(PuglView* view, PuglView* child);
// macOS specific, remove another view's window as child
-PUGL_API PuglStatus
-puglMacOSRemoveChildWindow(PuglView* view, PuglView* child);
+PuglStatus puglMacOSRemoveChildWindow(PuglView* view, PuglView* child);
// macOS specific, center view based on parent coordinates (if there is one)
-PUGL_API void
-puglMacOSShowCentered(PuglView* view);
+void puglMacOSShowCentered(PuglView* view);
#elif defined(DISTRHO_OS_WINDOWS)
// win32 specific, call ShowWindow with SW_RESTORE
-PUGL_API void
-puglWin32RestoreWindow(PuglView* view);
+void puglWin32RestoreWindow(PuglView* view);
// win32 specific, center view based on parent coordinates (if there is one)
-PUGL_API void
-puglWin32ShowCentered(PuglView* view);
+void puglWin32ShowCentered(PuglView* view);
#elif defined(HAVE_X11)
@@ -121,7 +107,4 @@ void puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone);
END_NAMESPACE_DGL
-// #define __cplusplus __cplusplus_backup
-// #undef __cplusplus_backup
-
#endif // DGL_PUGL_HPP_INCLUDED
diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
+ * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -297,6 +297,23 @@ protected:
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
/**
+ Get the types available for the data in a clipboard.
+ Must only be called within the context of uiClipboardDataOffer.
+ */
+ std::vector<DGL_NAMESPACE::ClipboardDataOffer> getClipboardDataOfferTypes();
+
+ /**
+ Window clipboard data offer function, called when clipboard has data present, possibly with several datatypes.
+ While handling this event, the data types can be investigated with getClipboardDataOfferTypes() to decide whether to accept the offer.
+
+ Reimplement and return a non-zero id to accept the clipboard data offer for a particular type.
+ UIs must ignore any type they do not recognize.
+
+ The default implementation does nothing.
+ */
+ virtual uint32_t uiClipboardDataOffer();
+
+ /**
Windows focus function, called when the window gains or loses the keyboard focus.
This function is for plugin UIs to be able to override Window::onFocus(bool, CrossingMode).
diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
+ * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -338,6 +338,16 @@ void UI::uiScaleFactorChanged(double)
}
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+std::vector<DGL_NAMESPACE::ClipboardDataOffer> UI::getClipboardDataOfferTypes()
+{
+ return uiData->window->getClipboardDataOfferTypes();
+}
+
+uint32_t UI::uiClipboardDataOffer()
+{
+ return 0;
+}
+
void UI::uiFocus(bool, DGL_NAMESPACE::CrossingMode)
{
}
diff --git a/distrho/src/DistrhoUIPrivateData.hpp b/distrho/src/DistrhoUIPrivateData.hpp
@@ -238,7 +238,22 @@ public:
}
#endif
+ std::vector<ClipboardDataOffer> getClipboardDataOfferTypes()
+ {
+ return Window::getClipboardDataOfferTypes();
+ }
+
protected:
+ uint32_t onClipboardDataOffer() override
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, 0);
+
+ if (initializing)
+ return 0;
+
+ return ui->uiClipboardDataOffer();
+ }
+
void onFocus(const bool focus, const DGL_NAMESPACE::CrossingMode mode) override
{
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
diff --git a/pugl-updates-notes.txt b/pugl-updates-notes.txt
@@ -1,9 +1,10 @@
puglClearMinSize needed?
-clipboard todo
-
puglSetWindowSize was used on first show, still needed?
+transientParentView needed? remove from WindowPrivateData
-pugl namespace details finalized
+update distrhoui.cpp get scale factor to match new parent request setup and pugl
-window starts centered for screen or parent finalized
+clipboard todo
+
+pugl namespace details finalized