mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 01:45:36 +00:00
app: [macOS] use cgo.Handle for referring to Go windows from native code
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+45
-56
@@ -10,6 +10,7 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/cgo"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
@@ -41,6 +42,7 @@ import (
|
|||||||
__attribute__ ((visibility ("hidden"))) void gio_main(void);
|
__attribute__ ((visibility ("hidden"))) void gio_main(void);
|
||||||
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createView(void);
|
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createView(void);
|
||||||
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef viewRef, CGFloat width, CGFloat height, CGFloat minWidth, CGFloat minHeight, CGFloat maxWidth, CGFloat maxHeight);
|
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef viewRef, CGFloat width, CGFloat height, CGFloat minWidth, CGFloat minHeight, CGFloat maxWidth, CGFloat maxHeight);
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle);
|
||||||
|
|
||||||
static void writeClipboard(CFTypeRef str) {
|
static void writeClipboard(CFTypeRef str) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
@@ -264,9 +266,6 @@ type window struct {
|
|||||||
config Config
|
config Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// viewMap is the mapping from Cocoa NSViews to Go windows.
|
|
||||||
var viewMap = make(map[C.CFTypeRef]*window)
|
|
||||||
|
|
||||||
// launched is closed when applicationDidFinishLaunching is called.
|
// launched is closed when applicationDidFinishLaunching is called.
|
||||||
var launched = make(chan struct{})
|
var launched = make(chan struct{})
|
||||||
|
|
||||||
@@ -274,18 +273,8 @@ var launched = make(chan struct{})
|
|||||||
// cascadeTopLeftFromPoint.
|
// cascadeTopLeftFromPoint.
|
||||||
var nextTopLeft C.NSPoint
|
var nextTopLeft C.NSPoint
|
||||||
|
|
||||||
// mustView is like lookupView, except that it panics
|
func windowFor(h C.uintptr_t) *window {
|
||||||
// if the view isn't mapped.
|
return cgo.Handle(h).Value().(*window)
|
||||||
func mustView(view C.CFTypeRef) *window {
|
|
||||||
w, exists := viewMap[view]
|
|
||||||
if !exists {
|
|
||||||
panic("no window for view")
|
|
||||||
}
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func insertView(view C.CFTypeRef, w *window) {
|
|
||||||
viewMap[view] = w
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) contextView() C.CFTypeRef {
|
func (w *window) contextView() C.CFTypeRef {
|
||||||
@@ -488,14 +477,14 @@ func (w *window) setStage(stage Stage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onKeys
|
//export gio_onKeys
|
||||||
func gio_onKeys(view, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger, keyDown C.bool) {
|
func gio_onKeys(h C.uintptr_t, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger, keyDown C.bool) {
|
||||||
str := nsstringToString(cstr)
|
str := nsstringToString(cstr)
|
||||||
kmods := convertMods(mods)
|
kmods := convertMods(mods)
|
||||||
ks := key.Release
|
ks := key.Release
|
||||||
if keyDown {
|
if keyDown {
|
||||||
ks = key.Press
|
ks = key.Press
|
||||||
}
|
}
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
for _, k := range str {
|
for _, k := range str {
|
||||||
if n, ok := convertKey(k); ok {
|
if n, ok := convertKey(k); ok {
|
||||||
w.ProcessEvent(key.Event{
|
w.ProcessEvent(key.Event{
|
||||||
@@ -508,15 +497,15 @@ func gio_onKeys(view, cstr C.CFTypeRef, ti C.double, mods C.NSUInteger, keyDown
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onText
|
//export gio_onText
|
||||||
func gio_onText(view, cstr C.CFTypeRef) {
|
func gio_onText(h C.uintptr_t, cstr C.CFTypeRef) {
|
||||||
str := nsstringToString(cstr)
|
str := nsstringToString(cstr)
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.w.EditorInsert(str)
|
w.w.EditorInsert(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onMouse
|
//export gio_onMouse
|
||||||
func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx, dy C.CGFloat, ti C.double, mods C.NSUInteger) {
|
func gio_onMouse(h C.uintptr_t, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx, dy C.CGFloat, ti C.double, mods C.NSUInteger) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
t := time.Duration(float64(ti)*float64(time.Second) + .5)
|
t := time.Duration(float64(ti)*float64(time.Second) + .5)
|
||||||
xf, yf := float32(x)*w.scale, float32(y)*w.scale
|
xf, yf := float32(x)*w.scale, float32(y)*w.scale
|
||||||
dxf, dyf := float32(dx)*w.scale, float32(dy)*w.scale
|
dxf, dyf := float32(dx)*w.scale, float32(dy)*w.scale
|
||||||
@@ -565,14 +554,14 @@ func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onDraw
|
//export gio_onDraw
|
||||||
func gio_onDraw(view C.CFTypeRef) {
|
func gio_onDraw(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.draw()
|
w.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onFocus
|
//export gio_onFocus
|
||||||
func gio_onFocus(view C.CFTypeRef, focus C.int) {
|
func gio_onFocus(h C.uintptr_t, focus C.int) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.ProcessEvent(key.FocusEvent{Focus: focus == 1})
|
w.ProcessEvent(key.FocusEvent{Focus: focus == 1})
|
||||||
if w.stage >= StageInactive {
|
if w.stage >= StageInactive {
|
||||||
if focus == 0 {
|
if focus == 0 {
|
||||||
@@ -585,15 +574,15 @@ func gio_onFocus(view C.CFTypeRef, focus C.int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onChangeScreen
|
//export gio_onChangeScreen
|
||||||
func gio_onChangeScreen(view C.CFTypeRef, did uint64) {
|
func gio_onChangeScreen(h C.uintptr_t, did uint64) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.displayLink.SetDisplayID(did)
|
w.displayLink.SetDisplayID(did)
|
||||||
C.setNeedsDisplay(w.view)
|
C.setNeedsDisplay(w.view)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_hasMarkedText
|
//export gio_hasMarkedText
|
||||||
func gio_hasMarkedText(view C.CFTypeRef) C.int {
|
func gio_hasMarkedText(h C.uintptr_t) C.int {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
if state.compose.Start != -1 {
|
if state.compose.Start != -1 {
|
||||||
return 1
|
return 1
|
||||||
@@ -602,8 +591,8 @@ func gio_hasMarkedText(view C.CFTypeRef) C.int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_markedRange
|
//export gio_markedRange
|
||||||
func gio_markedRange(view C.CFTypeRef) C.NSRange {
|
func gio_markedRange(h C.uintptr_t) C.NSRange {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
rng := state.compose
|
rng := state.compose
|
||||||
start, end := rng.Start, rng.End
|
start, end := rng.Start, rng.End
|
||||||
@@ -618,8 +607,8 @@ func gio_markedRange(view C.CFTypeRef) C.NSRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_selectedRange
|
//export gio_selectedRange
|
||||||
func gio_selectedRange(view C.CFTypeRef) C.NSRange {
|
func gio_selectedRange(h C.uintptr_t) C.NSRange {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
rng := state.Selection
|
rng := state.Selection
|
||||||
start, end := rng.Start, rng.End
|
start, end := rng.Start, rng.End
|
||||||
@@ -634,14 +623,14 @@ func gio_selectedRange(view C.CFTypeRef) C.NSRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_unmarkText
|
//export gio_unmarkText
|
||||||
func gio_unmarkText(view C.CFTypeRef) {
|
func gio_unmarkText(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.w.SetComposingRegion(key.Range{Start: -1, End: -1})
|
w.w.SetComposingRegion(key.Range{Start: -1, End: -1})
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_setMarkedText
|
//export gio_setMarkedText
|
||||||
func gio_setMarkedText(view, cstr C.CFTypeRef, selRange C.NSRange, replaceRange C.NSRange) {
|
func gio_setMarkedText(h C.uintptr_t, cstr C.CFTypeRef, selRange C.NSRange, replaceRange C.NSRange) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
str := nsstringToString(cstr)
|
str := nsstringToString(cstr)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
rng := state.compose
|
rng := state.compose
|
||||||
@@ -680,8 +669,8 @@ func gio_setMarkedText(view, cstr C.CFTypeRef, selRange C.NSRange, replaceRange
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_substringForProposedRange
|
//export gio_substringForProposedRange
|
||||||
func gio_substringForProposedRange(view C.CFTypeRef, crng C.NSRange, actual C.NSRangePointer) C.CFTypeRef {
|
func gio_substringForProposedRange(h C.uintptr_t, crng C.NSRange, actual C.NSRangePointer) C.CFTypeRef {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
start, end := state.Snippet.Start, state.Snippet.End
|
start, end := state.Snippet.Start, state.Snippet.End
|
||||||
if start > end {
|
if start > end {
|
||||||
@@ -701,8 +690,8 @@ func gio_substringForProposedRange(view C.CFTypeRef, crng C.NSRange, actual C.NS
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_insertText
|
//export gio_insertText
|
||||||
func gio_insertText(view, cstr C.CFTypeRef, crng C.NSRange) {
|
func gio_insertText(h C.uintptr_t, cstr C.CFTypeRef, crng C.NSRange) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
rng := state.compose
|
rng := state.compose
|
||||||
if rng.Start == -1 {
|
if rng.Start == -1 {
|
||||||
@@ -726,13 +715,13 @@ func gio_insertText(view, cstr C.CFTypeRef, crng C.NSRange) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_characterIndexForPoint
|
//export gio_characterIndexForPoint
|
||||||
func gio_characterIndexForPoint(view C.CFTypeRef, p C.NSPoint) C.NSUInteger {
|
func gio_characterIndexForPoint(h C.uintptr_t, p C.NSPoint) C.NSUInteger {
|
||||||
return C.NSNotFound
|
return C.NSNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_firstRectForCharacterRange
|
//export gio_firstRectForCharacterRange
|
||||||
func gio_firstRectForCharacterRange(view C.CFTypeRef, crng C.NSRange, actual C.NSRangePointer) C.NSRect {
|
func gio_firstRectForCharacterRange(h C.uintptr_t, crng C.NSRange, actual C.NSRangePointer) C.NSRect {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
state := w.w.EditorState()
|
state := w.w.EditorState()
|
||||||
sel := state.Selection
|
sel := state.Selection
|
||||||
u16start := state.UTF16Index(sel.Start)
|
u16start := state.UTF16Index(sel.Start)
|
||||||
@@ -813,40 +802,40 @@ func configFor(scale float32) unit.Metric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onClose
|
//export gio_onClose
|
||||||
func gio_onClose(view C.CFTypeRef) {
|
func gio_onClose(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.ProcessEvent(ViewEvent{})
|
w.ProcessEvent(ViewEvent{})
|
||||||
w.setStage(StagePaused)
|
w.setStage(StagePaused)
|
||||||
w.ProcessEvent(DestroyEvent{})
|
w.ProcessEvent(DestroyEvent{})
|
||||||
w.displayLink.Close()
|
w.displayLink.Close()
|
||||||
w.displayLink = nil
|
w.displayLink = nil
|
||||||
delete(viewMap, view)
|
cgo.Handle(h).Delete()
|
||||||
C.CFRelease(w.view)
|
C.CFRelease(w.view)
|
||||||
w.view = 0
|
w.view = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onHide
|
//export gio_onHide
|
||||||
func gio_onHide(view C.CFTypeRef) {
|
func gio_onHide(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.setStage(StagePaused)
|
w.setStage(StagePaused)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onShow
|
//export gio_onShow
|
||||||
func gio_onShow(view C.CFTypeRef) {
|
func gio_onShow(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.setStage(StageRunning)
|
w.setStage(StageRunning)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onFullscreen
|
//export gio_onFullscreen
|
||||||
func gio_onFullscreen(view C.CFTypeRef) {
|
func gio_onFullscreen(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.config.Mode = Fullscreen
|
w.config.Mode = Fullscreen
|
||||||
w.ProcessEvent(ConfigEvent{Config: w.config})
|
w.ProcessEvent(ConfigEvent{Config: w.config})
|
||||||
}
|
}
|
||||||
|
|
||||||
//export gio_onWindowed
|
//export gio_onWindowed
|
||||||
func gio_onWindowed(view C.CFTypeRef) {
|
func gio_onWindowed(h C.uintptr_t) {
|
||||||
w := mustView(view)
|
w := windowFor(h)
|
||||||
w.config.Mode = Windowed
|
w.config.Mode = Windowed
|
||||||
w.ProcessEvent(ConfigEvent{Config: w.config})
|
w.ProcessEvent(ConfigEvent{Config: w.config})
|
||||||
}
|
}
|
||||||
@@ -910,7 +899,7 @@ func (w *window) init() error {
|
|||||||
C.CFRelease(view)
|
C.CFRelease(view)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
insertView(view, w)
|
C.gio_viewSetHandle(view, C.uintptr_t(cgo.NewHandle(w)))
|
||||||
w.view = view
|
w.view = view
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-30
@@ -14,40 +14,50 @@ __attribute__ ((visibility ("hidden"))) CALayer *gio_layerFactory(void);
|
|||||||
@interface GioWindowDelegate : NSObject<NSWindowDelegate>
|
@interface GioWindowDelegate : NSObject<NSWindowDelegate>
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface GioView : NSView <CALayerDelegate,NSTextInputClient>
|
||||||
|
@property uintptr_t handle;
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation GioWindowDelegate
|
@implementation GioWindowDelegate
|
||||||
- (void)windowWillMiniaturize:(NSNotification *)notification {
|
- (void)windowWillMiniaturize:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
gio_onHide((__bridge CFTypeRef)window.contentView);
|
GioView *view = (GioView *)window.contentView;
|
||||||
|
gio_onHide(view.handle);
|
||||||
}
|
}
|
||||||
- (void)windowDidDeminiaturize:(NSNotification *)notification {
|
- (void)windowDidDeminiaturize:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
gio_onShow((__bridge CFTypeRef)window.contentView);
|
GioView *view = (GioView *)window.contentView;
|
||||||
|
gio_onShow(view.handle);
|
||||||
}
|
}
|
||||||
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
gio_onFullscreen((__bridge CFTypeRef)window.contentView);
|
GioView *view = (GioView *)window.contentView;
|
||||||
|
gio_onFullscreen(view.handle);
|
||||||
}
|
}
|
||||||
- (void)windowWillExitFullScreen:(NSNotification *)notification {
|
- (void)windowWillExitFullScreen:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
gio_onWindowed((__bridge CFTypeRef)window.contentView);
|
GioView *view = (GioView *)window.contentView;
|
||||||
|
gio_onWindowed(view.handle);
|
||||||
}
|
}
|
||||||
- (void)windowDidChangeScreen:(NSNotification *)notification {
|
- (void)windowDidChangeScreen:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
CGDirectDisplayID dispID = [[[window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
CGDirectDisplayID dispID = [[[window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
||||||
CFTypeRef view = (__bridge CFTypeRef)window.contentView;
|
GioView *view = (GioView *)window.contentView;
|
||||||
gio_onChangeScreen(view, dispID);
|
gio_onChangeScreen(view.handle, dispID);
|
||||||
}
|
}
|
||||||
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
- (void)windowDidBecomeKey:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
gio_onFocus((__bridge CFTypeRef)window.contentView, 1);
|
GioView *view = (GioView *)window.contentView;
|
||||||
|
gio_onFocus(view.handle, 1);
|
||||||
}
|
}
|
||||||
- (void)windowDidResignKey:(NSNotification *)notification {
|
- (void)windowDidResignKey:(NSNotification *)notification {
|
||||||
NSWindow *window = (NSWindow *)[notification object];
|
NSWindow *window = (NSWindow *)[notification object];
|
||||||
gio_onFocus((__bridge CFTypeRef)window.contentView, 0);
|
GioView *view = (GioView *)window.contentView;
|
||||||
|
gio_onFocus(view.handle, 0);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) {
|
static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) {
|
||||||
NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil];
|
NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil];
|
||||||
if (!event.hasPreciseScrollingDeltas) {
|
if (!event.hasPreciseScrollingDeltas) {
|
||||||
// dx and dy are in rows and columns.
|
// dx and dy are in rows and columns.
|
||||||
@@ -56,12 +66,9 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
}
|
}
|
||||||
// Origin is in the lower left corner. Convert to upper left.
|
// Origin is in the lower left corner. Convert to upper left.
|
||||||
CGFloat height = view.bounds.size.height;
|
CGFloat height = view.bounds.size.height;
|
||||||
gio_onMouse((__bridge CFTypeRef)view, (__bridge CFTypeRef)event, typ, event.buttonNumber, p.x, height - p.y, dx, dy, [event timestamp], [event modifierFlags]);
|
gio_onMouse(view.handle, (__bridge CFTypeRef)event, typ, event.buttonNumber, p.x, height - p.y, dx, dy, [event timestamp], [event modifierFlags]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface GioView : NSView <CALayerDelegate,NSTextInputClient>
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation GioView
|
@implementation GioView
|
||||||
- (void)setFrameSize:(NSSize)newSize {
|
- (void)setFrameSize:(NSSize)newSize {
|
||||||
[super setFrameSize:newSize];
|
[super setFrameSize:newSize];
|
||||||
@@ -70,11 +77,11 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
// drawRect is called when OpenGL is used, displayLayer otherwise.
|
// drawRect is called when OpenGL is used, displayLayer otherwise.
|
||||||
// Don't know why.
|
// Don't know why.
|
||||||
- (void)drawRect:(NSRect)r {
|
- (void)drawRect:(NSRect)r {
|
||||||
gio_onDraw((__bridge CFTypeRef)self);
|
gio_onDraw(self.handle);
|
||||||
}
|
}
|
||||||
- (void)displayLayer:(CALayer *)layer {
|
- (void)displayLayer:(CALayer *)layer {
|
||||||
layer.contentsScale = self.window.backingScaleFactor;
|
layer.contentsScale = self.window.backingScaleFactor;
|
||||||
gio_onDraw((__bridge CFTypeRef)self);
|
gio_onDraw(self.handle);
|
||||||
}
|
}
|
||||||
- (CALayer *)makeBackingLayer {
|
- (CALayer *)makeBackingLayer {
|
||||||
CALayer *layer = gio_layerFactory();
|
CALayer *layer = gio_layerFactory();
|
||||||
@@ -83,7 +90,7 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
}
|
}
|
||||||
- (void)viewDidMoveToWindow {
|
- (void)viewDidMoveToWindow {
|
||||||
if (self.window == nil) {
|
if (self.window == nil) {
|
||||||
gio_onClose((__bridge CFTypeRef)self);
|
gio_onClose(self.handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
- (void)mouseDown:(NSEvent *)event {
|
- (void)mouseDown:(NSEvent *)event {
|
||||||
@@ -124,14 +131,14 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
- (void)keyDown:(NSEvent *)event {
|
- (void)keyDown:(NSEvent *)event {
|
||||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||||
NSString *keys = [event charactersIgnoringModifiers];
|
NSString *keys = [event charactersIgnoringModifiers];
|
||||||
gio_onKeys((__bridge CFTypeRef)self, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], true);
|
gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], true);
|
||||||
}
|
}
|
||||||
- (void)keyUp:(NSEvent *)event {
|
- (void)keyUp:(NSEvent *)event {
|
||||||
NSString *keys = [event charactersIgnoringModifiers];
|
NSString *keys = [event charactersIgnoringModifiers];
|
||||||
gio_onKeys((__bridge CFTypeRef)self, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], false);
|
gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], false);
|
||||||
}
|
}
|
||||||
- (void)insertText:(id)string {
|
- (void)insertText:(id)string {
|
||||||
gio_onText((__bridge CFTypeRef)self, (__bridge CFTypeRef)string);
|
gio_onText(self.handle, (__bridge CFTypeRef)string);
|
||||||
}
|
}
|
||||||
- (void)doCommandBySelector:(SEL)sel {
|
- (void)doCommandBySelector:(SEL)sel {
|
||||||
// Don't pass commands up the responder chain.
|
// Don't pass commands up the responder chain.
|
||||||
@@ -139,17 +146,17 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)hasMarkedText {
|
- (BOOL)hasMarkedText {
|
||||||
int res = gio_hasMarkedText((__bridge CFTypeRef)self);
|
int res = gio_hasMarkedText(self.handle);
|
||||||
return res ? YES : NO;
|
return res ? YES : NO;
|
||||||
}
|
}
|
||||||
- (NSRange)markedRange {
|
- (NSRange)markedRange {
|
||||||
return gio_markedRange((__bridge CFTypeRef)self);
|
return gio_markedRange(self.handle);
|
||||||
}
|
}
|
||||||
- (NSRange)selectedRange {
|
- (NSRange)selectedRange {
|
||||||
return gio_selectedRange((__bridge CFTypeRef)self);
|
return gio_selectedRange(self.handle);
|
||||||
}
|
}
|
||||||
- (void)unmarkText {
|
- (void)unmarkText {
|
||||||
gio_unmarkText((__bridge CFTypeRef)self);
|
gio_unmarkText(self.handle);
|
||||||
}
|
}
|
||||||
- (void)setMarkedText:(id)string
|
- (void)setMarkedText:(id)string
|
||||||
selectedRange:(NSRange)selRange
|
selectedRange:(NSRange)selRange
|
||||||
@@ -161,14 +168,14 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
} else {
|
} else {
|
||||||
str = string;
|
str = string;
|
||||||
}
|
}
|
||||||
gio_setMarkedText((__bridge CFTypeRef)self, (__bridge CFTypeRef)str, selRange, replaceRange);
|
gio_setMarkedText(self.handle, (__bridge CFTypeRef)str, selRange, replaceRange);
|
||||||
}
|
}
|
||||||
- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText {
|
- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range
|
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range
|
||||||
actualRange:(NSRangePointer)actualRange {
|
actualRange:(NSRangePointer)actualRange {
|
||||||
NSString *str = CFBridgingRelease(gio_substringForProposedRange((__bridge CFTypeRef)self, range, actualRange));
|
NSString *str = CFBridgingRelease(gio_substringForProposedRange(self.handle, range, actualRange));
|
||||||
return [[NSAttributedString alloc] initWithString:str attributes:nil];
|
return [[NSAttributedString alloc] initWithString:str attributes:nil];
|
||||||
}
|
}
|
||||||
- (void)insertText:(id)string
|
- (void)insertText:(id)string
|
||||||
@@ -180,22 +187,22 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
|
|||||||
} else {
|
} else {
|
||||||
str = string;
|
str = string;
|
||||||
}
|
}
|
||||||
gio_insertText((__bridge CFTypeRef)self, (__bridge CFTypeRef)str, replaceRange);
|
gio_insertText(self.handle, (__bridge CFTypeRef)str, replaceRange);
|
||||||
}
|
}
|
||||||
- (NSUInteger)characterIndexForPoint:(NSPoint)p {
|
- (NSUInteger)characterIndexForPoint:(NSPoint)p {
|
||||||
return gio_characterIndexForPoint((__bridge CFTypeRef)self, p);
|
return gio_characterIndexForPoint(self.handle, p);
|
||||||
}
|
}
|
||||||
- (NSRect)firstRectForCharacterRange:(NSRange)rng
|
- (NSRect)firstRectForCharacterRange:(NSRange)rng
|
||||||
actualRange:(NSRangePointer)actual {
|
actualRange:(NSRangePointer)actual {
|
||||||
NSRect r = gio_firstRectForCharacterRange((__bridge CFTypeRef)self, rng, actual);
|
NSRect r = gio_firstRectForCharacterRange(self.handle, rng, actual);
|
||||||
r = [self convertRect:r toView:nil];
|
r = [self convertRect:r toView:nil];
|
||||||
return [[self window] convertRectToScreen:r];
|
return [[self window] convertRectToScreen:r];
|
||||||
}
|
}
|
||||||
- (void)applicationWillUnhide:(NSNotification *)notification {
|
- (void)applicationWillUnhide:(NSNotification *)notification {
|
||||||
gio_onShow((__bridge CFTypeRef)self);
|
gio_onShow(self.handle);
|
||||||
}
|
}
|
||||||
- (void)applicationDidHide:(NSNotification *)notification {
|
- (void)applicationDidHide:(NSNotification *)notification {
|
||||||
gio_onHide((__bridge CFTypeRef)self);
|
gio_onHide(self.handle);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -393,6 +400,11 @@ CFTypeRef gio_createView(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle) {
|
||||||
|
GioView *v = (__bridge GioView *)viewRef;
|
||||||
|
v.handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
@implementation GioAppDelegate
|
@implementation GioAppDelegate
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|||||||
Reference in New Issue
Block a user