]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
use AllocExclusive() instead of duplicating its code in wxFont-specific Unshare(...
[wxWidgets.git] / src / gtk / window.cpp
index 2161ae8607c0bb33320b86e29968e8c7d36c840a..35aa3f62426d9ac0da5298d00912439fb458f774 100644 (file)
@@ -210,6 +210,11 @@ wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL;
 // yet, defer setting the focus to idle time.
 wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL;
 
+// global variables because GTK+ DnD want to have the
+// mouse event that caused it
+GdkEvent    *g_lastMouseEvent = (GdkEvent*) NULL;
+int          g_lastButtonNumber = 0;
+
 extern bool g_mainThreadLocked;
 
 //-----------------------------------------------------------------------------
@@ -326,13 +331,13 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
 
     int x = dx;
     int y = dy;
-    
+
     int dw = 0;
     int dh = 0;
     if (win->m_hasScrolling)
     {
         GetScrollbarWidth(widget, dw, dh);
-        
+
         if (win->GetLayoutDirection() == wxLayout_RightToLeft)
         {
             // This is actually wrong for old GTK+ version
@@ -438,10 +443,16 @@ void wxgtk_combo_size_request_callback(GtkWidget *widget,
     GtkRequisition entry_req;
     entry_req.width = 2;
     entry_req.height = 2;
+    (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->entry) )->size_request )
+        (gcombo->entry, &entry_req );
+
+    GtkRequisition button_req;
+    button_req.width = 2;
+    button_req.height = 2;
     (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request )
-        (gcombo->button, &entry_req );
+        (gcombo->button, &button_req );
 
-    requisition->width = w - entry_req.width;
+    requisition->width = w - button_req.width;
     requisition->height = entry_req.height;
 }
 }
@@ -465,7 +476,12 @@ gtk_window_expose_callback( GtkWidget *widget,
     // time anymore.
 
     GtkPizza *pizza = GTK_PIZZA( widget );
-    if (gdk_event->window != pizza->bin_window) return FALSE;
+    if (gdk_event->window != pizza->bin_window)
+    {
+        // block expose events on GTK_WIDGET(pizza)->window,
+        //   all drawing is done on pizza->bin_window
+        return true;
+    }
 
 
 #if 0
@@ -1261,7 +1277,7 @@ template<typename T> void InitMouseEvent(wxWindowGTK *win,
     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
@@ -1451,6 +1467,8 @@ gtk_window_button_press_callback( GtkWidget *widget,
 {
     wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
 
+    g_lastButtonNumber = gdk_event->button;
+
     if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
     {
         gtk_widget_grab_focus( win->m_wxwindow );
@@ -1459,7 +1477,7 @@ gtk_window_button_press_callback( GtkWidget *widget,
     // GDK sends surplus button down events
     // before a double click event. We
     // need to filter these out.
-    if (gdk_event->type == GDK_BUTTON_PRESS)
+    if ((gdk_event->type == GDK_BUTTON_PRESS) && (win->m_wxwindow))
     {
         GdkEvent *peek_event = gdk_event_peek();
         if (peek_event)
@@ -1567,6 +1585,8 @@ gtk_window_button_press_callback( GtkWidget *widget,
         return FALSE;
     }
 
+    g_lastMouseEvent = (GdkEvent*) gdk_event;
+
     wxMouseEvent event( event_type );
     InitMouseEvent( win, event, gdk_event );
 
@@ -1586,10 +1606,10 @@ gtk_window_button_press_callback( GtkWidget *widget,
     event.SetEventObject( win );
     event.SetId( win->GetId() );
 
-    if (win->GTKProcessEvent( event ))
-    {
+    bool ret = win->GTKProcessEvent( event );
+    g_lastMouseEvent = NULL;
+    if ( ret )
         return TRUE;
-    }
 
     if (event_type == wxEVT_RIGHT_DOWN)
     {
@@ -1622,6 +1642,8 @@ gtk_window_button_release_callback( GtkWidget *widget,
 {
     wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
 
+    g_lastButtonNumber = 0;
+
     wxEventType event_type = wxEVT_NULL;
 
     switch (gdk_event->button)
@@ -1643,6 +1665,8 @@ gtk_window_button_release_callback( GtkWidget *widget,
             return FALSE;
     }
 
+    g_lastMouseEvent = (GdkEvent*) gdk_event;
+
     wxMouseEvent event( event_type );
     InitMouseEvent( win, event, gdk_event );
 
@@ -1658,7 +1682,11 @@ gtk_window_button_release_callback( GtkWidget *widget,
     event.SetEventObject( win );
     event.SetId( win->GetId() );
 
-    return win->GTKProcessEvent(event);
+    bool ret = win->GTKProcessEvent(event);
+    
+    g_lastMouseEvent = NULL;
+    
+    return ret;
 }
 
 //-----------------------------------------------------------------------------
@@ -1682,6 +1710,8 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
         gdk_event->y = y;
     }
 
+    g_lastMouseEvent = (GdkEvent*) gdk_event;
+
     wxMouseEvent event( wxEVT_MOTION );
     InitMouseEvent(win, event, gdk_event);
 
@@ -1724,7 +1754,11 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
         }
     }
 
-    return win->GTKProcessEvent(event);
+    bool ret = win->GTKProcessEvent(event);
+
+    g_lastMouseEvent = NULL;
+
+    return ret;
 }
 
 //-----------------------------------------------------------------------------
@@ -2113,7 +2147,7 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
                 alloc->width,
                 alloc->height );
 #endif
-                
+
     win->m_oldClientWidth = client_width;
     win->m_oldClientHeight = client_height;
 
@@ -2308,7 +2342,17 @@ bool wxWindowGTK::Create( wxWindow *parent,
     GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) );
     scroll_class->scrollbar_spacing = 0;
 
-    gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+    if (HasFlag(wxALWAYS_SHOW_SB))
+    {
+        gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS );
+
+        scrolledWindow->hscrollbar_visible = TRUE;
+        scrolledWindow->vscrollbar_visible = TRUE;
+    }
+    else
+    {
+        gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+    }
 
     m_scrollBar[ScrollDir_Horz] = GTK_RANGE(scrolledWindow->hscrollbar);
     m_scrollBar[ScrollDir_Vert] = GTK_RANGE(scrolledWindow->vscrollbar);
@@ -2570,7 +2614,7 @@ void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height)
 {
     // inform the parent to perform the move
     gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height );
-    
+
 }
 
 void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
@@ -2909,10 +2953,10 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const
     {
         if (GetLayoutDirection() == wxLayout_RightToLeft)
             *x = (GetClientSize().x - *x) + org_x;
-        else 
+        else
             *x += org_x;
     }
-    
+
     if (y) *y += org_y;
 }
 
@@ -2945,7 +2989,7 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
     {
         if (GetLayoutDirection() == wxLayout_RightToLeft)
             *x = (GetClientSize().x - *x) - org_x;
-        else 
+        else
             *x -= org_x;
     }
     if (y) *y -= org_y;
@@ -3170,7 +3214,7 @@ void wxWindowGTK::SetFocus()
                 gtk_widget_grab_focus (m_widget);
                 return;
             }
-        
+
             gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD );
         }
         else
@@ -3329,7 +3373,7 @@ void wxWindowGTK::SetLayoutDirection(wxLayoutDirection dir)
         return;
 
     GTKSetLayout(m_widget, dir);
-    
+
     if (m_wxwindow)
         GTKSetLayout(m_wxwindow, dir);
 }
@@ -3578,7 +3622,7 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
         {
             p = NULL;
         }
-        
+
         gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE );
     }
 }
@@ -3643,11 +3687,11 @@ void wxWindowGTK::GtkSendPaintEvents()
     {
         // Transform m_updateRegion under RTL
         m_updateRegion.Clear();
-        
+
         gint width;
         gdk_window_get_geometry( GTK_PIZZA(m_wxwindow)->bin_window,
                                  NULL, NULL, &width, NULL, NULL );
-        
+
         wxRegionIterator upd( m_nativeUpdateRegion );
         while (upd)
         {
@@ -3656,14 +3700,14 @@ void wxWindowGTK::GtkSendPaintEvents()
             rect.y = upd.GetY();
             rect.width = upd.GetWidth();
             rect.height = upd.GetHeight();
-            
+
             rect.x = width - rect.x - rect.width;
             m_updateRegion.Union( rect );
-            
+
             ++upd;
         }
     }
-    
+
     // widget to draw on
     GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
 
@@ -3752,8 +3796,15 @@ void wxWindowGTK::DoSetToolTip( wxToolTip *tip )
 
 void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 {
-    wxString tmp( tip );
-    gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL );
+    if (tip)
+    {
+        wxString tmp( tip );
+        gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL );
+    }
+    else
+    {
+        gtk_tooltips_set_tip( tips, GetConnectWidget(), NULL, NULL);
+    }
 }
 #endif // wxUSE_TOOLTIPS
 
@@ -4100,7 +4151,7 @@ void wxWindowGTK::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
         if (pos < 0)
             pos = 0;
         m_scrollPos[dir] = adj->value = pos;
-        
+
         // If a "value_changed" signal emission is not already in progress
         if (!m_blockValueChanged[dir])
         {
@@ -4153,9 +4204,9 @@ wxEventType wxWindowGTK::GetScrollEventType(GtkRange* range)
 
     const int barIndex = range == m_scrollBar[1];
     GtkAdjustment* adj = range->adjustment;
-    
+
     const int value = int(adj->value + 0.5);
-    
+
     // save previous position
     const double oldPos = m_scrollPos[barIndex];
     // update current position
@@ -4207,6 +4258,28 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
         gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
 
     m_clipPaintRegion = false;
+
+#if wxUSE_CARET
+    bool restoreCaret = (GetCaret() != NULL && GetCaret()->IsVisible());
+    if (restoreCaret)
+    {
+        wxRect caretRect(GetCaret()->GetPosition(), GetCaret()->GetSize());
+        if (dx > 0)
+            caretRect.width += dx;
+        else
+        {
+            caretRect.x += dx; caretRect.width -= dx;
+        }
+        if (dy > 0)
+            caretRect.height += dy;
+        else
+        {
+            caretRect.y += dy; caretRect.height -= dy;
+        }
+
+        RefreshRect(caretRect);
+    }
+#endif // wxUSE_CARET
 }
 
 void wxWindowGTK::GtkScrolledWindowSetBorder(GtkWidget* w, int wxstyle)