]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/toplevel.cpp
Removed notebook tab flicker.
[wxWidgets.git] / src / x11 / toplevel.cpp
index 69a6f46c178211dba22d5ba5c58cb5349002d30f..e63799559c59d477b8c4d264b2367d89169cbc9a 100644 (file)
@@ -62,7 +62,7 @@ void wxTopLevelWindowX11::Init()
     m_fsIsMaximized = FALSE;
     m_fsIsShowing = FALSE;
     
-    m_focusWidget = NULL;
+    m_needResizeInIdle = FALSE;
 }
 
 bool wxTopLevelWindowX11::Create(wxWindow *parent,
@@ -101,6 +101,18 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
     m_backgroundColour.CalcPixel( (WXColormap) cm );
     m_hasBgCol = TRUE;
        
+    wxSize size2(size);
+    if (size2.x == -1)
+       size2.x = 100;
+    if (size2.y == -1)
+       size2.y = 100;
+
+    wxPoint pos2(pos);
+    if (pos2.x == -1)
+       pos2.x = 100;
+    if (pos2.y == -1)
+       pos2.y = 100;
+    
 #if !wxUSE_NANOX
     XSetWindowAttributes xattributes;
     XSizeHints size_hints;
@@ -115,21 +127,11 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
     // TODO: if we want no border, caption etc.,
     // I think we set this to True to remove decorations
     // No. RR.
-    xattributes.override_redirect = False;
+    // Yes :-) JACS (because some WMs don't respect
+    // the hints)
+    xattributes.override_redirect = (style & wxNO_BORDER) ? True : False;
 #endif
     
-    wxSize size2(size);
-    if (size2.x == -1)
-       size2.x = 100;
-    if (size2.y == -1)
-       size2.y = 100;
-
-    wxPoint pos2(pos);
-    if (pos2.x == -1)
-       pos2.x = 100;
-    if (pos2.y == -1)
-       pos2.y = 100;
-    
 #if wxUSE_NANOX
     long backColor, foreColor;
     backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue());
@@ -149,11 +151,23 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
 #endif
 
     XSelectInput( xdisplay, xwindow,
-        extraFlags | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
-        ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
-        KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
-        PropertyChangeMask );
-
+                  extraFlags |
+                  ExposureMask |
+                  KeyPressMask |
+                  KeyReleaseMask |
+                  ButtonPressMask |
+                  ButtonReleaseMask |
+                  ButtonMotionMask |
+                  EnterWindowMask |
+                  LeaveWindowMask |
+                  PointerMotionMask |
+                  KeymapStateMask |
+                  FocusChangeMask |
+                  ColormapChangeMask |
+                  StructureNotifyMask |
+                  PropertyChangeMask
+                  );
+    
     wxAddWindowToTable( xwindow, (wxWindow*) this );
 
     // Set background to None which will prevent X11 from clearing the
@@ -213,12 +227,53 @@ wxTopLevelWindowX11::~wxTopLevelWindowX11()
     }
 }
 
+void wxTopLevelWindowX11::OnInternalIdle()
+{
+    wxWindow::OnInternalIdle();
+    
+    if (m_needResizeInIdle)
+    {
+        wxSizeEvent event( GetClientSize(), GetId() );
+        event.SetEventObject( this );
+        GetEventHandler()->ProcessEvent( event );
+        
+        m_needResizeInIdle = FALSE;
+    }
+}
+
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowX11 showing
 // ----------------------------------------------------------------------------
 
 bool wxTopLevelWindowX11::Show(bool show)
 {
+    // Nano-X has to force a size event,
+    // else there's no initial size.
+#if wxUSE_NANOX
+    if (show)
+#else
+    if (show && m_needResizeInIdle)
+#endif
+    {
+        wxSizeEvent event(GetSize(), GetId());
+        event.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(event);
+        
+        m_needResizeInIdle = FALSE;
+    }
+
+    if (show)
+    {
+        // This does the layout _before_ the
+        // window is shown, else the items are
+        // drawn first at the wrong positions,
+        // then at the correct positions.
+        if (GetAutoLayout())
+        {
+            Layout();
+        }
+    }
+
     return wxWindowX11::Show(show);
 }
 
@@ -384,6 +439,7 @@ bool wxSetWMDecorations(Window w, long style)
     GR_WM_PROPERTIES wmProp;
 
     wmProp.flags = 0;
+    wmProp.props = 0;
 
     if (style & wxRESIZE_BORDER)
     {
@@ -403,6 +459,11 @@ bool wxSetWMDecorations(Window w, long style)
     {
         wmProp.props |= GR_WM_PROPS_CAPTION ;
         wmProp.flags |= GR_WM_FLAGS_PROPS ;
+
+        // The default dialog style doesn't include any kind
+        // of border, which is a bit odd. Anyway, inclusion
+        // of a caption surely implies a border.
+        style |= wxTHICK_FRAME;
     }
 
     if (style & wxTHICK_FRAME)
@@ -468,7 +529,7 @@ bool wxSetWMDecorations(Window w, long style)
         hints.decorations |= MWM_DECOR_TITLE;
     }
 
-    if ((style & wxTHICK_FRAME) || (style & wxSIMPLE_BORDER) || (style & wxCAPTION))
+    if ((style & wxTHICK_FRAME) || (style & wxCAPTION))
     {
         // wxLogDebug("MWM_DECOR_BORDER");
         hints.flags |= MWM_HINTS_DECORATIONS;
@@ -528,112 +589,126 @@ bool wxMWMIsRunning(Window w)
 // smaller
 wxPoint wxTopLevelWindowX11::GetClientAreaOrigin() const
 {
-    // In fact wxFrame::GetClientAreaOrigin
+    // wxFrame::GetClientAreaOrigin
     // does the required calculation already.
-#if 0
-    if (this->IsKindOf(CLASSINFO(wxFrame)))
-    {
-       wxFrame* frame = (wxFrame*) this;
-       if (frame->GetMenuBar())
-           return wxPoint(0, frame->GetMenuBar()->GetSize().y);
-    }
-#endif
     return wxPoint(0, 0);
 }
 
 void wxTopLevelWindowX11::DoGetClientSize( int *width, int *height ) const
 {
+    XSync(wxGlobalDisplay(), False);
     wxWindowX11::DoGetClientSize(width, height);
-    // Done by wxTopLevelWindow
-#if 0
-    if (this->IsKindOf(CLASSINFO(wxFrame)))
-    {
-       wxFrame* frame = (wxFrame*) this;
-       if (frame->GetMenuBar())
-           (*height) -= frame->GetMenuBar()->GetSize().y;
-       if (frame->GetStatusBar())
-           (*height) -= frame->GetStatusBar()->GetSize().y;
-    }
-#endif
 }
 
 void wxTopLevelWindowX11::DoSetClientSize(int width, int height)
 {
     wxWindowX11::DoSetClientSize(width, height);
 
-#if 0
-    if (!GetMainWindow())
-        return;
+#if !wxUSE_NANOX
+    // Set the top-level window size
+    XSizeHints size_hints;
+    wxSize oldSize = GetSize();
+    wxSize oldClientSize = GetClientSize();
 
-    XWindowChanges windowChanges;
-    int valueMask = 0;
+    size_hints.flags = PSize;
+    size_hints.width = width + (oldSize.x - oldClientSize.x);
+    size_hints.height = height + (oldSize.y - oldClientSize.y);
+    XSetWMNormalHints( (Display*) GetXDisplay(), (Window) GetMainWindow(),
+                       &size_hints);
 
-    if (width != -1)
-    {
-        windowChanges.width = width ;
-        valueMask |= CWWidth;
-    }
-    if (height != -1)
-    {
-        windowChanges.height = height ;
-        valueMask |= CWHeight;
-    }
-    XConfigureWindow(wxGlobalDisplay(), (Window) GetMainWindow(),
-        valueMask, & windowChanges);
+    // This seems to be necessary or resizes don't get performed
+    XSync(wxGlobalDisplay(), False);
+    XSync(wxGlobalDisplay(), False);
+
+#if 0
+    wxLogDebug("DoSetClientSize: Tried to set size to %d, %d", (int) size_hints.width, (int) size_hints.height);
+
+    XSync(wxGlobalDisplay(), False);
+    wxSize newSize = GetSize();
+    wxLogDebug("New size is %d, %d", (int) newSize.x, (int) newSize.y);
+#endif
 #endif
 }
 
 void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
+#if 0
     // wxLogDebug( "Setting pos: %d, %d", x, y );
     wxWindowX11::DoSetSize(x, y, width, height, sizeFlags);
-
-    wxPoint pt = GetPosition();
-    // wxLogDebug( "After, pos: %d, %d", pt.x, pt.y );
-#if 0
+#endif
     XSync(wxGlobalDisplay(), False);
-    int w, h;
-    GetSize(& w, & h);
-    wxString msg;
-    msg.Printf("Before setting size: %d, %d", w, h);
-    wxLogDebug(msg);
-    if (!GetMainWindow())
-        return;
+    Window window = (Window) m_mainWidget;
+    if (!window)
+        return ;
+
+    Display *display = (Display*) GetXDisplay();
+    Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
+    Window parent_window = window,
+        next_parent   = window;
+
+    // search for the parent that is child of ROOT, because the WM may
+    // reparent twice and notify only the next parent (like FVWM)
+    while (next_parent != root) {
+        Window *theChildren;
+#if wxUSE_NANOX
+        GR_COUNT n;
+#else
+        unsigned int n;
+#endif
+        parent_window = next_parent;
+        XQueryTree(display, parent_window, &root,
+            &next_parent, &theChildren, &n);
+        XFree(theChildren); // not needed
+    }
 
     XWindowChanges windowChanges;
-    int valueMask = 0;
+    windowChanges.x = x;
+    windowChanges.y = y;
+    windowChanges.width = width;
+    windowChanges.height = height;
+    windowChanges.stack_mode = 0;
+    int valueMask = CWX | CWY | CWWidth | CWHeight;
 
     if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
     {
-        int yy = 0;
-        AdjustForParentClientOrigin( x, yy, sizeFlags);
-        windowChanges.x = x;
         valueMask |= CWX;
     }
     if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
     {
-        int xx = 0;
-        AdjustForParentClientOrigin( xx, y, sizeFlags);
-        windowChanges.y = y;
         valueMask |= CWY;
     }
-    if (width != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+    if (width != -1)
     {
-        windowChanges.width = width /* - m_borderSize*2 */;
+        windowChanges.width = wxMax(1, width);
         valueMask |= CWWidth;
     }
-    if (height != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+    if (height != -1)
     {
-        windowChanges.height = height /* -m_borderSize*2*/;
+        windowChanges.height = wxMax(1, height);
         valueMask |= CWHeight;
     }
 
-    XConfigureWindow(wxGlobalDisplay(), (Window) GetMainWindow(),
-                    valueMask, & windowChanges);
+    XConfigureWindow( display, parent_window, valueMask, &windowChanges );
+
+#if !wxUSE_NANOX    
+    XSizeHints size_hints;
+    size_hints.flags = 0;
+    if (x > -1 && y > -1)
+        size_hints.flags |= PPosition;
+    if (width > -1 && height > -1)
+        size_hints.flags |= PSize;
+    size_hints.width = width;
+    size_hints.height = height;
+    size_hints.x = x;
+    size_hints.y = y;
+    XSetWMNormalHints( (Display*) GetXDisplay(), (Window) GetMainWindow(),
+                       &size_hints);
+
+    // This seems to be necessary or resizes don't get performed.
+    // Take them out (or even just one of them), and the About
+    // box of the minimal sample probably won't be resized right.
+    XSync(wxGlobalDisplay(), False);
     XSync(wxGlobalDisplay(), False);
-    GetSize(& w, & h);
-    msg.Printf("Tried to set to %d, %d. After setting size: %d, %d", width, height, w, h);
-    wxLogDebug(msg);
 #endif
 }
 
@@ -641,28 +716,46 @@ void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const
 {
     XSync(wxGlobalDisplay(), False);
     Window window = (Window) m_mainWidget;
-    if (window)
-    {
-        int offsetX = 0;
-        int offsetY = 0;
-       
-#if !wxUSE_NANOX
-        // wxLogDebug("Translating...");
-        Window childWindow;
-        XTranslateCoordinates(wxGlobalDisplay(), window, XDefaultRootWindow(wxGlobalDisplay()),
-                                 0, 0, & offsetX, & offsetY, & childWindow);
-
-        // wxLogDebug("Offset: %d, %d", offsetX, offsetY);
+    if (!window)
+        return ;
+
+    Display *display = (Display*) GetXDisplay();
+    Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
+    Window parent_window = window,
+        next_parent   = window;
+
+    // search for the parent that is child of ROOT, because the WM may
+    // reparent twice and notify only the next parent (like FVWM)
+    while (next_parent != root) {
+        Window *theChildren;
+#if wxUSE_NANOX
+        GR_COUNT n;
+#else
+        unsigned int n;
 #endif
-       
-        XWindowAttributes attr;
-        Status status = XGetWindowAttributes(wxGlobalDisplay(), window, & attr);
-        wxASSERT(status);
-        
-        if (status)
-        {
-            *x = attr.x + offsetX;
-            *y = attr.y + offsetY;
-        }
+        parent_window = next_parent;
+        XQueryTree(display, parent_window, &root,
+            &next_parent, &theChildren, &n);
+        XFree(theChildren); // not needed
     }
+#if 0
+    int xx, yy; unsigned int dummy;
+    XGetGeometry(display, parent_window, &root,
+                 &xx, &yy, &dummy, &dummy, &dummy, &dummy);
+    if (x) *x = xx;
+    if (y) *y = yy;
+#else
+    XWindowAttributes attr;
+    Status status = XGetWindowAttributes((Display*) GetXDisplay(), parent_window, & attr);
+    if (status)
+    {
+        if (x) *x = attr.x;
+        if (y) *y = attr.y;
+    }
+    else
+    {
+        if (x) *x = 0;
+        if (y) *y = 0;
+    }
+#endif
 }