getScreenX / getScreenY on the AudioProcessorEditor always report 0


#1

As the title says, i'm the only one experiencing this ?


#2

Haven't heard anything like that before. Is it defintely visible when you call this? Tried stepping into it with the debugger?


#3

yes i need to step into it to see what is happening.

i discovered that this behaviour happens only when the plugin is bridged (64bit host > 32bit plugin) but when not bridged (64 > 64 or 32 > 32) the size is reported correctly.

i will let you know soon...


#4

I've stepped into the problem, where a PopuMenu is created inside a buttonClicked callback of a Button already added in the editor and shown. The LinuxComponentPeer bounds report 0 for x and y, even if the editor is in the center of the screen. The code is from latest version modules available in Introjucer.

Locals        

        p    @0x7f9486384390    juce::Point<int>
            x    13    int
            y    8    int
        this    @0x9bd59f0    juce::LinuxComponentPeer
            [juce::ComponentPeer]    @0x9bd59f0    juce::ComponentPeer
            bounds    @0x9bd5a58    juce::Rectangle<int>
                h    462    int
                pos    @0x9bd5a58    juce::Point<int>
                    x    0    int
                    y    0    int
                w    930    int


0    juce::ComponentPeer::localToGlobal    juce_ComponentPeer.cpp    402    0x7f9484ab3033    
1    juce::Component::ComponentHelpers::convertToParentSpace<juce::Point<int>>    juce_Component.cpp    345    0x7f9484b01dfe    
2    juce::Component::ComponentHelpers::convertCoordinate<juce::Point<int>>    juce_Component.cpp    384    0x7f9484b01361    
3    juce::Component::localPointToGlobal    juce_Component.cpp    1068    0x7f9484a226f3    
4    juce::Component::getScreenPosition    juce_Component.cpp    1043    0x7f9484a223c8    
5    juce::Component::getScreenX    juce_Component.cpp    1040    0x7f9484a22324    
6    FooBarEditor::buttonClicked    FooBarEditor.cpp    1453518    0x7f948473a0de    
7    juce::ListenerList<juce::Button::Listener, juce::Array<juce::Button::Listener*, juce::DummyCriticalSection, 0>>::callChecked<juce::Component::BailOutChecker, juce::Button*>    juce_ListenerList.h    178    0x7f9484b055d7    
8    juce::Button::sendClickMessage    juce_Button.cpp    410    0x7f9484a3270a    
9    juce::Button::internalClickCallback    juce_Button.cpp    354    0x7f9484a324ae    
10    juce::Button::mouseUp    juce_Button.cpp    460    0x7f9484a32a65    
11    juce::Component::internalMouseUp    juce_Component.cpp    2493    0x7f9484a281e4    
12    juce::MouseInputSourceInternal::sendMouseUp    juce_MouseInputSource.cpp    147    0x7f9484ac96a5    
13    juce::MouseInputSourceInternal::setButtons    juce_MouseInputSource.cpp    189    0x7f9484ac9b66    
14    juce::MouseInputSourceInternal::handleEvent    juce_MouseInputSource.cpp    306    0x7f9484aca684    
15    juce::MouseInputSource::handleEvent    juce_MouseInputSource.cpp    567    0x7f9484a2ab79    
16    juce::ComponentPeer::handleMouseEvent    juce_ComponentPeer.cpp    91    0x7f9484ab1ecf    
17    juce::LinuxComponentPeer::handleButtonReleaseEvent    juce_linux_Windowing.cpp    1560    0x7f9484afad23    
18    juce::LinuxComponentPeer::handleWindowMessage    juce_linux_Windowing.cpp    1300    0x7f9484af9fe9    
19    juce::LinuxComponentPeer::windowMessageReceive    juce_linux_Windowing.cpp    856    0x7f9484af82bf    
20    juce::InternalMessageQueue::dispatchNextXEvent    juce_linux_Messaging.cpp    174    0x7f948493d4c7    
...    <More>                


#5
void LinuxComponentPeer::updateWindowBounds()
{
    jassert (windowH != 0);
    if (windowH != 0)
    {
        Window root, child;
        int wx = 0, wy = 0;
        unsigned int ww = 0, wh = 0, bw, depth;

        ScopedXLock xlock;

        if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &depth))
            if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child))
                wx = wy = 0;

        bounds.setBounds (wx, wy, ww, wh);
    }
}

maybe there is something that do not work here for some reason ?


#6

There was something on another thread that mentioned that X windows don't always get created instantly, so their coords may be wrong for a few milliseconds after creating them. I hadn't seen that happen myself, but maybe that's what's happening here?


#7

i doubt it is the same problem... cause even after 10 seconds the window has been shown and dragged around the problem persist. 

since the VST juce::EditorCompWrapper is reparented in the host window, any call to LinuxComponentPeer::updateWindowBounds when the host window is moved are ignored...

i fact calling updateWindowBounds just before calling Component::getScreenX() make it work. Pity is only a horrible hack. 


#8
diff --git a/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
index 2fbc6cb..c8155cc 100644
--- a/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
+++ b/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
@@ -2220,7 +2220,9 @@ private:
         swa.override_redirect = (component.isAlwaysOnTop() && (styleFlags & windowIsTemporary) != 0) ? True : False;
         swa.event_mask = getAllEventsMask();
 
-        windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root,
+        parentWindow = (parentToAddTo != 0) ? parentToAddTo : root;
+
+        windowH = XCreateWindow (display, parentWindow,
                                  0, 0, 1, 1,
                                  0, depth, InputOutput, visual,
                                  CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect,
@@ -2302,7 +2304,7 @@ private:
     {
         return NoEventMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
                  | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
-                 | ExposureMask | StructureNotifyMask | FocusChangeMask;
+                 | ExposureMask | SubstructureNotifyMask | FocusChangeMask;
     }
 
     template <typename EventType>

this seems to fix. don't know actually if it's a terrible hack, but it works... any ideas ?


#9

Not sure what your first change is supposed to do? i.e. the assignment to parentWindow doesn't appear to make any difference?

The substructurenotify mask bit, I really don't know anything about - it may or may not be a sensible change, but I'd be worried that it might stop something else being updated..


#10

SubstructureNotifyMask will ask to be notified not only for events directly happening on the window, but also on the parent hierarchy (when the window is a child of another one, which is the case of a plugin reparented window). So if our parent window move (in case of a host window), we will get notified too.

the first change probably can be avoided but i think it is a typo in the library i think, cause parentWindow is set to 0 even if a window is created as child of another window. for completeness....


#11

diff --git a/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp                      
index 2fbc6cb..30d5c0b 100644
--- a/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
+++ b/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
@@ -2199,6 +2199,9 @@ private:
         const int screen = DefaultScreen (display);
         Window root = RootWindow (display, screen);
 
+        // Remember we are children of parent window
+        parentWindow = parentToAddTo;
+
         // Try to obtain a 32-bit visual or fallback to 24 or 16
         visual = Visuals::findVisualFormat ((styleFlags & windowIsSemiTransparent) ? 32 : 24, depth);
 
@@ -2220,7 +2223,7 @@ private:
         swa.override_redirect = (component.isAlwaysOnTop() && (styleFlags & windowIsTemporary) != 0) ? True : False;
         swa.event_mask = getAllEventsMask();
 
-        windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root,
+        windowH = XCreateWindow (display, parentWindow != 0 ? parentWindow : root,
                                  0, 0, 1, 1,
                                  0, depth, InputOutput, visual,
                                  CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect,
@@ -2298,11 +2301,12 @@ private:
         {}
     }
 
-    static int getAllEventsMask() noexcept
+    int getAllEventsMask() noexcept
     {
-        return NoEventMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
+        const int eventMask = (parentWindow != 0) ? SubstructureNotifyMask : StructureNotifyMask;
+        return eventMask | NoEventMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
                  | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
-                 | ExposureMask | StructureNotifyMask | FocusChangeMask;
+                 | ExposureMask | FocusChangeMask;
     }
 
     template <typename EventType>

what do you think ? it fixes things for me when running under a host window.


#12

Thanks, seems legit, I'll add something like that..


#13

thanx !