]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
No changes, just move time functions from wx/stopwatch.h to wx/time.h.
[wxWidgets.git] / src / gtk / window.cpp
index 2c416d0e80cc43ae8ff656e02403db1d99b076dc..c244d2c91cda7461517c2c79a500d884e06751fa 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "wx/gtk/private.h"
 #include "wx/gtk/private/win_gtk.h"
+#include "wx/gtk/private/event.h"
+using namespace wxGTKImpl;
 
 #include <gdk/gdkx.h>
 
 #include <gdk/gdkkeysyms-compat.h>
 #endif
 
-#if !GTK_CHECK_VERSION(2,10,0)
-    // GTK+ can reliably detect Meta key state only since 2.10 when
-    // GDK_META_MASK was introduced -- there wasn't any way to detect it
-    // in older versions. wxGTK used GDK_MOD2_MASK for this purpose, but
-    // GDK_MOD2_MASK is documented as:
-    //
-    //     the fifth modifier key (it depends on the modifier mapping of the X
-    //     server which key is interpreted as this modifier)
-    //
-    // In other words, it isn't guaranteed to map to Meta. This is a real
-    // problem: it is common to map NumLock to it (in fact, it's an exception
-    // if the X server _doesn't_ use it for NumLock).  So the old code caused
-    // wxKeyEvent::MetaDown() to always return true as long as NumLock was on
-    // on many systems, which broke all applications using
-    // wxKeyEvent::GetModifiers() to check modifiers state (see e.g.  here:
-    // http://tinyurl.com/56lsk2).
-    //
-    // Because of this, it's better to not detect Meta key state at all than
-    // to detect it incorrectly. Hence the following #define, which causes
-    // m_metaDown to be always set to false.
-    #define GDK_META_MASK 0
-#endif
-
 //-----------------------------------------------------------------------------
 // documentation on internals
 //-----------------------------------------------------------------------------
@@ -337,7 +316,7 @@ expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
 
 extern "C" {
 static void
-parent_set(GtkWidget* widget, GtkObject* old_parent, wxWindow* win)
+parent_set(GtkWidget* widget, GtkWidget* old_parent, wxWindow* win)
 {
     if (old_parent)
     {
@@ -1101,43 +1080,6 @@ gtk_window_key_release_callback( GtkWidget * WXUNUSED(widget),
 // mouse event processing helpers
 // ----------------------------------------------------------------------------
 
-// init wxMouseEvent with the info from GdkEventXXX struct
-template<typename T> void InitMouseEvent(wxWindowGTK *win,
-                                         wxMouseEvent& event,
-                                         T *gdk_event)
-{
-    event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0;
-    event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0;
-    event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0;
-    event.m_metaDown = (gdk_event->state & GDK_META_MASK) != 0;
-    event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK) != 0;
-    event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK) != 0;
-    event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK) != 0;
-
-    // In gdk/win32 VK_XBUTTON1 is translated to GDK_BUTTON4_MASK
-    // and VK_XBUTTON2 to GDK_BUTTON5_MASK. In x11/gdk buttons 4/5
-    // are wheel rotation and buttons 8/9 don't change the state.
-    event.m_aux1Down = (gdk_event->state & GDK_BUTTON4_MASK) != 0;
-    event.m_aux2Down = (gdk_event->state & GDK_BUTTON5_MASK) != 0;
-
-    wxPoint pt = win->GetClientAreaOrigin();
-    event.m_x = (wxCoord)gdk_event->x - pt.x;
-    event.m_y = (wxCoord)gdk_event->y - pt.y;
-
-    if ((win->m_wxwindow) && (win->GetLayoutDirection() == wxLayout_RightToLeft))
-    {
-        // origin in the upper right corner
-        GtkAllocation a;
-        gtk_widget_get_allocation(win->m_wxwindow, &a);
-        int window_width = a.width;
-        event.m_x = window_width - event.m_x;
-    }
-
-    event.SetEventObject( win );
-    event.SetId( win->GetId() );
-    event.SetTimestamp( gdk_event->time );
-}
-
 static void AdjustEventButtonState(wxMouseEvent& event)
 {
     // GDK reports the old state of the button for a button press event, but
@@ -1918,33 +1860,14 @@ gtk_window_realized_callback(GtkWidget* WXUNUSED(widget), wxWindow* win)
     win->GTKHandleRealized();
 }
 
-void wxWindowGTK::GTKHandleRealized()
-{
-    if (m_imData)
-    {
-        gtk_im_context_set_client_window
-        (
-            m_imData->context,
-            m_wxwindow ? GTKGetDrawingWindow()
-                       : gtk_widget_get_window(m_widget)
-        );
-    }
-
-    // We cannot set colours and fonts before the widget
-    // been realized, so we do this directly after realization
-    // or otherwise in idle time
-
-    if (m_needsStyleChange)
-    {
-        SetBackgroundStyle(GetBackgroundStyle());
-        m_needsStyleChange = false;
-    }
-
-    wxWindowCreateEvent event( this );
-    event.SetEventObject( this );
-    GTKProcessEvent( event );
+//-----------------------------------------------------------------------------
+// "unrealize" from m_wxwindow
+//-----------------------------------------------------------------------------
 
-    GTKUpdateCursor(true, false);
+static void unrealize(GtkWidget*, wxWindowGTK* win)
+{
+    if (win->m_imData)
+        gtk_im_context_set_client_window(win->m_imData->context, NULL);
 }
 
 //-----------------------------------------------------------------------------
@@ -2025,6 +1948,35 @@ void gtk_window_style_set_callback( GtkWidget *WXUNUSED(widget),
 
 } // extern "C"
 
+void wxWindowGTK::GTKHandleRealized()
+{
+    if (m_imData)
+    {
+        gtk_im_context_set_client_window
+        (
+            m_imData->context,
+            m_wxwindow ? GTKGetDrawingWindow()
+                       : gtk_widget_get_window(m_widget)
+        );
+    }
+
+    // We cannot set colours and fonts before the widget
+    // been realized, so we do this directly after realization
+    // or otherwise in idle time
+
+    if (m_needsStyleChange)
+    {
+        SetBackgroundStyle(GetBackgroundStyle());
+        m_needsStyleChange = false;
+    }
+
+    wxWindowCreateEvent event( this );
+    event.SetEventObject( this );
+    GTKProcessEvent( event );
+
+    GTKUpdateCursor(true, false);
+}
+
 // ----------------------------------------------------------------------------
 // this wxWindowBase function is implemented here (in platform-specific file)
 // because it is static and so couldn't be made virtual
@@ -2305,6 +2257,7 @@ wxWindowGTK::~wxWindowGTK()
 
     // delete before the widgets to avoid a crash on solaris
     delete m_imData;
+    m_imData = NULL;
 
     // avoid problem with GTK+ 2.18 where a frozen window causes the whole
     // TLW to be frozen, and if the window is then destroyed, nothing ever
@@ -2368,6 +2321,7 @@ void wxWindowGTK::PostCreation()
 
         g_signal_connect (m_imData->context, "commit",
                           G_CALLBACK (gtk_wxwindow_commit_cb), this);
+        g_signal_connect(m_wxwindow, "unrealize", G_CALLBACK(unrealize), this);
     }
 
     // focus handling
@@ -2467,7 +2421,8 @@ void wxWindowGTK::PostCreation()
         gtk_widget_show( m_widget );
 }
 
-unsigned long wxWindowGTK::GTKConnectWidget(const char *signal, void (*callback)())
+unsigned long
+wxWindowGTK::GTKConnectWidget(const char *signal, wxGTKCallback callback)
 {
     return g_signal_connect(m_widget, signal, callback, this);
 }
@@ -2545,12 +2500,15 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
     wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") );
 
-    int currentX, currentY;
-    GetPosition(&currentX, &currentY);
-    if (x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
-        x = currentX;
-    if (y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
-        y = currentY;
+    if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0 && (x == -1 || y == -1))
+    {
+        int currentX, currentY;
+        GetPosition(&currentX, &currentY);
+        if (x == -1)
+            x = currentX;
+        if (y == -1)
+            y = currentY;
+    }
     AdjustForParentClientOrigin(x, y, sizeFlags);
 
     // calculate the best size if we should auto size the window
@@ -3612,44 +3570,29 @@ bool wxWindowGTK::ScrollPages(int pages)
 void wxWindowGTK::Refresh(bool WXUNUSED(eraseBackground),
                           const wxRect *rect)
 {
-    if ( !m_widget )
-    {
-        // it is valid to call Refresh() for a window which hasn't been created
-        // yet, it simply doesn't do anything in this case
+    if (m_widget == NULL || !gtk_widget_get_mapped(m_widget))
         return;
-    }
 
-    if (!m_wxwindow)
-    {
-        if (rect)
-            gtk_widget_queue_draw_area( m_widget, rect->x, rect->y, rect->width, rect->height );
-        else
-            gtk_widget_queue_draw( m_widget );
-    }
-    else
+    if (m_wxwindow)
     {
-        // Just return if the widget or one of its ancestors isn't mapped
-        GtkWidget *w;
-        for (w = m_wxwindow; w != NULL; w = gtk_widget_get_parent(w))
-            if (!gtk_widget_get_mapped (w))
-                return;
-
-        GdkWindow* window = GTKGetDrawingWindow();
+        GdkWindow* window = gtk_widget_get_window(m_wxwindow);
         if (rect)
         {
-            int x = rect->x;
+            GdkRectangle r = { rect->x, rect->y, rect->width, rect->height };
             if (GetLayoutDirection() == wxLayout_RightToLeft)
-                x = GetClientSize().x - x - rect->width;
-            GdkRectangle r;
-            r.x = rect->x;
-            r.y = rect->y;
-            r.width = rect->width;
-            r.height = rect->height;
+                r.x = gdk_window_get_width(window) - r.x - rect->width;
             gdk_window_invalidate_rect(window, &r, true);
         }
         else
             gdk_window_invalidate_rect(window, NULL, true);
     }
+    else
+    {
+        if (rect)
+            gtk_widget_queue_draw_area(m_widget, rect->x, rect->y, rect->width, rect->height);
+        else
+            gtk_widget_queue_draw(m_widget);
+    }
 }
 
 void wxWindowGTK::Update()