Browse Source

Try to make X11 copy&paste more robust

Signed-off-by: falkTX <falktx@falktx.com>
pull/321/head
falkTX 3 years ago
parent
commit
9ab4ff8145
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
5 changed files with 77 additions and 21 deletions
  1. +43
    -19
      dgl/src/WindowPrivateData.cpp
  2. +2
    -1
      dgl/src/WindowPrivateData.hpp
  3. +1
    -1
      dgl/src/pugl-upstream
  4. +22
    -0
      dgl/src/pugl.cpp
  5. +9
    -0
      dgl/src/pugl.hpp

+ 43
- 19
dgl/src/WindowPrivateData.cpp View File

@@ -109,7 +109,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s)
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
waitingForClipboard(false),
waitingForClipboardData(false),
waitingForClipboardEvents(false),
clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
@@ -137,7 +138,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
waitingForClipboard(false),
waitingForClipboardData(false),
waitingForClipboardEvents(false),
clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
@@ -167,7 +169,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
waitingForClipboard(false),
waitingForClipboardData(false),
waitingForClipboardEvents(false),
clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
@@ -198,7 +201,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
waitingForClipboard(false),
waitingForClipboardData(false),
waitingForClipboardEvents(false),
clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
@@ -610,7 +614,7 @@ void Window::PrivateData::onPuglConfigure(const double width, const double heigh

void Window::PrivateData::onPuglExpose()
{
DGL_DBGp("PUGL: onPuglExpose\n");
DGL_DBG("PUGL: onPuglExpose\n");

puglOnDisplayPrepare(view);

@@ -769,36 +773,48 @@ void Window::PrivateData::onPuglScroll(const Widget::ScrollEvent& ev)
const void* Window::PrivateData::getClipboard(size_t& dataSize)
{
clipboardTypeId = 0;
waitingForClipboard = true;
waitingForClipboardData = true,
waitingForClipboardEvents = true;

// begin clipboard dance here
if (puglPaste(view) != PUGL_SUCCESS)
{
dataSize = 0;
waitingForClipboard = false;
waitingForClipboardEvents = false;
return nullptr;
}

// wait for type request
while (waitingForClipboard && clipboardTypeId == 0)
puglUpdate(appData->world, 0.03);
// wait for type request, clipboardTypeId must be != 0 to be valid
while (clipboardTypeId == 0 && waitingForClipboardData)
{
#ifdef DGL_USING_X11
puglX11UpdateWithoutExposures(appData->world);
#endif
}

if (clipboardTypeId == 0)
{
dataSize = 0;
waitingForClipboard = false;
waitingForClipboardEvents = false;
return nullptr;
}

// wait for actual data
while (waitingForClipboard)
puglUpdate(appData->world, 0.03);
// wait for actual data (assumes offer was accepted)
while (waitingForClipboardData)
{
#ifdef DGL_USING_X11
puglX11UpdateWithoutExposures(appData->world);
#endif
}

if (clipboardTypeId == 0)
{
dataSize = 0;
waitingForClipboardEvents = false;
return nullptr;
}

waitingForClipboardEvents = false;
return puglGetClipboard(view, clipboardTypeId - 1, &dataSize);
}

@@ -809,7 +825,8 @@ uint32_t Window::PrivateData::onClipboardDataOffer()
if ((clipboardTypeId = self->onClipboardDataOffer()) != 0)
return clipboardTypeId;

waitingForClipboard = false;
// stop waiting for data, it was rejected
waitingForClipboardData = false;
return 0;
}

@@ -818,7 +835,7 @@ void Window::PrivateData::onClipboardData(const uint32_t typeId)
if (clipboardTypeId != typeId)
clipboardTypeId = 0;

waitingForClipboard = false;
waitingForClipboardData = false;
}

#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS)
@@ -834,7 +851,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
}
#endif

if (pData->waitingForClipboard)
if (pData->waitingForClipboardEvents)
{
switch (event->type)
{
@@ -851,8 +868,15 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
case PUGL_BUTTON_RELEASE:
case PUGL_MOTION:
case PUGL_SCROLL:
case PUGL_TIMER:
case PUGL_LOOP_ENTER:
case PUGL_LOOP_LEAVE:
return PUGL_SUCCESS;
case PUGL_DATA_OFFER:
case PUGL_DATA:
break;
default:
d_stdout("Got event %d while waitingForClipboardEvents", event->type);
break;
}
}
@@ -865,10 +889,10 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu

///< View created, a #PuglEventCreate
case PUGL_CREATE:
#if defined(HAVE_X11) && !defined(DISTRHO_OS_MAC) && !defined(DISTRHO_OS_WINDOWS)
#ifdef DGL_USING_X11
if (! pData->isEmbed)
puglX11SetWindowTypeAndPID(view, pData->appData->isStandalone);
#endif
#endif
break;

///< View destroyed, a #PuglEventDestroy


+ 2
- 1
dgl/src/WindowPrivateData.hpp View File

@@ -78,7 +78,8 @@ struct Window::PrivateData : IdleCallback {
bool ignoreIdleCallbacks;

/** Whether we are waiting to receive clipboard data, ignoring some events in the process. */
bool waitingForClipboard;
bool waitingForClipboardData;
bool waitingForClipboardEvents;

/** The type id returned by the last onClipboardDataOffer call. */
uint32_t clipboardTypeId;


+ 1
- 1
dgl/src/pugl-upstream

@@ -1 +1 @@
Subproject commit e90fdaa11e0763fa31b6e0aedb32edb1ed2807cc
Subproject commit 1c669b15877b04c1fc8cff9d37bc336ef0ff7808

+ 22
- 0
dgl/src/pugl.cpp View File

@@ -226,6 +226,8 @@ void puglRaiseWindow(PuglView* const view)
if (NSWindow* const window = view->impl->window ? view->impl->window
: [view->impl->wrapperView window])
[window orderFrontRegardless];
#elif defined(DISTRHO_OS_WASM)
// nothing
#elif defined(DISTRHO_OS_WINDOWS)
SetForegroundWindow(view->impl->hwnd);
SetActiveWindow(view->impl->hwnd);
@@ -290,6 +292,8 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co
if (aspect && (status = updateSizeHint(view, PUGL_FIXED_ASPECT)) != PUGL_SUCCESS)
return status;
}
#elif defined(DISTRHO_OS_WASM)
// nothing
#elif defined(DISTRHO_OS_WINDOWS)
// nothing
#elif defined(HAVE_X11)
@@ -317,6 +321,8 @@ void puglSetResizable(PuglView* const view, const bool resizable)
[window setStyleMask:style];
}
// FIXME use [view setAutoresizingMask:NSViewNotSizable] ?
#elif defined(DISTRHO_OS_WASM)
// nothing
#elif defined(DISTRHO_OS_WINDOWS)
if (const HWND hwnd = view->impl->hwnd)
{
@@ -433,6 +439,8 @@ void puglFallbackOnResize(PuglView* const view)
#endif
}

// --------------------------------------------------------------------------------------------------------------------

#if defined(DISTRHO_OS_MAC)

// --------------------------------------------------------------------------------------------------------------------
@@ -570,8 +578,22 @@ void puglWin32ShowCentered(PuglView* const view)

// --------------------------------------------------------------------------------------------------------------------

#elif defined(DISTRHO_OS_WASM)

// nothing here yet

// --------------------------------------------------------------------------------------------------------------------

#elif defined(HAVE_X11)

PuglStatus puglX11UpdateWithoutExposures(PuglWorld* const world)
{
world->impl->dispatchingEvents = true;
const PuglStatus st = dispatchX11Events(world);
world->impl->dispatchingEvents = false;
return st;
}

// --------------------------------------------------------------------------------------------------------------------
// X11 specific, set dialog window type and pid hints



+ 9
- 0
dgl/src/pugl.hpp View File

@@ -84,6 +84,10 @@ PuglStatus puglMacOSRemoveChildWindow(PuglView* view, PuglView* child);
// macOS specific, center view based on parent coordinates (if there is one)
void puglMacOSShowCentered(PuglView* view);

#elif defined(DISTRHO_OS_WASM)

// nothing here yet

#elif defined(DISTRHO_OS_WINDOWS)

// win32 specific, call ShowWindow with SW_RESTORE
@@ -94,6 +98,11 @@ void puglWin32ShowCentered(PuglView* view);

#elif defined(HAVE_X11)

#define DGL_USING_X11

// X11 specific, update world without triggering exposure evente
PuglStatus puglX11UpdateWithoutExposures(PuglWorld* world);

// X11 specific, set dialog window type and pid hints
void puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone);



Loading…
Cancel
Save