]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
don't try to paint hidden windows
[wxWidgets.git] / src / gtk / window.cpp
index c52acc624112c934fd7d6717f547c65dcbb21ba7..a10119d5ada06e88e0edecf73d354a3c557217d2 100644 (file)
     #include "wx/layout.h"
     #include "wx/statusbr.h"
     #include "wx/math.h"
+    #include "wx/module.h"
 #endif
 
-#include "wx/module.h"
-
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
 #endif
@@ -219,8 +218,6 @@ extern bool       g_blockEventsOnDrag;
 extern bool       g_blockEventsOnScroll;
 extern wxCursor   g_globalCursor;
 
-static GdkGC *g_eraseGC = NULL;
-
 // mouse capture state: the window which has it and if the mouse is currently
 // inside it
 static wxWindowGTK  *g_captureWindow = (wxWindowGTK*) NULL;
@@ -480,8 +477,7 @@ gtk_window_expose_callback( GtkWidget *widget,
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     // This callback gets called in drawing-idle time under
     // GTK 2.0, so we don't need to defer anything to idle
@@ -991,8 +987,7 @@ gtk_window_key_press_callback( GtkWidget *widget,
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     if (!win->m_hasVMT)
         return FALSE;
@@ -1124,10 +1119,6 @@ gtk_window_key_press_callback( GtkWidget *widget,
         }
     }
 
-
-
-
-
     // win is a control: tab can be propagated up
     if ( !ret &&
          ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
@@ -1152,13 +1143,7 @@ gtk_window_key_press_callback( GtkWidget *widget,
         ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
     }
 
-    if (ret)
-    {
-        g_signal_stop_emission_by_name (widget, "key_press_event");
-        return TRUE;
-    }
-
-    return FALSE;
+    return ret;
 }
 }
 
@@ -1244,8 +1229,7 @@ gtk_window_key_release_callback( GtkWidget *widget,
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     if (!win->m_hasVMT)
         return FALSE;
@@ -1260,11 +1244,7 @@ gtk_window_key_release_callback( GtkWidget *widget,
         return FALSE;
     }
 
-    if ( !win->GetEventHandler()->ProcessEvent( event ) )
-        return FALSE;
-
-    g_signal_stop_emission_by_name (widget, "key_release_event");
-    return TRUE;
+    return win->GTKProcessEvent(event);
 }
 }
 
@@ -1410,12 +1390,17 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y)
 // common event handlers helpers
 // ----------------------------------------------------------------------------
 
+bool wxWindowGTK::GTKProcessEvent(wxEvent& event) const
+{
+    // nothing special at this level
+    return GetEventHandler()->ProcessEvent(event);
+}
+
 int wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     if (!m_hasVMT)
         return FALSE;
@@ -1615,9 +1600,8 @@ gtk_window_button_press_callback( GtkWidget *widget,
     event.SetEventObject( win );
     event.SetId( win->GetId() );
 
-    if (win->GetEventHandler()->ProcessEvent( event ))
+    if (win->GTKProcessEvent( event ))
     {
-        g_signal_stop_emission_by_name (widget, "button_press_event");
         return TRUE;
     }
 
@@ -1635,7 +1619,7 @@ gtk_window_button_press_callback( GtkWidget *widget,
             win->GetId(),
             win->ClientToScreen(event.GetPosition()));
         evtCtx.SetEventObject(win);
-        return win->GetEventHandler()->ProcessEvent(evtCtx);
+        return win->GTKProcessEvent(evtCtx);
     }
 
     return FALSE;
@@ -1688,13 +1672,7 @@ gtk_window_button_release_callback( GtkWidget *widget,
     event.SetEventObject( win );
     event.SetId( win->GetId() );
 
-    if (win->GetEventHandler()->ProcessEvent( event ))
-    {
-        g_signal_stop_emission_by_name (widget, "button_release_event");
-        return TRUE;
-    }
-
-    return FALSE;
+    return win->GTKProcessEvent(event);
 }
 
 //-----------------------------------------------------------------------------
@@ -1739,7 +1717,7 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
                                                         : wxEVT_LEAVE_WINDOW);
             InitMouseEvent(win, eventM, gdk_event);
             eventM.SetEventObject(win);
-            win->GetEventHandler()->ProcessEvent(eventM);
+            win->GTKProcessEvent(eventM);
         }
     }
     else // no capture
@@ -1754,19 +1732,13 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
     if ( !g_captureWindow )
     {
         wxSetCursorEvent cevent( event.m_x, event.m_y );
-        if (win->GetEventHandler()->ProcessEvent( cevent ))
+        if (win->GTKProcessEvent( cevent ))
         {
-            // Rewrite cursor handling here (away from idle).
+            win->SetCursor( cevent.GetCursor() );
         }
     }
 
-    if (win->GetEventHandler()->ProcessEvent( event ))
-    {
-        g_signal_stop_emission_by_name (widget, "motion_notify_event");
-        return TRUE;
-    }
-
-    return FALSE;
+    return win->GTKProcessEvent(event);
 }
 
 //-----------------------------------------------------------------------------
@@ -1778,8 +1750,7 @@ window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     if (gdk_event->direction != GDK_SCROLL_UP &&
         gdk_event->direction != GDK_SCROLL_DOWN)
@@ -1812,7 +1783,7 @@ window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
     event.SetId( win->GetId() );
     event.SetTimestamp( gdk_event->time );
 
-    return win->GetEventHandler()->ProcessEvent(event);
+    return win->GTKProcessEvent(event);
 }
 
 //-----------------------------------------------------------------------------
@@ -1823,7 +1794,7 @@ static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
 {
     wxContextMenuEvent event(wxEVT_CONTEXT_MENU, win->GetId(), wxPoint(-1, -1));
     event.SetEventObject(win);
-    return win->GetEventHandler()->ProcessEvent(event);
+    return win->GTKProcessEvent(event);
 }
 
 //-----------------------------------------------------------------------------
@@ -1837,8 +1808,7 @@ gtk_window_focus_in_callback( GtkWidget *widget,
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     if (win->m_imData)
         gtk_im_context_focus_in(win->m_imData->context);
@@ -1895,8 +1865,7 @@ gtk_window_focus_out_callback( GtkWidget *widget,
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     if (win->m_imData)
         gtk_im_context_focus_out(win->m_imData->context);
@@ -1936,7 +1905,7 @@ gtk_window_focus_out_callback( GtkWidget *widget,
         wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
         event.SetEventObject( win );
 
-        (void)win->GetEventHandler()->ProcessEvent( event );
+        (void)win->GTKProcessEvent( event );
 
         ret = TRUE;
     }
@@ -1978,19 +1947,13 @@ gtk_window_enter_callback( GtkWidget *widget,
     if ( !g_captureWindow )
     {
         wxSetCursorEvent cevent( event.m_x, event.m_y );
-        if (win->GetEventHandler()->ProcessEvent( cevent ))
+        if (win->GTKProcessEvent( cevent ))
         {
-            // Rewrite cursor handling here (away from idle).
+            win->SetCursor( cevent.GetCursor() );
         }
     }
 
-    if (win->GetEventHandler()->ProcessEvent( event ))
-    {
-       g_signal_stop_emission_by_name (widget, "enter_notify_event");
-       return TRUE;
-    }
-
-    return FALSE;
+    return win->GTKProcessEvent(event);
 }
 
 //-----------------------------------------------------------------------------
@@ -2029,13 +1992,7 @@ gtk_window_leave_callback( GtkWidget *widget,
     event.m_x = x + pt.x;
     event.m_y = y + pt.y;
 
-    if (win->GetEventHandler()->ProcessEvent( event ))
-    {
-        g_signal_stop_emission_by_name (widget, "leave_notify_event");
-        return TRUE;
-    }
-
-    return FALSE;
+    return win->GTKProcessEvent(event);
 }
 
 //-----------------------------------------------------------------------------
@@ -2060,7 +2017,7 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
         event.SetEventObject(win);
 
         win->m_blockValueChanged[dir] = true;
-        win->GetEventHandler()->ProcessEvent(event);
+        win->GTKProcessEvent(event);
         win->m_blockValueChanged[dir] = false;
     }
 }
@@ -2074,8 +2031,7 @@ gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win)
 {
     DEBUG_MAIN_THREAD
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
+    // don't need to install idle handler, its done from "event" signal
 
     g_blockEventsOnScroll = true;
     win->m_mouseButtonDown = true;
@@ -2098,7 +2054,7 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win)
                                         win->ScrollDirFromRange(range));
         wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient);
         event.SetEventObject(win);
-        win->GetEventHandler()->ProcessEvent(event);
+        win->GTKProcessEvent(event);
     }
 }
 
@@ -2150,7 +2106,7 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
 
     wxWindowCreateEvent event( win );
     event.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent( event );
+    win->GTKProcessEvent( event );
 }
 
 //-----------------------------------------------------------------------------
@@ -2178,7 +2134,7 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
     {
         wxSizeEvent event( win->GetSize(), win->GetId() );
         event.SetEventObject( win );
-        win->GetEventHandler()->ProcessEvent( event );
+        win->GTKProcessEvent( event );
     }
 }
 
@@ -2408,7 +2364,7 @@ void wxWindowGTK::Init()
     m_hasVMT = false;
     m_needParent = true;
     m_isBeingDeleted = false;
-    
+
     m_showOnIdle= false;
 
     m_noExpose = false;
@@ -2734,6 +2690,8 @@ void wxWindowGTK::PostCreation()
     InheritAttributes();
 
     m_hasVMT = true;
+    
+    SetLayoutDirection(wxLayout_Default);
 
     // unless the window was created initially hidden (i.e. Hide() had been
     // called before Create()), we should show it at GTK+ level as well
@@ -2829,8 +2787,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
        // don't take the x,y values, they're wrong because toolbar sets them
        GtkWidget  *widget = GTK_WIDGET(m_widget);
        gtk_widget_set_size_request (widget, m_width, m_height);
-       if (GTK_WIDGET_VISIBLE (widget))
-            gtk_widget_queue_resize (widget);
     }
     else
 #endif
@@ -2927,7 +2883,7 @@ bool wxWindowGTK::GtkShowFromOnIdle()
         m_showOnIdle = false;
         return true;
     }
-    
+
     return false;
 }
 
@@ -2949,9 +2905,6 @@ void wxWindowGTK::OnInternalIdle()
         SetBackgroundStyle(GetBackgroundStyle());
         m_needsStyleChange = false;
     }
-    
-    // Update invalidated regions.
-    GtkUpdate();
 
     wxCursor cursor = m_cursor;
     if (g_globalCursor.Ok()) cursor = g_globalCursor;
@@ -3433,13 +3386,15 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase )
             m_showOnIdle = true;
             gtk_widget_hide( m_widget );
         }
-    
+
         /* insert GTK representation */
         (*(newParent->m_insertCallback))(newParent, this);
     }
 
     /* reverse: prevent GTK from deleting the widget arbitrarily */
     gtk_widget_unref( m_widget );
+    
+    SetLayoutDirection(wxLayout_Default);
 
     return true;
 }
@@ -3475,6 +3430,51 @@ void wxWindowGTK::RemoveChild(wxWindowBase *child)
         wxapp_install_idle_handler();
 }
 
+/* static */
+wxLayoutDirection wxWindowGTK::GTKGetLayout(GtkWidget *widget)
+{
+    return gtk_widget_get_direction(GTK_WIDGET(widget)) == GTK_TEXT_DIR_RTL
+                ? wxLayout_RightToLeft
+                : wxLayout_LeftToRight;
+}
+
+/* static */
+void wxWindowGTK::GTKSetLayout(GtkWidget *widget, wxLayoutDirection dir)
+{
+    wxASSERT_MSG( dir != wxLayout_Default, _T("invalid layout direction") );
+
+    gtk_widget_set_direction(GTK_WIDGET(widget),
+                             dir == wxLayout_RightToLeft ? GTK_TEXT_DIR_RTL
+                                                         : GTK_TEXT_DIR_LTR);
+}
+
+wxLayoutDirection wxWindowGTK::GetLayoutDirection() const
+{
+    return GTKGetLayout(m_widget);
+}
+
+void wxWindowGTK::SetLayoutDirection(wxLayoutDirection dir)
+{
+    if ( dir == wxLayout_Default )
+    {
+        const wxWindow *const parent = GetParent();
+        if ( parent )
+        {
+            // inherit layout from parent.
+            dir = parent->GetLayoutDirection();
+        }
+        else // no parent, use global default layout
+        {
+            dir = wxTheApp->GetLayoutDirection();
+        }
+    }
+
+    if ( dir == wxLayout_Default )
+        return;
+
+    GTKSetLayout(m_widget, dir);
+}
+
 void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move)
 {
     wxWindowBase::DoMoveInTabOrder(win, move);
@@ -3585,15 +3585,12 @@ void wxWindowGTK::Lower()
 
 bool wxWindowGTK::SetCursor( const wxCursor &cursor )
 {
-    wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") );
+    if ( !wxWindowBase::SetCursor(cursor.Ok() ? cursor : *wxSTANDARD_CURSOR) )
+        return false;
 
-    if (cursor == m_cursor)
-       return false;
+    GTKUpdateCursor();
 
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    return wxWindowBase::SetCursor( cursor.Ok() ? cursor : *wxSTANDARD_CURSOR );
+    return true;
 }
 
 void wxWindowGTK::GTKUpdateCursor()
@@ -3612,7 +3609,14 @@ void wxWindowGTK::GTKUpdateCursor()
             const size_t count = windowsThis.size();
             for ( size_t n = 0; n < count; n++ )
             {
-                gdk_window_set_cursor(windowsThis[n], cursor.GetCursor());
+                GdkWindow *win = windowsThis[n];
+                if ( !win )
+                {
+                    wxFAIL_MSG(_T("NULL window returned by GTKGetWindow()?"));
+                    continue;
+                }
+
+                gdk_window_set_cursor(win, cursor.GetCursor());
             }
         }
     }
@@ -3688,7 +3692,7 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
     if (m_wxwindow)
     {
         if (!GTK_PIZZA(m_wxwindow)->bin_window) return;
-    
+
         GdkRectangle gdk_rect,
                     *p;
         if (rect)
@@ -4361,33 +4365,3 @@ void wxRemoveGrab(wxWindow* window)
 {
     gtk_grab_remove( (GtkWidget*) window->GetHandle() );
 }
-
-// ----------------------------------------------------------------------------
-// wxWinModule
-// ----------------------------------------------------------------------------
-
-class wxWinModule : public wxModule
-{
-public:
-    bool OnInit();
-    void OnExit();
-
-private:
-    DECLARE_DYNAMIC_CLASS(wxWinModule)
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxWinModule, wxModule)
-
-bool wxWinModule::OnInit()
-{
-    // g_eraseGC = gdk_gc_new( gdk_get_default_root_window() );
-    // gdk_gc_set_fill( g_eraseGC, GDK_SOLID );
-
-    return true;
-}
-
-void wxWinModule::OnExit()
-{
-    if (g_eraseGC)
-        g_object_unref (g_eraseGC);
-}