 
 :: on-key-press ( sender event user-data -- result )
     sender window :> world
-    event GdkEventKey memory>struct :> ev
-    ev key-event>gesture <key-down> :> gesture
-    gesture world propagate-key-gesture
-    ev keyval>> gdk_keyval_to_unicode 1string dup
-    gesture valid-input?
-    [ world user-input ] [ drop ] if
+    world handle>> im-context>> :> im-context
+    im-context event gtk_im_context_filter_keypress
+    [
+        event GdkEventKey memory>struct :> ev
+        ev key-event>gesture <key-down> :> gesture
+        gesture world propagate-key-gesture
+        ev keyval>> gdk_keyval_to_unicode 1string dup
+        gesture valid-input?
+        [ world user-input ] [ drop ] if
+    ] unless
     t ;
 
-: on-key-release ( sender event user-data -- result )
-    drop swap [
-        GdkEventKey memory>struct
+:: on-key-release ( sender event user-data -- result )
+    sender window :> world
+    world handle>> im-context>> event gtk_im_context_filter_keypress
+    [
+        event GdkEventKey memory>struct
         key-event>gesture <key-up>
-    ] dip window propagate-key-gesture t ;
+        world propagate-key-gesture
+    ] unless t ;
 
 : on-focus-in ( sender event user-data -- result )
-    2drop window focus-world t ;
+    2drop window [ focus-world ]
+    [ handle>> im-context>> gtk_im_context_focus_in ] bi
+    f ;
 
 : on-focus-out ( sender event user-data -- result )
-    2drop window unfocus-world t ;
+    2drop window [ unfocus-world ]
+    [ handle>> im-context>> gtk_im_context_focus_out ] bi
+    f ;
 
 : on-expose ( sender event user-data -- result )
     2drop window relayout t ;

    world setup-gl drop
    
    win connect-signals
    
    win gtk_widget_realize
    win world window-controls>> configure-window-controls
    
    win gtk_widget_show_all ;

M: gtk-ui-backend (close-window) ( handle -- )
    window>> [ unregister-window ] [ gtk_widget_destroy ] bi
    event-loop? [ gtk_main_quit ] unless ;

M: gtk-ui-backend set-title

ui.event-loop ui.gadgets ui.gadgets.private ui.gadgets.worlds
ui.gestures ui.pixel-formats ui.pixel-formats.private ui.private
glib.ffi gobject.ffi gtk.ffi gdk.ffi gdk.gl.ffi gtk.gl.ffi ;
RENAME: windows ui.private => ui:windows
IN: ui.backend.gtk

SINGLETON: gtk-ui-backend

TUPLE: handle ;
TUPLE: window-handle < handle window fullscreen? im-context ;

: <window-handle> ( window -- window-handle )
    [ window-handle new ] dip >>window ;
