forked from enlightenment/efl
ecore_cocoa: NSRunLoop integration
Summary: Get rid of the old NSApplicationLoad() which was aimed to be use with Carbon. Unless the NSRunLoop is strictly integrated to the ecore_main_loop() (where cocoa events would be checked when entering the ecore_main_loop) I think the poller is the only option left. Reviewers: raster, naguirre, raoulh, stefan_schmidt, cedric @feature Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D1222 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
parent
8f40c291ca
commit
c03876d611
|
@ -12,6 +12,8 @@ lib/ecore_cocoa/Ecore_Cocoa_Keys.h
|
|||
lib_ecore_cocoa_libecore_cocoa_la_SOURCES = \
|
||||
lib/ecore_cocoa/ecore_cocoa.m \
|
||||
lib/ecore_cocoa/ecore_cocoa_window.m \
|
||||
lib/ecore_cocoa/ecore_cocoa_app.m \
|
||||
lib/ecore_cocoa/ecore_cocoa_app.h \
|
||||
lib/ecore_cocoa/ecore_cocoa_private.h
|
||||
|
||||
lib_ecore_cocoa_libecore_cocoa_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_COCOA_CFLAGS@
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
# define EAPI
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -53,7 +55,7 @@ struct _Ecore_Cocoa_Screen
|
|||
|
||||
EAPI int ecore_cocoa_init(void);
|
||||
EAPI int ecore_cocoa_shutdown(void);
|
||||
EAPI void ecore_cocoa_feed_events(void);
|
||||
EAPI Eina_Bool ecore_cocoa_feed_events(void *anEvent);
|
||||
|
||||
/* Screen */
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "ecore_cocoa_window.h"
|
||||
#import "ecore_cocoa_app.h"
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
|
@ -30,16 +31,24 @@ ecore_cocoa_init(void)
|
|||
if (++_ecore_cocoa_init_count != 1)
|
||||
return _ecore_cocoa_init_count;
|
||||
|
||||
if (!ecore_event_init())
|
||||
if (!ecore_init())
|
||||
return --_ecore_cocoa_init_count;
|
||||
|
||||
NSApplicationLoad();
|
||||
if (!ecore_event_init())
|
||||
return --_ecore_cocoa_init_count;
|
||||
|
||||
ECORE_COCOA_EVENT_GOT_FOCUS = ecore_event_type_new();
|
||||
ECORE_COCOA_EVENT_LOST_FOCUS = ecore_event_type_new();
|
||||
ECORE_COCOA_EVENT_RESIZE = ecore_event_type_new();
|
||||
ECORE_COCOA_EVENT_EXPOSE = ecore_event_type_new();
|
||||
|
||||
/* Init the Application handler */
|
||||
[Ecore_Cocoa_Application sharedApplication];
|
||||
[NSApp setDelegate:[Ecore_Cocoa_AppDelegate appDelegate]];
|
||||
|
||||
/* Start events monitoring */
|
||||
[NSApp run];
|
||||
|
||||
return _ecore_cocoa_init_count;
|
||||
}
|
||||
|
||||
|
@ -89,21 +98,16 @@ _has_ecore_cocoa_window(NSEvent *event)
|
|||
return _nsevent_window_is_type_of(event, [EcoreCocoaWindow class]);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_cocoa_feed_events(void)
|
||||
EAPI Eina_Bool
|
||||
ecore_cocoa_feed_events(void *anEvent)
|
||||
{
|
||||
Ecore_Event *ev;
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0.001];
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:date
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
[date release];
|
||||
if (!event) return; // SDL loops until null; maybe we should do that too. or not.
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(anEvent, EINA_FALSE);
|
||||
|
||||
NSEvent *event = anEvent;
|
||||
unsigned int time = (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff);
|
||||
Eina_Bool pass = EINA_FALSE;
|
||||
|
||||
switch([event type])
|
||||
switch ([event type])
|
||||
{
|
||||
case NSMouseMoved:
|
||||
case NSLeftMouseDragged:
|
||||
|
@ -113,7 +117,7 @@ ecore_cocoa_feed_events(void)
|
|||
if (_has_ecore_cocoa_window(event))
|
||||
{
|
||||
Ecore_Event_Mouse_Move * ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
|
||||
if (!ev) return;
|
||||
if (!ev) return pass;
|
||||
|
||||
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
|
||||
NSView *view = [window contentView];
|
||||
|
@ -124,7 +128,7 @@ ecore_cocoa_feed_events(void)
|
|||
ev->root.x = ev->x;
|
||||
ev->root.y = ev->y;
|
||||
ev->timestamp = time;
|
||||
ev->window = window.ecore_window_data;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
ev->modifiers = 0; /* FIXME: keep modifier around. */
|
||||
|
||||
|
@ -135,7 +139,7 @@ ecore_cocoa_feed_events(void)
|
|||
// We might want to handle cases such as events on the menubar.
|
||||
// If so, let's do it here.
|
||||
}
|
||||
[NSApp sendEvent:event]; // pass along mouse events, for window manager
|
||||
pass = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
case NSLeftMouseDown:
|
||||
|
@ -145,7 +149,7 @@ ecore_cocoa_feed_events(void)
|
|||
if (_has_ecore_cocoa_window(event))
|
||||
{
|
||||
Ecore_Event_Mouse_Button * ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
|
||||
if (!ev) return;
|
||||
if (!ev) return pass;
|
||||
|
||||
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
|
||||
NSView *view = [window contentView];
|
||||
|
@ -163,7 +167,7 @@ ecore_cocoa_feed_events(void)
|
|||
case 2: ev->buttons = 2; break;
|
||||
default: ev->buttons = 0; break;
|
||||
}
|
||||
ev->window = window.ecore_window_data;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
|
||||
if ([event clickCount] == 2)
|
||||
|
@ -183,7 +187,7 @@ ecore_cocoa_feed_events(void)
|
|||
// We might want to handle cases such as events on the menubar.
|
||||
// If so, let's do it here.
|
||||
}
|
||||
[NSApp sendEvent:event]; // pass along mouse events, for window manager
|
||||
pass = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
case NSLeftMouseUp:
|
||||
|
@ -191,7 +195,7 @@ ecore_cocoa_feed_events(void)
|
|||
case NSOtherMouseUp:
|
||||
{
|
||||
Ecore_Event_Mouse_Button * ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
|
||||
if (!ev) return;
|
||||
if (!ev) return pass;
|
||||
|
||||
if (_has_ecore_cocoa_window(event))
|
||||
{
|
||||
|
@ -211,7 +215,7 @@ ecore_cocoa_feed_events(void)
|
|||
case 2: ev->buttons = 2; break;
|
||||
default: ev->buttons = 0; break;
|
||||
}
|
||||
ev->window = window.ecore_window_data;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
|
||||
if ([event clickCount] == 2)
|
||||
|
@ -231,7 +235,7 @@ ecore_cocoa_feed_events(void)
|
|||
// We might want to handle cases such as events on the menubar.
|
||||
// If so, let's do it here.
|
||||
}
|
||||
[NSApp sendEvent:event]; // pass along mouse events, for window manager
|
||||
pass = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
case NSKeyDown:
|
||||
|
@ -241,7 +245,7 @@ ecore_cocoa_feed_events(void)
|
|||
EcoreCocoaWindow *window = (EcoreCocoaWindow *)[event window];
|
||||
|
||||
ev = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!ev) return;
|
||||
if (!ev) return pass;
|
||||
ev->timestamp = time;
|
||||
ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]);
|
||||
|
||||
|
@ -253,10 +257,10 @@ ecore_cocoa_feed_events(void)
|
|||
ev->keyname = keystable[i].name;
|
||||
ev->key = keystable[i].name;
|
||||
ev->string = keystable[i].compose;
|
||||
ev->window = window.ecore_window_data;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
|
||||
return;
|
||||
return pass;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +275,7 @@ ecore_cocoa_feed_events(void)
|
|||
printf("Key Up\n");
|
||||
|
||||
ev = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!ev) return;
|
||||
if (!ev) return pass;
|
||||
ev->timestamp = time;
|
||||
ev->modifiers = _ecore_cocoa_event_modifiers([event modifierFlags]);
|
||||
|
||||
|
@ -282,10 +286,10 @@ ecore_cocoa_feed_events(void)
|
|||
ev->keyname = keystable[i].name;
|
||||
ev->key = keystable[i].name;
|
||||
ev->string = keystable[i].compose;
|
||||
ev->window = window.ecore_window_data;
|
||||
ev->window = (Ecore_Window)window.ecore_window_data;
|
||||
ev->event_window = ev->window;
|
||||
ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL);
|
||||
return;
|
||||
return pass;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,13 +303,13 @@ ecore_cocoa_feed_events(void)
|
|||
Ecore_Event_Key *evUp = NULL;
|
||||
|
||||
evDown = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!evDown) return;
|
||||
if (!evDown) return pass;
|
||||
|
||||
evUp = calloc(1, sizeof (Ecore_Event_Key));
|
||||
if (!evUp)
|
||||
{
|
||||
free(evDown);
|
||||
return;
|
||||
return pass;
|
||||
}
|
||||
|
||||
// Turn special key flags on
|
||||
|
@ -360,7 +364,7 @@ ecore_cocoa_feed_events(void)
|
|||
ecore_event_add(ECORE_COCOA_EVENT_GOT_FOCUS, NULL, NULL, NULL);
|
||||
else if ([event subtype] == NSApplicationDeactivatedEventType)
|
||||
ecore_event_add(ECORE_COCOA_EVENT_LOST_FOCUS, NULL, NULL, NULL);
|
||||
[NSApp sendEvent:event]; // pass along AppKit events, for window manager
|
||||
pass = EINA_TRUE; // pass along AppKit events, for window manager
|
||||
break;
|
||||
}
|
||||
case NSScrollWheel:
|
||||
|
@ -370,12 +374,12 @@ ecore_cocoa_feed_events(void)
|
|||
}
|
||||
default:
|
||||
{
|
||||
[NSApp sendEvent:event];
|
||||
pass = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[event release];
|
||||
return pass;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#include "Ecore_Cocoa.h"
|
||||
#include <Ecore.h>
|
||||
|
||||
@interface Ecore_Cocoa_Application : NSApplication
|
||||
{
|
||||
Ecore_Poller *_poller;
|
||||
NSDate *_expiration;
|
||||
}
|
||||
|
||||
- (NSDate *)eventExpirationDate;
|
||||
|
||||
+ (Ecore_Cocoa_Application *)sharedApplication;
|
||||
- (void)run;
|
||||
- (void)sendEvent:(NSEvent *)anEvent;
|
||||
- (id)init;
|
||||
- (void)internalUpdate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface Ecore_Cocoa_AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
+ (Ecore_Cocoa_AppDelegate *)appDelegate;
|
||||
- (id)init;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
#import "ecore_cocoa_app.h"
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_cocoa_run_loop_cb(void *data EINA_UNUSED)
|
||||
{
|
||||
@autoreleasepool {
|
||||
@try {
|
||||
NSEvent *e;
|
||||
do {
|
||||
e = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSApp eventExpirationDate]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
if (e != nil) {
|
||||
//NSLog(@"Catching event %@", e);
|
||||
|
||||
[NSApp sendEvent:e];
|
||||
|
||||
/* Update (en/disable) the services menu's items */
|
||||
NSEventType type = [e type];
|
||||
if (type != NSPeriodic && type != NSMouseMoved) {
|
||||
[NSApp internalUpdate];
|
||||
}
|
||||
}
|
||||
} while (e != nil);
|
||||
}
|
||||
@catch (NSException *except) {
|
||||
NSLog(@"EXCEPTION: %@: %@", [except name], [except reason]);
|
||||
/* Show the "fancy" annoying report panel */
|
||||
[NSApp reportException:except];
|
||||
// XXX Maybe use Eina_Log to report the error instead
|
||||
}
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
@implementation Ecore_Cocoa_Application
|
||||
|
||||
+ (Ecore_Cocoa_Application *)sharedApplication
|
||||
{
|
||||
return (Ecore_Cocoa_Application *)[super sharedApplication];
|
||||
}
|
||||
|
||||
- (void)internalUpdate
|
||||
{
|
||||
[_mainMenu update];
|
||||
// FIXME Will not compile with GNUStep (member is named "_main_menu")
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil) {
|
||||
// XXX Critical error. Abort right now! Log?
|
||||
return nil;
|
||||
}
|
||||
NSApp = self; // NSApp is used EVERYWHERE! Set it right now!
|
||||
return NSApp;
|
||||
}
|
||||
|
||||
- (NSDate *)eventExpirationDate
|
||||
{
|
||||
return _expiration;
|
||||
}
|
||||
|
||||
- (void)run
|
||||
{
|
||||
[self finishLaunching];
|
||||
|
||||
_running = 1;
|
||||
_expiration = [NSDate distantPast];
|
||||
|
||||
_poller = ecore_poller_add(ECORE_POLLER_CORE,
|
||||
ecore_poller_poll_interval_get(ECORE_POLLER_CORE),
|
||||
_ecore_cocoa_run_loop_cb, NULL);
|
||||
if (_poller == NULL) {
|
||||
// XXX ERROR
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)sendEvent:(NSEvent *)anEvent
|
||||
{
|
||||
Eina_Bool to_super;
|
||||
|
||||
/* Some events shall be handled by Ecore (like single non-command keys).
|
||||
* If we dispatch all events right to NSApplication, it will complain
|
||||
* with NSBeep() when an event is not authorized */
|
||||
to_super = ecore_cocoa_feed_events(anEvent);
|
||||
if (to_super)
|
||||
[super sendEvent:anEvent];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
static Ecore_Cocoa_AppDelegate *_appDelegate = nil;
|
||||
|
||||
@implementation Ecore_Cocoa_AppDelegate
|
||||
|
||||
+ (Ecore_Cocoa_AppDelegate *)appDelegate
|
||||
{
|
||||
if (_appDelegate == nil) {
|
||||
_appDelegate = [[self alloc] init];
|
||||
}
|
||||
return _appDelegate;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
{
|
||||
// XXX This should be alterable (by Elm_Window policy)
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -65,7 +65,6 @@
|
|||
event->w = size.width;
|
||||
event->h = size.height -
|
||||
(([self isFullScreen] == YES) ? 0 : ecore_cocoa_titlebar_height_get());
|
||||
printf("Is fullscreen: %i\n", [self isFullScreen]);
|
||||
ecore_event_add(ECORE_COCOA_EVENT_RESIZE, event, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ static Ecore_Event_Handler *ecore_evas_event_handlers[4] = {
|
|||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
|
||||
static Ecore_Poller *ecore_evas_event = NULL;
|
||||
|
||||
//static const char *ecore_evas_cocoa_default = "EFL Cocoa";
|
||||
|
||||
|
@ -198,17 +197,6 @@ _ecore_evas_cocoa_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSE
|
|||
// return EINA_TRUE;
|
||||
//}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_evas_cocoa_event(void *data EINA_UNUSED)
|
||||
{
|
||||
//Ecore_Evas *ee = data;
|
||||
|
||||
DBG("Cocoa Event");
|
||||
|
||||
ecore_cocoa_feed_events();
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_evas_cocoa_init(void)
|
||||
|
@ -246,8 +234,6 @@ _ecore_evas_cocoa_shutdown(void)
|
|||
ecore_event_evas_shutdown();
|
||||
ecore_idle_enterer_del(ecore_evas_idle_enterer);
|
||||
ecore_evas_idle_enterer = NULL;
|
||||
ecore_poller_del(ecore_evas_event);
|
||||
ecore_evas_event = NULL;
|
||||
|
||||
ecore_event_evas_shutdown();
|
||||
}
|
||||
|
@ -529,14 +515,6 @@ ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int
|
|||
|
||||
ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_cocoa_engine_func;
|
||||
|
||||
/* this is pretty bad: poller? and set poll time? pol time is meant to be
|
||||
* adjustable for things like polling battery state, or amoutn of spare
|
||||
* memory etc. I know it's bad but cedric did it for ecore_evas_sdl
|
||||
* so why not me ? BTW why 0.006s ?
|
||||
*/
|
||||
ecore_evas_event = ecore_poller_add(ECORE_POLLER_CORE, 1, _ecore_evas_cocoa_event, ee);
|
||||
ecore_poller_poll_interval_set(ECORE_POLLER_CORE, 0.006);
|
||||
|
||||
if (w < 1) w = 1;
|
||||
if (h < 1) h = 1;
|
||||
ee->visible = 1;
|
||||
|
|
Loading…
Reference in New Issue