             gtk_main
         ] with-destructors
     ] ui-running ;
+
+: im-context>window ( im-context -- world )
+    ui:windows get-global
+    [ second handle>> im-context>> = ] with find nip second ;
+
+:: on-commit ( im-context string' user-data -- )
+    im-context im-context>window :> world
+    string' utf8 alien>string :> string
+    f string f <key-down> :> gesture
+    gesture world propagate-key-gesture
+    string world user-input ;
 
 : connect-signal ( object signal-name callback -- )
     [ utf8 string>alien ] dip f f 0 g_signal_connect_data drop ;

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 ;
IN: ui.backend.gtk

SINGLETON: gtk-ui-backend

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

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


:: on-key-press ( sender event user-data -- result )
    sender window :> world
    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 )
    sender window :> world
    world handle>> im-context>> event gtk_im_context_filter_keypress
    [
        event GdkEventKey memory>struct
        key-event>gesture <key-up>
        world propagate-key-gesture
    ] unless t ;

: on-focus-in ( sender event user-data -- result )
    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 ]
    [ handle>> im-context>> gtk_im_context_focus_out ] bi
    f ;

: on-expose ( sender event user-data -- result )
    2drop window relayout t ;
