Added tracking areas to Area on Mac OS X so mouse move events can work; they work now.
This commit is contained in:
parent
5819e52f8d
commit
cc01981999
|
@ -12,6 +12,7 @@ import (
|
||||||
//// #include <HIToolbox/Events.h>
|
//// #include <HIToolbox/Events.h>
|
||||||
// #include "objc_darwin.h"
|
// #include "objc_darwin.h"
|
||||||
// extern BOOL areaView_isFlipped_acceptsFirstResponder(id, SEL);
|
// extern BOOL areaView_isFlipped_acceptsFirstResponder(id, SEL);
|
||||||
|
// extern void areaView_updateTrackingAreas(id, SEL);
|
||||||
// extern void areaView_mouseMoved_mouseDragged(id, SEL, id);
|
// extern void areaView_mouseMoved_mouseDragged(id, SEL, id);
|
||||||
// extern void areaView_mouseDown(id, SEL, id);
|
// extern void areaView_mouseDown(id, SEL, id);
|
||||||
// extern void areaView_mouseUp(id, SEL, id);
|
// extern void areaView_mouseUp(id, SEL, id);
|
||||||
|
@ -36,6 +37,8 @@ var goAreaSels = []selector{
|
||||||
"ensuring that an Area's coordinate system has (0,0) at the top-left corner"},
|
"ensuring that an Area's coordinate system has (0,0) at the top-left corner"},
|
||||||
selector{"acceptsFirstResponder", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool,
|
selector{"acceptsFirstResponder", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool,
|
||||||
"registering that Areas are to receive events"},
|
"registering that Areas are to receive events"},
|
||||||
|
selector{"updateTrackingAreas", uintptr(C.areaView_updateTrackingAreas), sel_void,
|
||||||
|
"updating tracking areas for handling mouse movements in Area"},
|
||||||
selector{"mouseMoved:", uintptr(C.areaView_mouseMoved_mouseDragged), sel_void_id,
|
selector{"mouseMoved:", uintptr(C.areaView_mouseMoved_mouseDragged), sel_void_id,
|
||||||
"handling mouse movements in Area"},
|
"handling mouse movements in Area"},
|
||||||
selector{"mouseDown:", uintptr(C.areaView_mouseDown), sel_void_id,
|
selector{"mouseDown:", uintptr(C.areaView_mouseDown), sel_void_id,
|
||||||
|
@ -78,6 +81,7 @@ func makeArea(parentWindow C.id, alternate bool, s *sysData) C.id {
|
||||||
area := C.objc_msgSend_noargs(_goArea, _alloc)
|
area := C.objc_msgSend_noargs(_goArea, _alloc)
|
||||||
area = initWithDummyFrame(area)
|
area = initWithDummyFrame(area)
|
||||||
// TODO others?
|
// TODO others?
|
||||||
|
retrack(area, s)
|
||||||
area = newScrollView(area)
|
area = newScrollView(area)
|
||||||
addControl(parentWindow, area)
|
addControl(parentWindow, area)
|
||||||
return area
|
return area
|
||||||
|
@ -117,6 +121,24 @@ func areaView_isFlipped_acceptsFirstResponder(self C.id, sel C.SEL) C.BOOL {
|
||||||
return C.BOOL(C.YES)
|
return C.BOOL(C.YES)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_addTrackingArea = sel_getUid("addTrackingArea:")
|
||||||
|
_removeTrackingArea = sel_getUid("removeTrackingArea:")
|
||||||
|
)
|
||||||
|
|
||||||
|
func retrack(area C.id, s *sysData) {
|
||||||
|
s.trackingArea = C.makeTrackingArea(area)
|
||||||
|
C.objc_msgSend_id(area, _addTrackingArea, s.trackingArea)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export areaView_updateTrackingAreas
|
||||||
|
func areaView_updateTrackingAreas(self C.id, sel C.SEL) {
|
||||||
|
s := getSysData(self)
|
||||||
|
C.objc_msgSend_id(self, _removeTrackingArea, s.trackingArea)
|
||||||
|
C.objc_msgSend_noargs(s.trackingArea, _release)
|
||||||
|
retrack(self, s)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_NSEvent = objc_getClass("NSEvent")
|
_NSEvent = objc_getClass("NSEvent")
|
||||||
|
|
||||||
|
@ -175,6 +197,7 @@ func areaMouseEvent(self C.id, e C.id, click bool, up bool) {
|
||||||
which = 0 // reset for Held processing below
|
which = 0 // reset for Held processing below
|
||||||
}
|
}
|
||||||
// pressedMouseButtons is a class method; calling objc_msgSend() directly with e as an argument on these will panic (in real Objective-C the compiler can detect [e pressedMouseButtons])
|
// pressedMouseButtons is a class method; calling objc_msgSend() directly with e as an argument on these will panic (in real Objective-C the compiler can detect [e pressedMouseButtons])
|
||||||
|
// the docs do say don't use this for tracking since it returns the state now, and mouse move events work by tracking, but as far as I can tell dragging the mouse over the inactive window does n ot generate an event on Mac OS X, so :/ (TODO see what happens when the program is the current one; in my own separate tests no harm was done so eh; also no need for this if tracking doesn't touch dragging)
|
||||||
held := C.objc_msgSend_uintret_noargs(_NSEvent, _pressedMouseButtons)
|
held := C.objc_msgSend_uintret_noargs(_NSEvent, _pressedMouseButtons)
|
||||||
if which != 1 && (held & 1) != 0 { // button 1
|
if which != 1 && (held & 1) != 0 { // button 1
|
||||||
me.Held = append(me.Held, 1)
|
me.Held = append(me.Held, 1)
|
||||||
|
@ -200,8 +223,8 @@ func areaMouseEvent(self C.id, e C.id, click bool, up bool) {
|
||||||
|
|
||||||
//export areaView_mouseMoved_mouseDragged
|
//export areaView_mouseMoved_mouseDragged
|
||||||
func areaView_mouseMoved_mouseDragged(self C.id, sel C.SEL, e C.id) {
|
func areaView_mouseMoved_mouseDragged(self C.id, sel C.SEL, e C.id) {
|
||||||
|
// for moving, this is handled by the tracking rect stuff above
|
||||||
// for dragging, if multiple buttons are held, only one of their xxxMouseDragged: messages will be sent, so this is OK to do
|
// for dragging, if multiple buttons are held, only one of their xxxMouseDragged: messages will be sent, so this is OK to do
|
||||||
// TODO implement tracking for dragging
|
|
||||||
areaMouseEvent(self, e, false, false)
|
areaMouseEvent(self, e, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ though this is not always the case.
|
||||||
#include <AppKit/NSBitmapImageRep.h>
|
#include <AppKit/NSBitmapImageRep.h>
|
||||||
#include <AppKit/NSCell.h>
|
#include <AppKit/NSCell.h>
|
||||||
#include <AppKit/NSApplication.h>
|
#include <AppKit/NSApplication.h>
|
||||||
|
#include <AppKit/NSTrackingArea.h>
|
||||||
|
|
||||||
/* used by listbox_darwin.go; requires NSString */
|
/* used by listbox_darwin.go; requires NSString */
|
||||||
id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey);
|
id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey);
|
||||||
|
@ -43,6 +44,9 @@ static id c_NSFont;
|
||||||
static SEL s_setFont; /* objc_setFont() */
|
static SEL s_setFont; /* objc_setFont() */
|
||||||
static SEL s_systemFontOfSize;
|
static SEL s_systemFontOfSize;
|
||||||
static SEL s_systemFontSizeForControlSize;
|
static SEL s_systemFontSizeForControlSize;
|
||||||
|
static id c_NSTrackingArea;
|
||||||
|
static SEL s_bounds;
|
||||||
|
static SEL s_initTrackingArea;
|
||||||
|
|
||||||
void initBleh()
|
void initBleh()
|
||||||
{
|
{
|
||||||
|
@ -60,6 +64,9 @@ void initBleh()
|
||||||
s_setFont = sel_getUid("setFont:");
|
s_setFont = sel_getUid("setFont:");
|
||||||
s_systemFontOfSize = sel_getUid("systemFontOfSize:");
|
s_systemFontOfSize = sel_getUid("systemFontOfSize:");
|
||||||
s_systemFontSizeForControlSize = sel_getUid("systemFontSizeForControlSize:");
|
s_systemFontSizeForControlSize = sel_getUid("systemFontSizeForControlSize:");
|
||||||
|
c_NSTrackingArea = objc_getClass("NSTrackingArea");
|
||||||
|
s_bounds = sel_getUid("bounds");
|
||||||
|
s_initTrackingArea = sel_getUid("initWithRect:options:owner:userInfo:");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -350,3 +357,25 @@ static NSApplicationTerminateReply __appDelegate_applicationShouldTerminate(id s
|
||||||
void *_appDelegate_applicationShouldTerminate = (void *) __appDelegate_applicationShouldTerminate;
|
void *_appDelegate_applicationShouldTerminate = (void *) __appDelegate_applicationShouldTerminate;
|
||||||
|
|
||||||
char *encodedTerminateReply = @encode(NSApplicationTerminateReply);
|
char *encodedTerminateReply = @encode(NSApplicationTerminateReply);
|
||||||
|
|
||||||
|
/*
|
||||||
|
tracking areas; also here for convenience only
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* IDK if this is needed; just to be safe */
|
||||||
|
static id (*objc_msgSend_initTrackingArea)(id, SEL, NSRect, NSTrackingAreaOptions, id, id) =
|
||||||
|
(id (*)(id, SEL, NSRect, NSTrackingAreaOptions, id, id)) objc_msgSend;
|
||||||
|
|
||||||
|
id makeTrackingArea(id area)
|
||||||
|
{
|
||||||
|
id trackingArea;
|
||||||
|
|
||||||
|
trackingArea = objc_msgSend(c_NSTrackingArea, s_alloc);
|
||||||
|
trackingArea = (*objc_msgSend_initTrackingArea)(trackingArea, s_initTrackingArea,
|
||||||
|
(*objc_msgSend_stret_rect)(area, s_bounds), /* initWithRect: */
|
||||||
|
/* this bit mask (except for NSTrackingInVisibleRect, which was added later) comes from https://github.com/andlabs/misctestprogs/blob/master/cocoaviewmousetest.m (and I wrote this bit mask on 25 april 2014) and yes I know it includes enter/exit even though we don't watch those events; it probably won't really matter anyway but if it does I can change it easily */
|
||||||
|
(NSTrackingAreaOptions) (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways | NSTrackingEnabledDuringMouseDrag | NSTrackingInVisibleRect), /* options: */
|
||||||
|
area, /* owner: */
|
||||||
|
nil); /* userData: */
|
||||||
|
return trackingArea;
|
||||||
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ const (
|
||||||
sel_bool
|
sel_bool
|
||||||
sel_void_rect
|
sel_void_rect
|
||||||
sel_terminatereply_id
|
sel_terminatereply_id
|
||||||
|
sel_void
|
||||||
nitypes
|
nitypes
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -107,6 +108,7 @@ var itypes = [nitypes][]C.char{
|
||||||
sel_bool: []C.char{'c', '@', ':', 0},
|
sel_bool: []C.char{'c', '@', ':', 0},
|
||||||
sel_void_rect: nil, // see init() below
|
sel_void_rect: nil, // see init() below
|
||||||
sel_terminatereply_id: nil,
|
sel_terminatereply_id: nil,
|
||||||
|
sel_void: []C.char{'v', '@', ':', 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -112,8 +112,10 @@ extern void initBleh();
|
||||||
extern id makeDummyEvent();
|
extern id makeDummyEvent();
|
||||||
|
|
||||||
/* for area_darwin.go */
|
/* for area_darwin.go */
|
||||||
|
/* TODO apparently ISO C forbids casting a function pointer to a non-function pointer; this will need to change???? */
|
||||||
extern void *_areaView_drawRect;
|
extern void *_areaView_drawRect;
|
||||||
extern void drawImage(void *, int64_t, int64_t, int64_t, int64_t, int64_t);
|
extern void drawImage(void *, int64_t, int64_t, int64_t, int64_t, int64_t);
|
||||||
|
extern id makeTrackingArea(id);
|
||||||
extern struct xpoint getTranslatedEventPoint(id, id);
|
extern struct xpoint getTranslatedEventPoint(id, id);
|
||||||
|
|
||||||
/* for objc_darwin.go */
|
/* for objc_darwin.go */
|
||||||
|
|
|
@ -50,7 +50,6 @@ var (
|
||||||
_initWithContentRect = sel_getUid("initWithContentRect:styleMask:backing:defer:")
|
_initWithContentRect = sel_getUid("initWithContentRect:styleMask:backing:defer:")
|
||||||
_initWithFrame = sel_getUid("initWithFrame:")
|
_initWithFrame = sel_getUid("initWithFrame:")
|
||||||
_setDelegate = sel_getUid("setDelegate:")
|
_setDelegate = sel_getUid("setDelegate:")
|
||||||
_setAcceptsMouseMovedEvents = sel_getUid("setAcceptsMouseMovedEvents:")
|
|
||||||
_makeKeyAndOrderFront = sel_getUid("makeKeyAndOrderFront:")
|
_makeKeyAndOrderFront = sel_getUid("makeKeyAndOrderFront:")
|
||||||
_orderOut = sel_getUid("orderOut:")
|
_orderOut = sel_getUid("orderOut:")
|
||||||
_setHidden = sel_getUid("setHidden:")
|
_setHidden = sel_getUid("setHidden:")
|
||||||
|
@ -147,8 +146,7 @@ var classTypes = [nctypes]*classData{
|
||||||
C.uintptr_t(_NSBackingStoreBuffered),
|
C.uintptr_t(_NSBackingStoreBuffered),
|
||||||
C.BOOL(C.YES)) // defer creation of device until we show the window
|
C.BOOL(C.YES)) // defer creation of device until we show the window
|
||||||
C.objc_msgSend_id(win, _setDelegate, appDelegate)
|
C.objc_msgSend_id(win, _setDelegate, appDelegate)
|
||||||
// this is needed for Areas in the window to receive mouse move events
|
// we do not need setAcceptsMouseMovedEvents: here since we are using a tracking rect in Areas for that
|
||||||
// C.objc_msgSend_bool(win, _setAcceptsMouseMovedEvents, C.BOOL(C.YES))
|
|
||||||
return win
|
return win
|
||||||
},
|
},
|
||||||
show: func(what C.id) {
|
show: func(what C.id) {
|
||||||
|
|
Loading…
Reference in New Issue