Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -55,6 +55,12 @@ public: | |||||
*/ | */ | ||||
explicit Window(Application& app); | explicit Window(Application& app); | ||||
/** | |||||
Constructor for a modal window, by having another window as its parent. | |||||
The Application instance must be the same between the 2 windows. | |||||
*/ | |||||
explicit Window(Application& app, Window& parent); | |||||
/** | /** | ||||
Constructor for an embed Window without known size, | Constructor for an embed Window without known size, | ||||
typically used in modules or plugins that run inside another host. | typically used in modules or plugins that run inside another host. | ||||
@@ -224,6 +230,13 @@ public: | |||||
*/ | */ | ||||
void repaint(const Rectangle<uint>& rect) noexcept; | void repaint(const Rectangle<uint>& rect) noexcept; | ||||
/** | |||||
Run this window as a modal, blocking input events from the parent. | |||||
Only valid for windows that have been created with another window as parent (as passed in the constructor). | |||||
Can optionally block-wait, but such option is only available if the application is running as standalone. | |||||
*/ | |||||
void runAsModal(bool blockWait = false); | |||||
/** | /** | ||||
Set geometry constraints for the Window when resized by the user, and optionally scale contents automatically. | Set geometry constraints for the Window when resized by the user, and optionally scale contents automatically. | ||||
*/ | */ | ||||
@@ -239,6 +252,7 @@ public: | |||||
// TODO deprecated | // TODO deprecated | ||||
inline bool getIgnoringKeyRepeat() const noexcept { return isIgnoringKeyRepeat(); } | inline bool getIgnoringKeyRepeat() const noexcept { return isIgnoringKeyRepeat(); } | ||||
inline double getScaling() const noexcept { return getScaling(); } | inline double getScaling() const noexcept { return getScaling(); } | ||||
inline void exec(bool blockWait = false) { runAsModal(blockWait); } | |||||
protected: | protected: | ||||
/** | /** | ||||
@@ -257,6 +271,7 @@ protected: | |||||
/** | /** | ||||
A function called when the window is resized. | A function called when the window is resized. | ||||
If there is a top-level widget associated with this window, its size will be set right after this function. | If there is a top-level widget associated with this window, its size will be set right after this function. | ||||
TODO this seems wrong, top-level widget should be resized here | |||||
*/ | */ | ||||
virtual void onReshape(uint width, uint height); | virtual void onReshape(uint width, uint height); | ||||
@@ -318,10 +333,6 @@ END_NAMESPACE_DGL | |||||
}; | }; | ||||
#endif // DGL_FILE_BROWSER_DISABLED | #endif // DGL_FILE_BROWSER_DISABLED | ||||
static Window& withTransientParentWindow(Window& transientParentWindow); | |||||
void exec(bool lockWait = false); | |||||
void addIdleCallback(IdleCallback* const callback); | void addIdleCallback(IdleCallback* const callback); | ||||
void removeIdleCallback(IdleCallback* const callback); | void removeIdleCallback(IdleCallback* const callback); | ||||
@@ -23,12 +23,12 @@ START_NAMESPACE_DGL | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Window | // Window | ||||
// Window::Window(Window& transientParentWindow) | |||||
// : pData(new PrivateData(transientParentWindow.pData->fAppData, this, transientParentWindow)) {} | |||||
Window::Window(Application& app) | Window::Window(Application& app) | ||||
: pData(new PrivateData(app, this)) {} | : pData(new PrivateData(app, this)) {} | ||||
Window::Window(Application& app, Window& parent) | |||||
: pData(new PrivateData(app, this, parent.pData)) {} | |||||
Window::Window(Application& app, | Window::Window(Application& app, | ||||
const uintptr_t parentWindowHandle, | const uintptr_t parentWindowHandle, | ||||
const double scaleFactor, | const double scaleFactor, | ||||
@@ -170,10 +170,7 @@ double Window::getScaleFactor() const noexcept | |||||
void Window::focus() | void Window::focus() | ||||
{ | { | ||||
if (! pData->isEmbed) | |||||
puglRaiseWindow(pData->view); | |||||
puglGrabFocus(pData->view); | |||||
pData->focus(); | |||||
} | } | ||||
void Window::repaint() noexcept | void Window::repaint() noexcept | ||||
@@ -192,6 +189,11 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept | |||||
puglPostRedisplayRect(pData->view, prect); | puglPostRedisplayRect(pData->view, prect); | ||||
} | } | ||||
void Window::runAsModal(bool blockWait) | |||||
{ | |||||
pData->runAsModal(blockWait); | |||||
} | |||||
void Window::setGeometryConstraints(const uint minimumWidth, | void Window::setGeometryConstraints(const uint minimumWidth, | ||||
const uint minimumHeight, | const uint minimumHeight, | ||||
const bool keepAspectRatio, | const bool keepAspectRatio, | ||||
@@ -242,13 +244,6 @@ void Window::onReshape(uint, uint) | |||||
} | } | ||||
#if 0 | #if 0 | ||||
#if 0 | |||||
void Window::exec(bool lockWait) | |||||
{ | |||||
pData->exec(lockWait); | |||||
} | |||||
#endif | |||||
void Window::setTransientWinId(const uintptr_t winId) | void Window::setTransientWinId(const uintptr_t winId) | ||||
{ | { | ||||
puglSetTransientFor(pData->fView, winId); | puglSetTransientFor(pData->fView, winId); | ||||
@@ -63,12 +63,13 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) | |||||
autoScaling(false), | autoScaling(false), | ||||
autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
minWidth(0), | minWidth(0), | ||||
minHeight(0) | |||||
minHeight(0), | |||||
modal(this) | |||||
{ | { | ||||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | ||||
} | } | ||||
Window::PrivateData::PrivateData(Application& a, Window* const s, Window& transientWindow) | |||||
Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* const ppData) | |||||
: app(a), | : app(a), | ||||
appData(a.pData), | appData(a.pData), | ||||
self(s), | self(s), | ||||
@@ -77,15 +78,16 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, Window& transi | |||||
isClosed(true), | isClosed(true), | ||||
isVisible(false), | isVisible(false), | ||||
isEmbed(false), | isEmbed(false), | ||||
scaleFactor(getDesktopScaleFactor()), | |||||
scaleFactor(ppData->scaleFactor), | |||||
autoScaling(false), | autoScaling(false), | ||||
autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
minWidth(0), | minWidth(0), | ||||
minHeight(0) | |||||
minHeight(0), | |||||
modal(this, ppData) | |||||
{ | { | ||||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | ||||
puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | |||||
puglSetTransientFor(view, puglGetNativeWindow(ppData->view)); | |||||
} | } | ||||
Window::PrivateData::PrivateData(Application& a, Window* const s, | Window::PrivateData::PrivateData(Application& a, Window* const s, | ||||
@@ -103,7 +105,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
autoScaling(false), | autoScaling(false), | ||||
autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
minWidth(0), | minWidth(0), | ||||
minHeight(0) | |||||
minHeight(0), | |||||
modal(this) | |||||
{ | { | ||||
if (isEmbed) | if (isEmbed) | ||||
{ | { | ||||
@@ -136,7 +139,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
autoScaling(false), | autoScaling(false), | ||||
autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
minWidth(0), | minWidth(0), | ||||
minHeight(0) | |||||
minHeight(0), | |||||
modal(this) | |||||
{ | { | ||||
if (isEmbed) | if (isEmbed) | ||||
{ | { | ||||
@@ -279,16 +283,26 @@ void Window::PrivateData::hide() | |||||
// } | // } | ||||
#endif | #endif | ||||
puglHide(view); | |||||
if (modal.enabled) | |||||
stopModal(); | |||||
// if (fModal.enabled) | |||||
// exec_fini(); | |||||
puglHide(view); | |||||
isVisible = false; | isVisible = false; | ||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
void Window::PrivateData::focus() | |||||
{ | |||||
if (! isEmbed) | |||||
puglRaiseWindow(view); | |||||
puglGrabFocus(view); | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
void Window::PrivateData::close() | void Window::PrivateData::close() | ||||
{ | { | ||||
DGL_DBG("Window close\n"); | DGL_DBG("Window close\n"); | ||||
@@ -327,13 +341,91 @@ void Window::PrivateData::idleCallback() | |||||
// std::free(buffer); | // std::free(buffer); | ||||
// } | // } | ||||
// #endif | // #endif | ||||
// | |||||
// if (fModal.enabled && fModal.parent != nullptr) | |||||
// fModal.parent->windowSpecificIdle(); | |||||
// self->repaint(); | |||||
// if (modal.enabled && modal.parent != nullptr) | |||||
// modal.parent->idleCallback(); | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// modal handling | |||||
void Window::PrivateData::startModal() | |||||
{ | |||||
DGL_DBG("Window modal loop starting..."); DGL_DBGF; | |||||
DISTRHO_SAFE_ASSERT_RETURN(modal.parent != nullptr, show()); | |||||
// activate modal mode for this window | |||||
modal.enabled = true; | |||||
// make parent give focus to us | |||||
modal.parent->modal.child = this; | |||||
// make sure both parent and ourselves are visible | |||||
modal.parent->show(); | |||||
show(); | |||||
DGL_DBG("Ok\n"); | |||||
} | |||||
void Window::PrivateData::stopModal() | |||||
{ | |||||
DGL_DBG("Window modal loop stopping..."); DGL_DBGF; | |||||
// deactivate modal mode | |||||
modal.enabled = false; | |||||
// safety checks, make sure we have a parent and we are currently active as the child to give focus to | |||||
if (modal.parent == nullptr) | |||||
return; | |||||
if (modal.parent->modal.child != this) | |||||
return; | |||||
// stop parent from giving focus to us, so it behaves like normal | |||||
modal.parent->modal.child = nullptr; | |||||
// the mouse position probably changed since the modal appeared, | |||||
// so send a mouse motion event to the modal's parent window | |||||
#if 0 | |||||
#if defined(DISTRHO_OS_HAIKU) | |||||
// TODO | |||||
#elif defined(DISTRHO_OS_MAC) | |||||
// TODO | |||||
#elif defined(DISTRHO_OS_WINDOWS) | |||||
// TODO | |||||
#else | |||||
int i, wx, wy; | |||||
uint u; | |||||
::Window w; | |||||
if (XQueryPointer(fModal.parent->xDisplay, fModal.parent->xWindow, &w, &w, &i, &i, &wx, &wy, &u) == True) | |||||
fModal.parent->onPuglMotion(wx, wy); | |||||
#endif | |||||
#endif | |||||
DGL_DBG("Ok\n"); | |||||
} | |||||
void Window::PrivateData::runAsModal(const bool blockWait) | |||||
{ | |||||
DGL_DBGp("Window::PrivateData::runAsModal %i\n", blockWait); | |||||
startModal(); | |||||
if (blockWait) | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(appData->isStandalone,); | |||||
while (isVisible && modal.enabled) | |||||
appData->idle(10); | |||||
stopModal(); | |||||
} | |||||
else | |||||
{ | |||||
appData->idle(0); | |||||
} | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
// pugl events | |||||
void Window::PrivateData::onPuglConfigure(const int width, const int height) | void Window::PrivateData::onPuglConfigure(const int width, const int height) | ||||
{ | { | ||||
@@ -372,14 +464,19 @@ void Window::PrivateData::onPuglClose() | |||||
{ | { | ||||
DGL_DBG("PUGL: onClose\n"); | DGL_DBG("PUGL: onClose\n"); | ||||
// if (fModal.enabled) | |||||
// exec_fini(); | |||||
if (! self->onClose()) | if (! self->onClose()) | ||||
return; | return; | ||||
// if (fModal.childFocus != nullptr) | |||||
// fModal.childFocus->fSelf->onClose(); | |||||
if (modal.enabled) | |||||
stopModal(); | |||||
if (modal.child != nullptr) | |||||
{ | |||||
if (modal.child->modal.enabled) | |||||
modal.child->stopModal(); | |||||
modal.child->close(); | |||||
} | |||||
close(); | close(); | ||||
} | } | ||||
@@ -388,8 +485,8 @@ void Window::PrivateData::onPuglFocus(const bool focus, const CrossingMode mode) | |||||
{ | { | ||||
DGL_DBGp("onPuglFocus : %i %i\n", focus, mode); | DGL_DBGp("onPuglFocus : %i %i\n", focus, mode); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
self->onFocus(focus, mode); | self->onFocus(focus, mode); | ||||
@@ -400,8 +497,8 @@ void Window::PrivateData::onPuglKey(const Events::KeyboardEvent& ev) | |||||
{ | { | ||||
DGL_DBGp("onPuglKey : %i %u %u\n", ev.press, ev.key, ev.keycode); | DGL_DBGp("onPuglKey : %i %u %u\n", ev.press, ev.key, ev.keycode); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
@@ -413,8 +510,8 @@ void Window::PrivateData::onPuglSpecial(const Events::SpecialEvent& ev) | |||||
{ | { | ||||
DGL_DBGp("onPuglSpecial : %i %u\n", ev.press, ev.key); | DGL_DBGp("onPuglSpecial : %i %u\n", ev.press, ev.key); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
@@ -426,8 +523,8 @@ void Window::PrivateData::onPuglText(const Events::CharacterInputEvent& ev) | |||||
{ | { | ||||
DGL_DBGp("onPuglText : %u %u %s\n", ev.keycode, ev.character, ev.string); | DGL_DBGp("onPuglText : %u %u %s\n", ev.keycode, ev.character, ev.string); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
@@ -439,8 +536,8 @@ void Window::PrivateData::onPuglMouse(const Events::MouseEvent& ev) | |||||
{ | { | ||||
DGL_DBGp("onPuglMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); | DGL_DBGp("onPuglMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
@@ -452,8 +549,8 @@ void Window::PrivateData::onPuglMotion(const Events::MotionEvent& ev) | |||||
{ | { | ||||
DGL_DBGp("onPuglMotion : %f %f\n", ev.pos.getX(), ev.pos.getY()); | DGL_DBGp("onPuglMotion : %f %f\n", ev.pos.getX(), ev.pos.getY()); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
@@ -465,8 +562,8 @@ void Window::PrivateData::onPuglScroll(const Events::ScrollEvent& ev) | |||||
{ | { | ||||
DGL_DBGp("onPuglScroll : %f %f %f %f\n", ev.pos.getX(), ev.pos.getY(), ev.delta.getX(), ev.delta.getY()); | DGL_DBGp("onPuglScroll : %f %f %f %f\n", ev.pos.getX(), ev.pos.getY(), ev.delta.getX(), ev.delta.getY()); | ||||
// if (fModal.childFocus != nullptr) | |||||
// return fModal.childFocus->focus(); | |||||
if (modal.child != nullptr) | |||||
return modal.child->focus(); | |||||
#ifndef DPF_TEST_WINDOW_CPP | #ifndef DPF_TEST_WINDOW_CPP | ||||
if (topLevelWidget != nullptr) | if (topLevelWidget != nullptr) | ||||
@@ -68,11 +68,40 @@ struct Window::PrivateData : IdleCallback { | |||||
/** Pugl minWidth, minHeight access. */ | /** Pugl minWidth, minHeight access. */ | ||||
uint minWidth, minHeight; | uint minWidth, minHeight; | ||||
/** Modal window setup. */ | |||||
struct Modal { | |||||
// PrivateData* self; // pointer to PrivateData this Modal class belongs to | |||||
PrivateData* parent; // parent of this window (so we can become modal) | |||||
PrivateData* child; // child window to give focus to when modal mode is enabled | |||||
bool enabled; // wherever modal mode is enabled (only possible if parent != null) | |||||
/** Constructor for a non-modal window. */ | |||||
Modal(PrivateData* const s) noexcept | |||||
: parent(nullptr), | |||||
child(nullptr), | |||||
enabled(false) {} | |||||
/** Constructor for a modal window (with a parent). */ | |||||
Modal(PrivateData* const s, PrivateData* const p) noexcept | |||||
: parent(p), | |||||
child(nullptr), | |||||
enabled(false) {} | |||||
/** Destructor. */ | |||||
~Modal() noexcept | |||||
{ | |||||
DISTRHO_SAFE_ASSERT(! enabled); | |||||
} | |||||
} modal; | |||||
/** Constructor for a regular, standalone window. */ | /** Constructor for a regular, standalone window. */ | ||||
explicit PrivateData(Application& app, Window* self); | explicit PrivateData(Application& app, Window* self); | ||||
/** Constructor for a modal window. */ | |||||
explicit PrivateData(Application& app, Window* self, PrivateData* ppData); | |||||
/** Constructor for a regular, standalone window with a transient parent. */ | /** Constructor for a regular, standalone window with a transient parent. */ | ||||
explicit PrivateData(Application& app, Window* self, Window& transientWindow); | |||||
// explicit PrivateData(Application& app, Window* self, Window& transientWindow); | |||||
/** Constructor for an embed Window, with a few extra hints from the host side. */ | /** Constructor for an embed Window, with a few extra hints from the host side. */ | ||||
explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable); | explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable); | ||||
@@ -89,6 +118,7 @@ struct Window::PrivateData : IdleCallback { | |||||
void show(); | void show(); | ||||
void hide(); | void hide(); | ||||
void focus(); | |||||
/** Hide window and notify application of a window close event. | /** Hide window and notify application of a window close event. | ||||
* Does nothing if window is embed (that is, not standalone). | * Does nothing if window is embed (that is, not standalone). | ||||
@@ -105,6 +135,11 @@ struct Window::PrivateData : IdleCallback { | |||||
void idleCallback() override; | void idleCallback() override; | ||||
// modal handling | |||||
void startModal(); | |||||
void stopModal(); | |||||
void runAsModal(bool blockWait); | |||||
// pugl events | // pugl events | ||||
void onPuglConfigure(int width, int height); | void onPuglConfigure(int width, int height); | ||||
void onPuglExpose(); | void onPuglExpose(); | ||||
@@ -128,39 +163,6 @@ struct Window::PrivateData : IdleCallback { | |||||
END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
#if 0 | #if 0 | ||||
// this one depends on build type | |||||
// GraphicsContext fContext; | |||||
bool fFirstInit; | |||||
bool fVisible; | |||||
bool fUsingEmbed; | |||||
double fScaling; | |||||
double fAutoScaling; | |||||
struct Modal { | |||||
bool enabled; | |||||
PrivateData* parent; | |||||
PrivateData* childFocus; | |||||
Modal() | |||||
: enabled(false), | |||||
parent(nullptr), | |||||
childFocus(nullptr) {} | |||||
Modal(PrivateData* const p) | |||||
: enabled(false), | |||||
parent(p), | |||||
childFocus(nullptr) {} | |||||
~Modal() | |||||
{ | |||||
DISTRHO_SAFE_ASSERT(! enabled); | |||||
DISTRHO_SAFE_ASSERT(childFocus == nullptr); | |||||
} | |||||
DISTRHO_DECLARE_NON_COPY_STRUCT(Modal) | |||||
} fModal; | |||||
// #if defined(DISTRHO_OS_HAIKU) | // #if defined(DISTRHO_OS_HAIKU) | ||||
// BApplication* bApplication; | // BApplication* bApplication; | ||||
// BView* bView; | // BView* bView; | ||||
@@ -189,74 +191,6 @@ END_NAMESPACE_DGL | |||||
struct Window::PrivateData { | struct Window::PrivateData { | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
void exec(const bool lockWait) | |||||
{ | |||||
DBG("Window exec\n"); | |||||
exec_init(); | |||||
if (lockWait) | |||||
{ | |||||
for (; fVisible && fModal.enabled;) | |||||
{ | |||||
idle(); | |||||
d_msleep(10); | |||||
} | |||||
exec_fini(); | |||||
} | |||||
else | |||||
{ | |||||
idle(); | |||||
} | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
void exec_init() | |||||
{ | |||||
DBG("Window modal loop starting..."); DBGF; | |||||
DISTRHO_SAFE_ASSERT_RETURN(fModal.parent != nullptr, setVisible(true)); | |||||
fModal.enabled = true; | |||||
fModal.parent->fModal.childFocus = this; | |||||
fModal.parent->setVisible(true); | |||||
setVisible(true); | |||||
DBG("Ok\n"); | |||||
} | |||||
void exec_fini() | |||||
{ | |||||
DBG("Window modal loop stopping..."); DBGF; | |||||
fModal.enabled = false; | |||||
if (fModal.parent != nullptr) | |||||
{ | |||||
fModal.parent->fModal.childFocus = nullptr; | |||||
// the mouse position probably changed since the modal appeared, | |||||
// so send a mouse motion event to the modal's parent window | |||||
#if defined(DISTRHO_OS_HAIKU) | |||||
// TODO | |||||
#elif defined(DISTRHO_OS_MAC) | |||||
// TODO | |||||
#elif defined(DISTRHO_OS_WINDOWS) | |||||
// TODO | |||||
#else | |||||
int i, wx, wy; | |||||
uint u; | |||||
::Window w; | |||||
if (XQueryPointer(fModal.parent->xDisplay, fModal.parent->xWindow, &w, &w, &i, &i, &wx, &wy, &u) == True) | |||||
fModal.parent->onPuglMotion(wx, wy); | |||||
#endif | |||||
} | |||||
DBG("Ok\n"); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
bool handlePluginSpecial(const bool press, const Key key) | bool handlePluginSpecial(const bool press, const Key key) | ||||
{ | { | ||||
DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key); | DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key); | ||||