]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
Made SetFont for wxCheckListBox more intelligent.
[wxWidgets.git] / src / gtk / window.cpp
index a66604c1d79e934e0cdbabb559b83b73c0311d33..93cb0f3c647acc87ddcae2cea7eff61b9d076b24 100644 (file)
 #include "gtk/gtk.h"
 #include "gdk/gdkprivate.h"
 #include "gdk/gdkkeysyms.h"
-#include "gdk/gdkx.h"
 #include "wx/gtk/win_gtk.h"
 
+#if (GTK_MINOR_VERSION == 0)
+#include "gdk/gdkx.h"
+#endif
+
 //-----------------------------------------------------------------------------
 // documentation on internals
 //-----------------------------------------------------------------------------
 extern wxList     wxPendingDelete;
 extern bool       g_blockEventsOnDrag;
 extern bool       g_blockEventsOnScroll;
+extern wxCursor   g_globalCursor;
 static bool       g_capturing = FALSE;
 static wxWindow  *g_focusWindow = (wxWindow*) NULL;
 
@@ -186,6 +190,22 @@ extern bool g_isIdle;
 // key event conversion routines
 //-----------------------------------------------------------------------------
 
+#if (GTK_MINOR_VERSION == 0)
+static guint
+gdk_keyval_to_upper (guint       keyval)
+{
+  if (keyval)
+    {
+      KeySym lower_val = 0;
+      KeySym upper_val = 0;
+      
+      XConvertCase (keyval, &lower_val, &upper_val);
+      return upper_val;
+    }
+  return 0;
+}
+#endif
+
 static long map_to_unmodified_wx_keysym( KeySym keysym )
 {
     guint key_code = 0;
@@ -196,6 +216,12 @@ static long map_to_unmodified_wx_keysym( KeySym keysym )
         case GDK_Shift_R:       key_code = WXK_SHIFT;       break;
         case GDK_Control_L:
         case GDK_Control_R:     key_code = WXK_CONTROL;     break;
+       case GDK_Meta_L:
+       case GDK_Meta_R:
+       case GDK_Alt_L:
+       case GDK_Alt_R:
+       case GDK_Super_L:
+       case GDK_Super_R:       key_code = WXK_ALT;         break;
         case GDK_Menu:          key_code = WXK_MENU;        break;
         case GDK_Help:          key_code = WXK_HELP;        break;
         case GDK_BackSpace:     key_code = WXK_BACK;        break;
@@ -249,7 +275,7 @@ static long map_to_unmodified_wx_keysym( KeySym keysym )
         case GDK_KP_Down:      key_code = WXK_NUMPAD_DOWN;  break;
         case GDK_KP_Prior:     key_code = WXK_NUMPAD_PRIOR; break;
 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break;
-        case GDK_KP_Next:      key_code = WXK_NUMPAD_PRIOR; break;
+        case GDK_KP_Next:      key_code = WXK_NUMPAD_NEXT;  break;
 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
         case GDK_KP_End:       key_code = WXK_NUMPAD_END;   break;
         case GDK_KP_Begin:     key_code = WXK_NUMPAD_BEGIN; break;
@@ -295,10 +321,6 @@ static long map_to_wx_keysym( KeySym keysym )
 
     switch (keysym)
     {
-        case GDK_Shift_L:
-        case GDK_Shift_R:       key_code = WXK_SHIFT;       break;
-        case GDK_Control_L:
-        case GDK_Control_R:     key_code = WXK_CONTROL;     break;
         case GDK_Menu:          key_code = WXK_MENU;        break;
         case GDK_Help:          key_code = WXK_HELP;        break;
         case GDK_BackSpace:     key_code = WXK_BACK;        break;
@@ -352,7 +374,7 @@ static long map_to_wx_keysym( KeySym keysym )
         case GDK_KP_Down:      key_code = WXK_DOWN;  break;
         case GDK_KP_Prior:     key_code = WXK_PRIOR; break;
 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break;
-        case GDK_KP_Next:      key_code = WXK_PRIOR;  break;
+        case GDK_KP_Next:      key_code = WXK_NEXT;  break;
 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
         case GDK_KP_End:       key_code = WXK_END;    break;
         case GDK_KP_Begin:     key_code = WXK_HOME;   break;
@@ -390,14 +412,6 @@ static long map_to_wx_keysym( KeySym keysym )
     return (key_code);
 }
 
-static long get_unmodified_wx_keysym( GdkEventKey *event )
-{
-    KeyCode keycode = XKeysymToKeycode( GDK_DISPLAY(), event->keyval );
-    KeySym keysym = XKeycodeToKeysym( GDK_DISPLAY(), keycode, 0 );
-
-    return (map_to_unmodified_wx_keysym( keysym ));
-}
-
 //-----------------------------------------------------------------------------
 // local code (see below)
 //-----------------------------------------------------------------------------
@@ -433,7 +447,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
         if (scroll_window->hscrollbar_visible)
         {
             dh += 15;   /* dh += hscrollbar->allocation.height; */
-            dw += scroll_class->scrollbar_spacing;
+            dh += scroll_class->scrollbar_spacing;
         }
     }
 
@@ -566,15 +580,17 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
       printf( "ControlUp.\n" );
     printf( "\n" );
 */
-
-    bool ret = FALSE;
-    
     int x = 0;
     int y = 0;
     GdkModifierType state;
     if (gdk_event->window) gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
 
-    long key_code = get_unmodified_wx_keysym( gdk_event );
+    long key_code = map_to_unmodified_wx_keysym( gdk_event->keyval );
+    
+    /* sending unknown key events doesn't really make sense */
+    if (key_code == 0) return FALSE;
+
+    bool ret = FALSE;
     
     wxKeyEvent event( wxEVT_KEY_DOWN );         
     event.SetTimestamp( gdk_event->time );
@@ -592,7 +608,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
     key_code = map_to_wx_keysym( gdk_event->keyval );
 
     /* wxMSW doesn't send char events with Alt pressed */
-    if (((gdk_event->state & GDK_MOD1_MASK) == 0) &&
+    if ((key_code != 0) &&
+        ((gdk_event->state & GDK_MOD1_MASK) == 0) &&
         ((gdk_event->state & GDK_MOD1_MASK) == 0))
     {
         wxKeyEvent event2( wxEVT_CHAR );                 
@@ -625,7 +642,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
         }
     }
 
-    // win is a control: tab can be propagated up
+    /* win is a control: tab can be propagated up */
     if ( (!ret) &&
          ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
          (win->HasFlag(wxTE_PROCESS_TAB) == 0))
@@ -639,6 +656,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
         ret = win->GetEventHandler()->ProcessEvent( new_event );
     }
 
+    /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
     if ( (!ret) &&
          (gdk_event->keyval == GDK_Escape) )
     {
@@ -646,6 +664,36 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
         new_event.SetEventObject( win );
         ret = win->GetEventHandler()->ProcessEvent( new_event );
     }
+    
+#if (GTK_MINOR_VERSION > 0)
+    /* pressing F10 will activate the menu bar of the top frame */
+    if ( (!ret) &&
+         (gdk_event->keyval == GDK_F10) )
+    {
+        wxWindow *ancestor = win;
+        while (ancestor)
+        {
+            if (wxIsKindOf(ancestor,wxFrame))
+           {
+               wxFrame *frame = (wxFrame*) ancestor;
+                wxMenuBar *menubar = frame->GetMenuBar();
+               if (menubar)
+               {
+                    wxNode *node = menubar->GetMenus().First();
+                   if (node)
+                   {
+                        wxMenu *firstMenu = (wxMenu*) node->Data();
+                       // doesn't work correctly
+                       // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
+                       // ret = TRUE;
+                       break;
+                   }
+               }
+           }
+            ancestor = ancestor->GetParent();
+        }
+    }
+#endif
 
 /*
     Damn, I forgot why this didn't work, but it didn't work.
@@ -704,7 +752,10 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk
     printf( "\n" );
 */
 
-    long key_code = get_unmodified_wx_keysym( gdk_event );
+    long key_code = map_to_unmodified_wx_keysym( gdk_event->keyval );
+    
+    /* sending unknown key events doesn't really make sense */
+    if (key_code == 0) return FALSE;
 
     int x = 0;
     int y = 0;
@@ -1206,11 +1257,10 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_
 
     if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
 
-    if (widget->window && win->GetCursor().Ok() )
-        gdk_window_set_cursor( widget->window, win->GetCursor().GetCursor() );
-
     wxMouseEvent event( wxEVT_ENTER_WINDOW );
+#if (GTK_MINOR_VERSION > 0)
     event.SetTimestamp( gdk_event->time );
+#endif
     event.SetEventObject( win );
 
     int x = 0;
@@ -1253,11 +1303,10 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_
 
     if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
     
-    if (widget->window && win->GetCursor().Ok() )
-        gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
-
     wxMouseEvent event( wxEVT_LEAVE_WINDOW );
+#if (GTK_MINOR_VERSION > 0)
     event.SetTimestamp( gdk_event->time );
+#endif
     event.SetEventObject( win );
 
     int x = 0;
@@ -1493,6 +1542,10 @@ gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
         win->SetForegroundColour( win->GetForegroundColour() );
 
     win->SetCursor( win->GetCursor() );
+    
+    wxWindowCreateEvent event( win );
+    event.SetEventObject( win );
+    win->GetEventHandler()->ProcessEvent( event );
 
     return FALSE;
 }
@@ -1933,11 +1986,13 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
         if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
 
         int border = 0;
+       int bottom_border = 0;
 
-        if (GTK_WIDGET_HAS_DEFAULT(m_widget))
+        if (GTK_WIDGET_CAN_DEFAULT(m_widget))
        {
            /* the default button has a border around it */
-           border = 5;
+           border = 6;
+           bottom_border = 5;
        }
 
        /* this is the result of hours of debugging: the following code
@@ -1966,7 +2021,7 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
                              m_x-border, 
                              m_y-border,
                              m_width+2*border, 
-                             m_height+2*border );
+                             m_height+border+bottom_border );
     }
 
     m_sizeSet = TRUE;
@@ -1980,6 +2035,19 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
 
 void wxWindow::OnInternalIdle()
 {
+    GdkWindow *window = GetConnectWidget()->window;
+    if (window)
+    {
+        wxCursor cursor = m_cursor;
+        if (g_globalCursor.Ok()) cursor = g_globalCursor;
+       
+       if (m_currentGdkCursor != cursor)
+       {
+           gdk_window_set_cursor( window, cursor.GetCursor() );
+           m_currentGdkCursor = cursor;
+       }
+    }
+
     UpdateWindowUI();
 }
 
@@ -2046,7 +2114,7 @@ void wxWindow::DoSetClientSize( int width, int height )
             if (scroll_window->hscrollbar_visible)
             {
                 dh += 15;   /* dh += hscrollbar->allocation.height; */
-                dw += scroll_class->scrollbar_spacing;
+                dh += scroll_class->scrollbar_spacing;
             }
        }
 
@@ -2126,7 +2194,7 @@ void wxWindow::DoGetPosition( int *x, int *y ) const
     if (y) (*y) = m_y;
 }
 
-void wxWindow::ClientToScreen( int *x, int *y ) const
+void wxWindow::DoClientToScreen( int *x, int *y ) const
 {
     wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
 
@@ -2155,7 +2223,7 @@ void wxWindow::ClientToScreen( int *x, int *y ) const
     if (y) *y += org_y;
 }
 
-void wxWindow::ScreenToClient( int *x, int *y ) const
+void wxWindow::DoScreenToClient( int *x, int *y ) const
 {
     wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
 
@@ -2339,11 +2407,7 @@ bool wxWindow::SetCursor( const wxCursor &cursor )
         return TRUE;
     }
 
-        if ((m_widget) && (m_widget->window))
-             gdk_window_set_cursor( m_widget->window, GetCursor().GetCursor() );
-
-        if ((m_wxwindow) && (m_wxwindow->window))
-             gdk_window_set_cursor( m_wxwindow->window, GetCursor().GetCursor() );
+//    gdk_window_set_cursor( connect_widget->window, GetCursor().GetCursor() );
 
     // cursor was set
     return TRUE;
@@ -2863,6 +2927,14 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
         m_scrollGC = gdk_gc_new( m_wxwindow->window );
         gdk_gc_set_exposures( m_scrollGC, TRUE );
     }
+    
+    wxNode *node = m_children.First();
+    while (node)
+    {
+        wxWindow *child = (wxWindow*) node->Data();
+       child->Move( child->m_x + dx, child->m_y + dy );
+       node = node->Next();
+    }
 
     int cw = 0;
     int ch = 0;
@@ -2896,14 +2968,6 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
 
         Refresh( TRUE, &rect );
     }
-    
-    wxNode *node = m_children.First();
-    while (node)
-    {
-        wxWindow *child = (wxWindow*) node->Data();
-       child->Move( child->m_x + dx, child->m_y + dy );
-       node = node->Next();
-    }
 }
 
 void wxWindow::SetScrolling(bool scroll)