diff options
author | Jan Djärv <jan.h.d@swipnet.se> | 2012-08-15 20:58:19 +0200 |
---|---|---|
committer | Jan Djärv <jan.h.d@swipnet.se> | 2012-08-15 20:58:19 +0200 |
commit | ddee65158cd55a0c045a1ebc26f8ff73768cdc64 (patch) | |
tree | 3ec8cde41573810900d76832751badde8c57f41e /src/nsmenu.m | |
parent | ac4845a68bf3ee0a0b4b88c292207d9738b981bd (diff) | |
download | emacs-ddee65158cd55a0c045a1ebc26f8ff73768cdc64.tar.gz |
Improve event loop on NS so that no polling is used.
* nsmenu.m (popupSession): Remove.
(pop_down_menu): Remove endModalSession.
(timeout_handler:): New method.
(runDialogAt:): Get next timeout. Start a NSTimer with that timeout.
Call runModalForWindow. Check timer_fired when it returns.
If not set, cancel timer and break out of loop.
Otherwise loop again, with a new timeout.
* nsterm.h (EmacsApp): fd_handler takes id argument.
(EmacsDialogPanel): Add timer_fired and timeout_handler.
* nsterm.m: Include fcntl.h if present.
(fd_entry, t_readfds, inNsSelect): Remove.
(select_writefds, select_valid, select_timeout, selfds)
(select_mutex, apploopnr): Add.
(EV_TRAILER): Call kbd_buffer_store_event_hold only if q_event_ptr.
Otherwise call kbd_buffer_store_event.
(ns_send_appdefined): Remove release of fd_entry.
(ns_read_socket): Always send appdefined. Remove inNsSelect check.
Increment and decrement apploopnr.
(ns_select): If no file descriptors, just do a NSTimer.
Otherwise copy read/write masks and start select thread (fd_handler).
Start main loop and wait for application defined event.
Inform select thread to stop selecting after main loop is exited.
(ns_term_init): Create selfds pipe and set non-blocking.
Initialize select_mutex. Start the select thread (fd_handler).
(fd_handler:): Loop forever, wait for info from the main thread
to either start or stop selecting. When select returns, send
and appdefined event.
(sendScrollEventAtLoc:fromEvent:): Check if q_event_ptr is set.
If not call kbd_buffer_store_event.
Diffstat (limited to 'src/nsmenu.m')
-rw-r--r-- | src/nsmenu.m | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/nsmenu.m b/src/nsmenu.m index 210f4530d7a..657b9306942 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -73,7 +73,6 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu; /* Nonzero means a menu is currently active. */ static int popup_activated_flag; -static NSModalSession popupSession; /* Nonzero means we are tracking and updating menus. */ static int trackingMenu; @@ -1365,8 +1364,6 @@ pop_down_menu (Lisp_Object arg) { EmacsDialogPanel *panel = unwind_data->dialog; popup_activated_flag = 0; - [NSApp endModalSession: popupSession]; - [panel close]; [unwind_data->pool release]; [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; @@ -1756,20 +1753,40 @@ void process_dialog (id window, Lisp_Object list) } + +- (void)timeout_handler: (NSTimer *)timedEntry +{ + timer_fired = 1; + [NSApp abortModal]; +} + - (Lisp_Object)runDialogAt: (NSPoint)p { - NSInteger ret; + NSInteger ret = 0; - /* initiate a session that will be ended by pop_down_menu */ - popupSession = [NSApp beginModalSessionForWindow: self]; - while (popup_activated_flag - && (ret = [NSApp runModalSession: popupSession]) - == NSRunContinuesResponse) + while (popup_activated_flag) { - /* Run this for timers.el, indep of atimers; might not return. - TODO: use return value to avoid calling every iteration. */ - timer_check (); - [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; + NSTimer *tmo = nil; + EMACS_TIME next_time = timer_check (); + + if (EMACS_TIME_VALID_P (next_time)) + { + double time = EMACS_TIME_TO_DOUBLE (next_time); + tmo = [NSTimer timerWithTimeInterval: time + target: self + selector: @selector (timeout_handler:) + userInfo: 0 + repeats: NO]; + [[NSRunLoop currentRunLoop] addTimer: tmo + forMode: NSModalPanelRunLoopMode]; + } + timer_fired = 0; + ret = [NSApp runModalForWindow: self]; + if (! timer_fired) + { + if (tmo != nil) [tmo invalidate]; /* Cancels timer */ + break; + } } { /* FIXME: BIG UGLY HACK!!! */ |