gtk: enable input-method (e.g., Chinese) support
original commit: d8e123753c40fadc6d51513cf1fa5e4eca614bc8
This commit is contained in:
parent
d9bea8bf42
commit
d6e4425fbb
|
@ -108,6 +108,52 @@
|
||||||
(define-gdk gdk_gc_set_rgb_fg_color (_fun _pointer _GdkColor-pointer -> _void))
|
(define-gdk gdk_gc_set_rgb_fg_color (_fun _pointer _GdkColor-pointer -> _void))
|
||||||
(define-gdk gdk_draw_rectangle (_fun _GdkWindow _pointer _gboolean _int _int _int _int -> _void))
|
(define-gdk gdk_draw_rectangle (_fun _GdkWindow _pointer _gboolean _int _int _int _int -> _void))
|
||||||
|
|
||||||
|
(define _GtkIMContext (_cpointer 'GtkIMContext))
|
||||||
|
(define-gtk gtk_im_multicontext_new (_fun -> _GtkIMContext))
|
||||||
|
(define-gtk gtk_im_context_set_use_preedit (_fun _GtkIMContext _gboolean -> _void))
|
||||||
|
(define-gtk gtk_im_context_focus_in (_fun _GtkIMContext -> _void))
|
||||||
|
(define-gtk gtk_im_context_focus_out (_fun _GtkIMContext -> _void))
|
||||||
|
(define-gtk gtk_im_context_filter_keypress (_fun _GtkIMContext _GdkEventKey-pointer -> _gboolean))
|
||||||
|
(define-gtk gtk_im_context_set_client_window (_fun _GtkIMContext _GdkWindow -> _void))
|
||||||
|
(define-gtk gtk_im_context_set_cursor_location (_fun _GtkIMContext _GdkRectangle-pointer -> _void))
|
||||||
|
|
||||||
|
(define im-string-result #f)
|
||||||
|
(define im-filtering? #f)
|
||||||
|
(define im-canvas #f)
|
||||||
|
|
||||||
|
(define-signal-handler connect-commit "commit"
|
||||||
|
(_fun _GtkIMContext _string -> _void)
|
||||||
|
(lambda (im str)
|
||||||
|
(cond
|
||||||
|
[im-filtering?
|
||||||
|
;; filtering an event => we can handle the string
|
||||||
|
;; result directly
|
||||||
|
(set! im-string-result str)]
|
||||||
|
[(and im-canvas
|
||||||
|
(weak-box-value im-canvas))
|
||||||
|
;; not filtering, but there's a target canvas =>
|
||||||
|
;; queue a made-up key press event for each character
|
||||||
|
;; of the string
|
||||||
|
=> (lambda (wx)
|
||||||
|
(for ([c (in-string str)])
|
||||||
|
(let ([e (new key-event%
|
||||||
|
[key-code c]
|
||||||
|
[shift-down #f]
|
||||||
|
[control-down #f]
|
||||||
|
[meta-down #f]
|
||||||
|
[alt-down #f]
|
||||||
|
[x 0]
|
||||||
|
[y 0]
|
||||||
|
[time-stamp 0]
|
||||||
|
[caps-down #f])])
|
||||||
|
(queue-window-event wx (lambda ()
|
||||||
|
(send wx dispatch-on-char e #f))))))])))
|
||||||
|
|
||||||
|
(define im (gtk_im_multicontext_new))
|
||||||
|
(void (connect-commit (cast im _pointer _GtkWidget)))
|
||||||
|
|
||||||
|
(gtk_im_context_set_use_preedit im #f)
|
||||||
|
|
||||||
;; We rely some on the implementation of GtkComboBoxEntry to replace
|
;; We rely some on the implementation of GtkComboBoxEntry to replace
|
||||||
;; the drawing routine.
|
;; the drawing routine.
|
||||||
(define-cstruct _GList ([data _pointer]))
|
(define-cstruct _GList ([data _pointer]))
|
||||||
|
@ -595,6 +641,40 @@
|
||||||
|
|
||||||
(define/public (set-combo-text t) (void))
|
(define/public (set-combo-text t) (void))
|
||||||
|
|
||||||
|
(define/override (focus-change on?)
|
||||||
|
;; input-method management
|
||||||
|
(if on?
|
||||||
|
(begin
|
||||||
|
(set! im-canvas (make-weak-box this))
|
||||||
|
(gtk_im_context_focus_in im)
|
||||||
|
(gtk_im_context_set_client_window im (widget-window client-gtk))
|
||||||
|
(let ([w (box 0)]
|
||||||
|
[h (box 0)])
|
||||||
|
(get-client-size w h)
|
||||||
|
(gtk_im_context_set_cursor_location
|
||||||
|
im
|
||||||
|
(make-GdkRectangle 0 0 (unbox w) (unbox h)))))
|
||||||
|
(when (and im-canvas
|
||||||
|
(eq? this (weak-box-value im-canvas)))
|
||||||
|
(gtk_im_context_focus_out im)
|
||||||
|
(set! im-canvas #f))))
|
||||||
|
|
||||||
|
(define/override (filter-key-event e)
|
||||||
|
;; give the input method a chance to handle the
|
||||||
|
;; key event; see call in "window.rkt" for
|
||||||
|
;; information on the results
|
||||||
|
(if (and im-canvas
|
||||||
|
(eq? this (weak-box-value im-canvas)))
|
||||||
|
(begin
|
||||||
|
(set! im-filtering? #t)
|
||||||
|
(set! im-string-result #f)
|
||||||
|
(if (begin0
|
||||||
|
(gtk_im_context_filter_keypress im e)
|
||||||
|
(set! im-filtering? #f))
|
||||||
|
im-string-result
|
||||||
|
'none))
|
||||||
|
'none))
|
||||||
|
|
||||||
(define/public (do-scroll direction)
|
(define/public (do-scroll direction)
|
||||||
(if (is-auto-scroll?)
|
(if (is-auto-scroll?)
|
||||||
(refresh-for-autoscroll)
|
(refresh-for-autoscroll)
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
(struct-out GdkEventExpose)
|
(struct-out GdkEventExpose)
|
||||||
_GdkEventSelection _GdkEventSelection-pointer
|
_GdkEventSelection _GdkEventSelection-pointer
|
||||||
(struct-out GdkEventSelection)
|
(struct-out GdkEventSelection)
|
||||||
|
_GdkRectangle _GdkRectangle-pointer
|
||||||
(struct-out GdkRectangle)
|
(struct-out GdkRectangle)
|
||||||
_GdkColor _GdkColor-pointer
|
_GdkColor _GdkColor-pointer
|
||||||
(struct-out GdkColor)))
|
(struct-out GdkColor)))
|
||||||
|
|
|
@ -130,6 +130,7 @@
|
||||||
(lambda (gtk event)
|
(lambda (gtk event)
|
||||||
(let ([wx (gtk->wx gtk)])
|
(let ([wx (gtk->wx gtk)])
|
||||||
(when wx
|
(when wx
|
||||||
|
(send wx focus-change #t)
|
||||||
(send (send wx get-top-win) on-focus-child #t)
|
(send (send wx get-top-win) on-focus-child #t)
|
||||||
(queue-window-event wx (lambda () (send wx on-set-focus))))
|
(queue-window-event wx (lambda () (send wx on-set-focus))))
|
||||||
#f)))
|
#f)))
|
||||||
|
@ -138,6 +139,7 @@
|
||||||
(lambda (gtk event)
|
(lambda (gtk event)
|
||||||
(let ([wx (gtk->wx gtk)])
|
(let ([wx (gtk->wx gtk)])
|
||||||
(when wx
|
(when wx
|
||||||
|
(send wx focus-change #f)
|
||||||
(send (send wx get-top-win) on-focus-child #f)
|
(send (send wx get-top-win) on-focus-child #f)
|
||||||
(queue-window-event wx (lambda () (send wx on-kill-focus))))
|
(queue-window-event wx (lambda () (send wx on-kill-focus))))
|
||||||
#f)))
|
#f)))
|
||||||
|
@ -180,6 +182,14 @@
|
||||||
(let ([wx (gtk->wx gtk)])
|
(let ([wx (gtk->wx gtk)])
|
||||||
(and
|
(and
|
||||||
wx
|
wx
|
||||||
|
(let ([im-str (if scroll?
|
||||||
|
'none
|
||||||
|
;; Result from `filter-key-event' is one of
|
||||||
|
;; - #f => drop the event
|
||||||
|
;; - 'none => no replacement; handle as usual
|
||||||
|
;; - a string => use as the keycode
|
||||||
|
(send wx filter-key-event event))])
|
||||||
|
(when im-str
|
||||||
(let* ([modifiers (if scroll?
|
(let* ([modifiers (if scroll?
|
||||||
(GdkEventScroll-state event)
|
(GdkEventScroll-state event)
|
||||||
(GdkEventKey-state event))]
|
(GdkEventKey-state event))]
|
||||||
|
@ -195,7 +205,10 @@
|
||||||
'wheel-down)
|
'wheel-down)
|
||||||
(keyval->code (GdkEventKey-keyval event)))]
|
(keyval->code (GdkEventKey-keyval event)))]
|
||||||
[k (new key-event%
|
[k (new key-event%
|
||||||
[key-code key-code]
|
[key-code (if (and (string? im-str)
|
||||||
|
(= 1 (string-length im-str)))
|
||||||
|
(string-ref im-str 0)
|
||||||
|
key-code)]
|
||||||
[shift-down (bit? modifiers GDK_SHIFT_MASK)]
|
[shift-down (bit? modifiers GDK_SHIFT_MASK)]
|
||||||
[control-down (bit? modifiers GDK_CONTROL_MASK)]
|
[control-down (bit? modifiers GDK_CONTROL_MASK)]
|
||||||
[meta-down (bit? modifiers GDK_MOD1_MASK)]
|
[meta-down (bit? modifiers GDK_MOD1_MASK)]
|
||||||
|
@ -233,7 +246,7 @@
|
||||||
#t)
|
#t)
|
||||||
(constrained-reply (send wx get-eventspace)
|
(constrained-reply (send wx get-eventspace)
|
||||||
(lambda () (send wx dispatch-on-char k #t))
|
(lambda () (send wx dispatch-on-char k #t))
|
||||||
#t)))))))
|
#t)))))))))
|
||||||
|
|
||||||
(define-signal-handler connect-button-press "button-press-event"
|
(define-signal-handler connect-button-press "button-press-event"
|
||||||
(_fun _GtkWidget _GdkEventButton-pointer -> _gboolean)
|
(_fun _GtkWidget _GdkEventButton-pointer -> _gboolean)
|
||||||
|
@ -562,6 +575,9 @@
|
||||||
(define/public (on-set-focus) (void))
|
(define/public (on-set-focus) (void))
|
||||||
(define/public (on-kill-focus) (void))
|
(define/public (on-kill-focus) (void))
|
||||||
|
|
||||||
|
(define/public (focus-change on?) (void))
|
||||||
|
(define/public (filter-key-event e) 'none)
|
||||||
|
|
||||||
(define/private (pre-event-refresh)
|
(define/private (pre-event-refresh)
|
||||||
;; Since we break the connection between the
|
;; Since we break the connection between the
|
||||||
;; Gtk queue and event handling, we
|
;; Gtk queue and event handling, we
|
||||||
|
|
Loading…
Reference in New Issue
Block a user