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 "objc_darwin.h"
|
||||
// extern BOOL areaView_isFlipped_acceptsFirstResponder(id, SEL);
|
||||
// extern void areaView_updateTrackingAreas(id, SEL);
|
||||
// extern void areaView_mouseMoved_mouseDragged(id, SEL, id);
|
||||
// extern void areaView_mouseDown(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"},
|
||||
selector{"acceptsFirstResponder", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool,
|
||||
"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,
|
||||
"handling mouse movements in Area"},
|
||||
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 = initWithDummyFrame(area)
|
||||
// TODO others?
|
||||
retrack(area, s)
|
||||
area = newScrollView(area)
|
||||
addControl(parentWindow, area)
|
||||
return area
|
||||
|
@ -117,6 +121,24 @@ func areaView_isFlipped_acceptsFirstResponder(self C.id, sel C.SEL) C.BOOL {
|
|||
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 (
|
||||
_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
|
||||
}
|
||||
// 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)
|
||||
if which != 1 && (held & 1) != 0 { // button 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
|
||||
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
|
||||
// TODO implement tracking for dragging
|
||||
areaMouseEvent(self, e, false, false)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ though this is not always the case.
|
|||
#include <AppKit/NSBitmapImageRep.h>
|
||||
#include <AppKit/NSCell.h>
|
||||
#include <AppKit/NSApplication.h>
|
||||
#include <AppKit/NSTrackingArea.h>
|
||||
|
||||
/* used by listbox_darwin.go; requires NSString */
|
||||
id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey);
|
||||
|
@ -43,6 +44,9 @@ static id c_NSFont;
|
|||
static SEL s_setFont; /* objc_setFont() */
|
||||
static SEL s_systemFontOfSize;
|
||||
static SEL s_systemFontSizeForControlSize;
|
||||
static id c_NSTrackingArea;
|
||||
static SEL s_bounds;
|
||||
static SEL s_initTrackingArea;
|
||||
|
||||
void initBleh()
|
||||
{
|
||||
|
@ -60,6 +64,9 @@ void initBleh()
|
|||
s_setFont = sel_getUid("setFont:");
|
||||
s_systemFontOfSize = sel_getUid("systemFontOfSize:");
|
||||
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;
|
||||
|
||||
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_void_rect
|
||||
sel_terminatereply_id
|
||||
sel_void
|
||||
nitypes
|
||||
)
|
||||
|
||||
|
@ -107,6 +108,7 @@ var itypes = [nitypes][]C.char{
|
|||
sel_bool: []C.char{'c', '@', ':', 0},
|
||||
sel_void_rect: nil, // see init() below
|
||||
sel_terminatereply_id: nil,
|
||||
sel_void: []C.char{'v', '@', ':', 0},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -112,8 +112,10 @@ extern void initBleh();
|
|||
extern id makeDummyEvent();
|
||||
|
||||
/* 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 drawImage(void *, int64_t, int64_t, int64_t, int64_t, int64_t);
|
||||
extern id makeTrackingArea(id);
|
||||
extern struct xpoint getTranslatedEventPoint(id, id);
|
||||
|
||||
/* for objc_darwin.go */
|
||||
|
|
|
@ -50,7 +50,6 @@ var (
|
|||
_initWithContentRect = sel_getUid("initWithContentRect:styleMask:backing:defer:")
|
||||
_initWithFrame = sel_getUid("initWithFrame:")
|
||||
_setDelegate = sel_getUid("setDelegate:")
|
||||
_setAcceptsMouseMovedEvents = sel_getUid("setAcceptsMouseMovedEvents:")
|
||||
_makeKeyAndOrderFront = sel_getUid("makeKeyAndOrderFront:")
|
||||
_orderOut = sel_getUid("orderOut:")
|
||||
_setHidden = sel_getUid("setHidden:")
|
||||
|
@ -147,8 +146,7 @@ var classTypes = [nctypes]*classData{
|
|||
C.uintptr_t(_NSBackingStoreBuffered),
|
||||
C.BOOL(C.YES)) // defer creation of device until we show the window
|
||||
C.objc_msgSend_id(win, _setDelegate, appDelegate)
|
||||
// this is needed for Areas in the window to receive mouse move events
|
||||
// C.objc_msgSend_bool(win, _setAcceptsMouseMovedEvents, C.BOOL(C.YES))
|
||||
// we do not need setAcceptsMouseMovedEvents: here since we are using a tracking rect in Areas for that
|
||||
return win
|
||||
},
|
||||
show: func(what C.id) {
|
||||
|
|
Loading…
Reference in New Issue