gtk: fix clipboard; implement ye olde X selection
original commit: 82ab45b11d3f890d4830248feb95f38dcfe98c56
This commit is contained in:
parent
1ed409f26c
commit
f4d458d0fd
|
@ -7,6 +7,7 @@
|
||||||
"../../lock.rkt"
|
"../../lock.rkt"
|
||||||
"../common/queue.rkt"
|
"../common/queue.rkt"
|
||||||
"../common/local.rkt"
|
"../common/local.rkt"
|
||||||
|
"../common/freeze.rkt"
|
||||||
"utils.rkt"
|
"utils.rkt"
|
||||||
"types.rkt"
|
"types.rkt"
|
||||||
"pixbuf.rkt")
|
"pixbuf.rkt")
|
||||||
|
@ -16,11 +17,12 @@
|
||||||
has-x-selection?
|
has-x-selection?
|
||||||
_GtkSelectionData
|
_GtkSelectionData
|
||||||
gtk_selection_data_get_length
|
gtk_selection_data_get_length
|
||||||
gtk_selection_data_get_data))
|
gtk_selection_data_get_data
|
||||||
|
primary-atom
|
||||||
|
get-selection-eventspace))
|
||||||
|
|
||||||
(define (has-x-selection?) #t)
|
(define (has-x-selection?) #t)
|
||||||
|
|
||||||
(define _GdkAtom _int)
|
|
||||||
(define _GtkClipboard (_cpointer 'GtkClipboard))
|
(define _GtkClipboard (_cpointer 'GtkClipboard))
|
||||||
(define _GtkDisplay _pointer)
|
(define _GtkDisplay _pointer)
|
||||||
(define _GtkSelectionData (_cpointer 'GtkSelectionData))
|
(define _GtkSelectionData (_cpointer 'GtkSelectionData))
|
||||||
|
@ -81,32 +83,38 @@
|
||||||
(define clear_owner
|
(define clear_owner
|
||||||
(function-ptr clear-owner (_fun #:atomic? #t _GtkClipboard _pointer -> _void)))
|
(function-ptr clear-owner (_fun #:atomic? #t _GtkClipboard _pointer -> _void)))
|
||||||
|
|
||||||
|
(define primary-atom (gdk_atom_intern "PRIMARY" #t))
|
||||||
|
(define clipboard-atom (gdk_atom_intern "CLIPBOARD" #t))
|
||||||
|
|
||||||
|
(define the-x-selection-driver #f)
|
||||||
|
|
||||||
(defclass clipboard-driver% object%
|
(defclass clipboard-driver% object%
|
||||||
(init-field [x-selection? #f])
|
(init-field [x-selection? #f])
|
||||||
|
|
||||||
|
(when x-selection?
|
||||||
|
(set! the-x-selection-driver this))
|
||||||
|
|
||||||
(define client #f)
|
(define client #f)
|
||||||
(define client-data #f)
|
(define client-data #f)
|
||||||
|
(define client-types #f)
|
||||||
|
(define client-orig-types #f)
|
||||||
|
|
||||||
(define cb (gtk_clipboard_get
|
(define cb (gtk_clipboard_get
|
||||||
(if x-selection?
|
(if x-selection?
|
||||||
(gdk_atom_intern "CLIPBOARD" #t)
|
primary-atom
|
||||||
(gdk_atom_intern "PRIMARY" #t))))
|
clipboard-atom)))
|
||||||
(define self-box #f)
|
(define self-box #f)
|
||||||
|
|
||||||
(define/public (get-client) client)
|
(define/public (get-client) client)
|
||||||
|
|
||||||
(define/public (set-client c types)
|
(define/public (set-client c orig-types)
|
||||||
(if x-selection?
|
|
||||||
;; For now, we can't call it on demand, so we don't call at all:
|
|
||||||
(queue-event (send c get-client-eventspace)
|
|
||||||
(lambda ()
|
|
||||||
(send c on-replaced)))
|
|
||||||
;; In clipboard mode (as opposed to X selection), we can get the data
|
;; In clipboard mode (as opposed to X selection), we can get the data
|
||||||
;; now, so it's ready if anyone asks:
|
;; now, so it's ready if anyone asks:
|
||||||
(let ([all-data (for/list ([t (in-list types)])
|
(let ([all-data (if x-selection?
|
||||||
(send c get-data t))]
|
#f
|
||||||
[types (for/list ([t (in-list types)])
|
(for/list ([t (in-list orig-types)])
|
||||||
|
(send c get-data t)))]
|
||||||
|
[types (for/list ([t (in-list orig-types)])
|
||||||
(if (equal? t "TEXT")
|
(if (equal? t "TEXT")
|
||||||
"UTF8_STRING"
|
"UTF8_STRING"
|
||||||
t))])
|
t))])
|
||||||
|
@ -126,6 +134,8 @@
|
||||||
(+ offset 1))))
|
(+ offset 1))))
|
||||||
(set! client c)
|
(set! client c)
|
||||||
(set! client-data all-data)
|
(set! client-data all-data)
|
||||||
|
(set! client-types types)
|
||||||
|
(set! client-orig-types orig-types)
|
||||||
|
|
||||||
(atomically
|
(atomically
|
||||||
(let ([this-box (malloc-immobile-cell this)])
|
(let ([this-box (malloc-immobile-cell this)])
|
||||||
|
@ -137,7 +147,7 @@
|
||||||
clear_owner
|
clear_owner
|
||||||
this-box)))
|
this-box)))
|
||||||
|
|
||||||
(free target-strings)))))
|
(free target-strings))))
|
||||||
|
|
||||||
(define/public (replaced s-box)
|
(define/public (replaced s-box)
|
||||||
;; Called in Gtk event-dispatch thread --- atomically with respect
|
;; Called in Gtk event-dispatch thread --- atomically with respect
|
||||||
|
@ -148,19 +158,27 @@
|
||||||
(when c
|
(when c
|
||||||
(set! client #f)
|
(set! client #f)
|
||||||
(set! client-data #f)
|
(set! client-data #f)
|
||||||
|
(set! client-types #f)
|
||||||
|
(set! client-orig-types #f)
|
||||||
(queue-event (send c get-client-eventspace)
|
(queue-event (send c get-client-eventspace)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(send c on-replaced))))))
|
(send c on-replaced))))))
|
||||||
(free-immobile-cell s-box))
|
(free-immobile-cell s-box))
|
||||||
|
|
||||||
(define/public (provide-data i sel-data)
|
(define/public (provide-data i sel-data)
|
||||||
;; Called in Gtk event-dispatch thread --- atomically with respect
|
;; In atomic mode; if it's the selection (not clipboard),
|
||||||
;; to any other thread
|
;; then hopefully we're in the right eventspace
|
||||||
(let ([bstr (if client
|
(let ([bstr (if client
|
||||||
|
(if client-data
|
||||||
(list-ref client-data i)
|
(list-ref client-data i)
|
||||||
|
(constrained-reply (send client get-client-eventspace)
|
||||||
|
(lambda ()
|
||||||
|
(send client get-data
|
||||||
|
(list-ref client-orig-types i)))
|
||||||
|
#""))
|
||||||
#"")])
|
#"")])
|
||||||
(gtk_selection_data_set sel-data
|
(gtk_selection_data_set sel-data
|
||||||
(gdk_atom_intern "UTF8_STRING" #t)
|
(gdk_atom_intern (list-ref client-types i) #t)
|
||||||
8
|
8
|
||||||
bstr
|
bstr
|
||||||
(bytes-length bstr))))
|
(bytes-length bstr))))
|
||||||
|
@ -190,3 +208,9 @@
|
||||||
(gobject-unref pixbuf)))))
|
(gobject-unref pixbuf)))))
|
||||||
|
|
||||||
(super-new))
|
(super-new))
|
||||||
|
|
||||||
|
(define (get-selection-eventspace)
|
||||||
|
(and the-x-selection-driver
|
||||||
|
(let ([c (send the-x-selection-driver get-client)])
|
||||||
|
(and c
|
||||||
|
(send c get-client-eventspace)))))
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"../../lock.rkt"
|
"../../lock.rkt"
|
||||||
"../common/queue.rkt"
|
"../common/queue.rkt"
|
||||||
"../common/freeze.rkt"
|
"../common/freeze.rkt"
|
||||||
|
"clipboard.rkt"
|
||||||
"const.rkt"
|
"const.rkt"
|
||||||
"w32.rkt"
|
"w32.rkt"
|
||||||
"unique.rkt")
|
"unique.rkt")
|
||||||
|
@ -163,11 +164,19 @@
|
||||||
(let* ([gtk (gtk_get_event_widget evt)]
|
(let* ([gtk (gtk_get_event_widget evt)]
|
||||||
[wx (and gtk (widget-hook gtk))])
|
[wx (and gtk (widget-hook gtk))])
|
||||||
(cond
|
(cond
|
||||||
[(and (= (ptr-ref evt _int) GDK_EXPOSE)
|
[(and (= (ptr-ref evt _GdkEventType) GDK_EXPOSE)
|
||||||
wx
|
wx
|
||||||
(send wx direct-update?))
|
(send wx direct-update?))
|
||||||
(gtk_main_do_event evt)]
|
(gtk_main_do_event evt)]
|
||||||
[(and wx (send wx get-eventspace))
|
[(or
|
||||||
|
;; event for a window that we control?
|
||||||
|
(and wx (send wx get-eventspace))
|
||||||
|
;; event to get X selection data?
|
||||||
|
(and (= (ptr-ref evt _GdkEventType) GDK_SELECTION_REQUEST)
|
||||||
|
(let ([s (cast evt _pointer _GdkEventSelection-pointer)])
|
||||||
|
(= (GdkEventSelection-selection s)
|
||||||
|
primary-atom))
|
||||||
|
(get-selection-eventspace)))
|
||||||
=> (lambda (e)
|
=> (lambda (e)
|
||||||
(let ([evt (gdk_event_copy evt)])
|
(let ([evt (gdk_event_copy evt)])
|
||||||
(queue-event e (lambda ()
|
(queue-event e (lambda ()
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
_GdkScreen
|
_GdkScreen
|
||||||
_gpointer
|
_gpointer
|
||||||
_GType
|
_GType
|
||||||
|
_GdkEventType
|
||||||
|
_GdkAtom
|
||||||
|
|
||||||
_fnpointer
|
_fnpointer
|
||||||
_gboolean
|
_gboolean
|
||||||
|
@ -27,6 +29,8 @@
|
||||||
(struct-out GdkEventConfigure)
|
(struct-out GdkEventConfigure)
|
||||||
_GdkEventExpose _GdkEventExpose-pointer
|
_GdkEventExpose _GdkEventExpose-pointer
|
||||||
(struct-out GdkEventExpose)
|
(struct-out GdkEventExpose)
|
||||||
|
_GdkEventSelection _GdkEventSelection-pointer
|
||||||
|
(struct-out GdkEventSelection)
|
||||||
(struct-out GdkRectangle)
|
(struct-out GdkRectangle)
|
||||||
_GdkColor _GdkColor-pointer
|
_GdkColor _GdkColor-pointer
|
||||||
(struct-out GdkColor)))
|
(struct-out GdkColor)))
|
||||||
|
@ -50,6 +54,8 @@
|
||||||
(define _gfloat _float)
|
(define _gfloat _float)
|
||||||
(define _GdkEventType _int)
|
(define _GdkEventType _int)
|
||||||
|
|
||||||
|
(define _GdkAtom _int)
|
||||||
|
|
||||||
(define-cstruct _GdkEventButton ([type _GdkEventType]
|
(define-cstruct _GdkEventButton ([type _GdkEventType]
|
||||||
[window _GdkWindow]
|
[window _GdkWindow]
|
||||||
[send_event _byte]
|
[send_event _byte]
|
||||||
|
@ -123,6 +129,15 @@
|
||||||
[width _int]
|
[width _int]
|
||||||
[height _int]))
|
[height _int]))
|
||||||
|
|
||||||
|
(define-cstruct _GdkEventSelection ([type _GdkEventType]
|
||||||
|
[window _GdkWindow]
|
||||||
|
[send_event _byte]
|
||||||
|
[selection _GdkAtom]
|
||||||
|
[target _GdkAtom]
|
||||||
|
[property _GdkAtom]
|
||||||
|
[time _uint32]
|
||||||
|
[requestor _pointer]))
|
||||||
|
|
||||||
(define-cstruct _GdkRectangle ([x _int]
|
(define-cstruct _GdkRectangle ([x _int]
|
||||||
[y _int]
|
[y _int]
|
||||||
[width _int]
|
[width _int]
|
||||||
|
|
|
@ -49,12 +49,7 @@
|
||||||
(define outline-pen (send the-pen-list find-or-create-pen "BLACK" 0 'transparent))
|
(define outline-pen (send the-pen-list find-or-create-pen "BLACK" 0 'transparent))
|
||||||
(define outline-inactive-pen (send the-pen-list find-or-create-pen (get-highlight-background-color) 1 'solid))
|
(define outline-inactive-pen (send the-pen-list find-or-create-pen (get-highlight-background-color) 1 'solid))
|
||||||
(define outline-brush (send the-brush-list find-or-create-brush (get-highlight-background-color) 'solid))
|
(define outline-brush (send the-brush-list find-or-create-brush (get-highlight-background-color) 'solid))
|
||||||
(define xpattern #"\x88\x88\0\0\x22\x22\0\0\x88\x88\0\0\x22\x22\0\0\x88\x88\0\0\x22\x22\0\0\x88\x88\0\0\x22\x22\0\0")
|
(define outline-nonowner-brush outline-brush)
|
||||||
(define outline-nonowner-brush (let ([b (new brush%)])
|
|
||||||
(send b set-color "BLACK")
|
|
||||||
(send b set-stipple (make-object bitmap% xpattern 16 16))
|
|
||||||
(send b set-style 'xor)
|
|
||||||
b))
|
|
||||||
(define clear-brush (send the-brush-list find-or-create-brush "WHITE" 'solid))
|
(define clear-brush (send the-brush-list find-or-create-brush "WHITE" 'solid))
|
||||||
|
|
||||||
(define (showcaret>= a b)
|
(define (showcaret>= a b)
|
||||||
|
@ -5257,9 +5252,10 @@
|
||||||
hilite-some? hsxs hsxe hsys hsye
|
hilite-some? hsxs hsxe hsys hsye
|
||||||
old-style))))))))))
|
old-style))))))))))
|
||||||
(let*-values ([(draw-first?)
|
(let*-values ([(draw-first?)
|
||||||
(or (not (showcaret>= show-caret 'show-caret))
|
(or (and (or (not (showcaret>= show-caret 'show-caret))
|
||||||
(and s-caret-snip (not (pair? show-caret)))
|
(and s-caret-snip (not (pair? show-caret)))
|
||||||
(not hilite-on?)
|
(not hilite-on?))
|
||||||
|
(not show-xsel?))
|
||||||
(= -startpos -endpos)
|
(= -startpos -endpos)
|
||||||
(-endpos . < . pcounter)
|
(-endpos . < . pcounter)
|
||||||
(-startpos . > . (+ pcounter (mline-len line))))]
|
(-startpos . > . (+ pcounter (mline-len line))))]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user