Commit ddee6515 authored by Jan Djärv's avatar Jan Djärv

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.
parent ac4845a6
2012-08-15 Jan Djärv <jan.h.d@swipnet.se> 2012-08-15 Jan Djärv <jan.h.d@swipnet.se>
* 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.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.
* nsterm.h (EmacsApp): fd_handler takes id argument.
(EmacsDialogPanel): Add timer_fired and timeout_handler.
* gtkutil.c (xg_mark_data): Use FRAME_X_P. * gtkutil.c (xg_mark_data): Use FRAME_X_P.
2012-08-15 Eli Zaretskii <eliz@gnu.org> 2012-08-15 Eli Zaretskii <eliz@gnu.org>
......
...@@ -73,7 +73,6 @@ ...@@ -73,7 +73,6 @@
/* Nonzero means a menu is currently active. */ /* Nonzero means a menu is currently active. */
static int popup_activated_flag; static int popup_activated_flag;
static NSModalSession popupSession;
/* Nonzero means we are tracking and updating menus. */ /* Nonzero means we are tracking and updating menus. */
static int trackingMenu; static int trackingMenu;
...@@ -1365,8 +1364,6 @@ - (NSRect) frame ...@@ -1365,8 +1364,6 @@ - (NSRect) frame
{ {
EmacsDialogPanel *panel = unwind_data->dialog; EmacsDialogPanel *panel = unwind_data->dialog;
popup_activated_flag = 0; popup_activated_flag = 0;
[NSApp endModalSession: popupSession];
[panel close]; [panel close];
[unwind_data->pool release]; [unwind_data->pool release];
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
...@@ -1756,20 +1753,40 @@ void process_dialog (id window, Lisp_Object list) ...@@ -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 - (Lisp_Object)runDialogAt: (NSPoint)p
{ {
NSInteger ret; NSInteger ret = 0;
/* initiate a session that will be ended by pop_down_menu */ while (popup_activated_flag)
popupSession = [NSApp beginModalSessionForWindow: self];
while (popup_activated_flag
&& (ret = [NSApp runModalSession: popupSession])
== NSRunContinuesResponse)
{ {
/* Run this for timers.el, indep of atimers; might not return. NSTimer *tmo = nil;
TODO: use return value to avoid calling every iteration. */ EMACS_TIME next_time = timer_check ();
timer_check ();
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; 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!!! */ { /* FIXME: BIG UGLY HACK!!! */
......
...@@ -56,7 +56,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -56,7 +56,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
- (void)sendEvent: (NSEvent *)theEvent; - (void)sendEvent: (NSEvent *)theEvent;
- (void)showPreferencesWindow: (id)sender; - (void)showPreferencesWindow: (id)sender;
- (BOOL) openFile: (NSString *)fileName; - (BOOL) openFile: (NSString *)fileName;
- (void)fd_handler: (NSTimer *) fdEntry; - (void)fd_handler: (id)unused;
- (void)timeout_handler: (NSTimer *)timedEntry; - (void)timeout_handler: (NSTimer *)timedEntry;
- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg;
@end @end
...@@ -195,12 +195,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -195,12 +195,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
NSTextField *title; NSTextField *title;
NSMatrix *matrix; NSMatrix *matrix;
int rows, cols; int rows, cols;
int timer_fired;
} }
- initFromContents: (Lisp_Object)menu isQuestion: (BOOL)isQ; - initFromContents: (Lisp_Object)menu isQuestion: (BOOL)isQ;
- addButton: (char *)str value: (Lisp_Object)val row: (int)row; - addButton: (char *)str value: (Lisp_Object)val row: (int)row;
- addString: (char *)str row: (int)row; - addString: (char *)str row: (int)row;
- addSplit; - addSplit;
- (Lisp_Object)runDialogAt: (NSPoint)p; - (Lisp_Object)runDialogAt: (NSPoint)p;
- (void)timeout_handler: (NSTimer *)timedEntry;
@end @end
#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
......
...@@ -39,6 +39,10 @@ Updated by Christian Limpach (chris@nice.ch) ...@@ -39,6 +39,10 @@ Updated by Christian Limpach (chris@nice.ch)
#include <c-strcase.h> #include <c-strcase.h>
#include <ftoastr.h> #include <ftoastr.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "lisp.h" #include "lisp.h"
#include "blockinput.h" #include "blockinput.h"
#include "sysselect.h" #include "sysselect.h"
...@@ -184,17 +188,20 @@ Updated by Christian Limpach (chris@nice.ch) ...@@ -184,17 +188,20 @@ Updated by Christian Limpach (chris@nice.ch)
static BOOL send_appdefined = YES; static BOOL send_appdefined = YES;
static NSEvent *last_appdefined_event = 0; static NSEvent *last_appdefined_event = 0;
static NSTimer *timed_entry = 0; static NSTimer *timed_entry = 0;
static NSTimer *fd_entry = nil;
static NSTimer *scroll_repeat_entry = nil; static NSTimer *scroll_repeat_entry = nil;
static fd_set select_readfds, t_readfds; static fd_set select_readfds, select_writefds;
static int select_nfds; enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 };
static int select_nfds = 0, select_valid = 0;
static EMACS_TIME select_timeout = { 0, 0 };
static int selfds[2] = { -1, -1 };
static pthread_mutex_t select_mutex;
static int apploopnr = 0;
static NSAutoreleasePool *outerpool; static NSAutoreleasePool *outerpool;
static struct input_event *emacs_event = NULL; static struct input_event *emacs_event = NULL;
static struct input_event *q_event_ptr = NULL; static struct input_event *q_event_ptr = NULL;
static int n_emacs_events_pending = 0; static int n_emacs_events_pending = 0;
static NSMutableArray *ns_pending_files, *ns_pending_service_names, static NSMutableArray *ns_pending_files, *ns_pending_service_names,
*ns_pending_service_args; *ns_pending_service_args;
static BOOL inNsSelect = 0;
static BOOL ns_do_open_file = NO; static BOOL ns_do_open_file = NO;
/* Convert modifiers in a NeXTstep event to emacs style modifiers. */ /* Convert modifiers in a NeXTstep event to emacs style modifiers. */
...@@ -252,15 +259,20 @@ Updated by Christian Limpach (chris@nice.ch) ...@@ -252,15 +259,20 @@ Updated by Christian Limpach (chris@nice.ch)
/* This is a piece of code which is common to all the event handling /* This is a piece of code which is common to all the event handling
methods. Maybe it should even be a function. */ methods. Maybe it should even be a function. */
#define EV_TRAILER(e) \ #define EV_TRAILER(e) \
{ \ { \
XSETFRAME (emacs_event->frame_or_window, emacsframe); \ XSETFRAME (emacs_event->frame_or_window, emacsframe); \
if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \
n_emacs_events_pending++; \ if (q_event_ptr) \
kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \ { \
EVENT_INIT (*emacs_event); \ n_emacs_events_pending++; \
ns_send_appdefined (-1); \ kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \
} } \
else \
kbd_buffer_store_event (emacs_event); \
EVENT_INIT (*emacs_event); \
ns_send_appdefined (-1); \
}
void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object); void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
...@@ -3377,14 +3389,6 @@ overwriting cursor (usually when cursor on a tab) */ ...@@ -3377,14 +3389,6 @@ overwriting cursor (usually when cursor on a tab) */
timed_entry = nil; timed_entry = nil;
} }
/* Ditto for file descriptor poller */
if (fd_entry)
{
[fd_entry invalidate];
[fd_entry release];
fd_entry = nil;
}
nxev = [NSEvent otherEventWithType: NSApplicationDefined nxev = [NSEvent otherEventWithType: NSApplicationDefined
location: NSMakePoint (0, 0) location: NSMakePoint (0, 0)
modifierFlags: 0 modifierFlags: 0
...@@ -3402,7 +3406,6 @@ overwriting cursor (usually when cursor on a tab) */ ...@@ -3402,7 +3406,6 @@ overwriting cursor (usually when cursor on a tab) */
} }
} }
static int static int
ns_read_socket (struct terminal *terminal, int expected, ns_read_socket (struct terminal *terminal, int expected,
struct input_event *hold_quit) struct input_event *hold_quit)
...@@ -3466,24 +3469,14 @@ overwriting cursor (usually when cursor on a tab) */ ...@@ -3466,24 +3469,14 @@ overwriting cursor (usually when cursor on a tab) */
/* Run and wait for events. We must always send one NX_APPDEFINED event /* Run and wait for events. We must always send one NX_APPDEFINED event
to ourself, otherwise [NXApp run] will never exit. */ to ourself, otherwise [NXApp run] will never exit. */
send_appdefined = YES; send_appdefined = YES;
ns_send_appdefined (-1);
/* If called via ns_select, this is called once with expected=1, if (++apploopnr != 1)
because we expect either the timeout or file descriptor activity.
In this case the first event through will either be real input or
one of these. read_avail_input() then calls once more with expected=0
and in that case we need to return quickly if there is nothing.
If we're being called outside of that, it's also OK to return quickly
after one iteration through the event loop, since other terms do
this and emacs expects it. */
if (!(inNsSelect && expected))
{ {
/* Post an application defined event on the event queue. When this is abort ();
received the [NXApp run] will return, thus having processed all
events which are currently queued, if any. */
ns_send_appdefined (-1);
} }
[NSApp run]; [NSApp run];
--apploopnr;
} }
nevents = n_emacs_events_pending; nevents = n_emacs_events_pending;
...@@ -3503,65 +3496,89 @@ overwriting cursor (usually when cursor on a tab) */ ...@@ -3503,65 +3496,89 @@ overwriting cursor (usually when cursor on a tab) */
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
{ {
int result; int result;
double time;
NSEvent *ev; NSEvent *ev;
struct timespec select_timeout; int k, nr = 0;
struct input_event event;
char c;
/* NSTRACE (ns_select); */ /* NSTRACE (ns_select); */
if (NSApp == nil || inNsSelect == 1 /* || ([NSApp isActive] == NO && for (k = 0; readfds && k < nfds+1; k++)
[NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil if (FD_ISSET(k, readfds)) ++nr;
inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */)
if (NSApp == nil
|| (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
/* Save file descriptor set, which gets overwritten in calls to select () [outerpool release];
Note, this is called from process.c, and only readfds is ever set */ outerpool = [[NSAutoreleasePool alloc] init];
if (readfds)
send_appdefined = YES;
if (nr > 0)
{ {
memcpy (&select_readfds, readfds, sizeof (fd_set)); pthread_mutex_lock (&select_mutex);
select_nfds = nfds; select_nfds = nfds;
select_valid = 0;
if (readfds)
{
select_readfds = *readfds;
select_valid += SELECT_HAVE_READ;
}
if (writefds)
{
select_writefds = *writefds;
select_valid += SELECT_HAVE_WRITE;
}
if (timeout)
{
select_timeout = *timeout;
select_valid += SELECT_HAVE_TMO;
}
pthread_mutex_unlock (&select_mutex);
/* Inform fd_handler that select should be called */
c = 'g';
write (selfds[1], &c, 1);
} }
else else if (nr == 0 && timeout)
select_nfds = 0; {
/* No file descriptor, just a timeout, no need to wake fd_handler */
/* Try an initial select for pending data on input files */ double time = EMACS_TIME_TO_DOUBLE (*timeout);
select_timeout.tv_sec = select_timeout.tv_nsec = 0; timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
result = pselect (nfds, readfds, writefds, exceptfds, target: NSApp
&select_timeout, sigmask); selector:
if (result) @selector (timeout_handler:)
return result; userInfo: 0
repeats: NO]
/* if (!timeout || timed_entry || fd_entry) retain];
fprintf (stderr, "assertion failed: timeout null or timed_entry/fd_entry non-null in ns_select\n"); */ }
else /* No timeout and no file descriptors, can this happen? */
/* set a timeout and run the main AppKit event loop while continuing {
to monitor the files */ /* Send appdefined so we exit from the loop */
time = EMACS_TIME_TO_DOUBLE (*timeout); ns_send_appdefined (-1);
timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time }
target: NSApp
selector: @selector (timeout_handler:) EVENT_INIT (event);
userInfo: 0 BLOCK_INPUT;
repeats: YES] /* for safe removal */ emacs_event = &event;
retain]; if (++apploopnr != 1)
{
/* set a periodic task to try the pselect () again */ abort();
fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1 }
target: NSApp [NSApp run];
selector: @selector (fd_handler:) --apploopnr;
userInfo: 0 emacs_event = NULL;
repeats: YES] if (nr > 0 && readfds)
retain]; {
c = 's';
/* Let Application dispatch events until it receives an event of the type write (selfds[1], &c, 1);
NX_APPDEFINED, which should only be sent by timeout_handler. }
We tell read_avail_input() that input is "expected" because we do expect UNBLOCK_INPUT;
either the timeout or fd handler to fire, and if they don't, the original
call from process.c that got us here expects us to wait until some input
comes. */
inNsSelect = 1;
gobble_input (1);
ev = last_appdefined_event; ev = last_appdefined_event;
inNsSelect = 0;
if (ev) if (ev)
{ {
...@@ -3575,25 +3592,28 @@ We tell read_avail_input() that input is "expected" because we do expect ...@@ -3575,25 +3592,28 @@ We tell read_avail_input() that input is "expected" because we do expect
if (t == -2) if (t == -2)
{ {
/* The NX_APPDEFINED event we received was a timeout. */ /* The NX_APPDEFINED event we received was a timeout. */
return 0; result = 0;
} }
else if (t == -1) else if (t == -1)
{ {
/* The NX_APPDEFINED event we received was the result of /* The NX_APPDEFINED event we received was the result of
at least one real input event arriving. */ at least one real input event arriving. */
errno = EINTR; errno = EINTR;
return -1; result = -1;
} }
else else
{ {
/* Received back from pselect () in fd_handler; copy the results */ /* Received back from select () in fd_handler; copy the results */
if (readfds) pthread_mutex_lock (&select_mutex);
memcpy (readfds, &select_readfds, sizeof (fd_set)); if (readfds) *readfds = select_readfds;
return t; if (writefds) *writefds = select_writefds;
if (timeout) *timeout = select_timeout;
pthread_mutex_unlock (&select_mutex);
result = t;
} }
} }
/* never reached, shut compiler up */
return 0; return result;
} }
...@@ -4024,6 +4044,21 @@ static Lisp_Object ns_string_to_lispmod (const char *s) ...@@ -4024,6 +4044,21 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
{ {
baud_rate = 38400; baud_rate = 38400;
Fset_input_interrupt_mode (Qnil); Fset_input_interrupt_mode (Qnil);
if (selfds[0] == -1)
{
if (pipe (selfds) == -1)
{
fprintf (stderr, "Failed to create pipe: %s\n",
emacs_strerror (errno));
abort ();
}
fcntl (selfds[0], F_SETFL, O_NONBLOCK|fcntl (selfds[0], F_GETFL));
FD_ZERO (&select_readfds);
FD_ZERO (&select_writefds);
pthread_mutex_init (&select_mutex, NULL);
}
ns_initialized = 1; ns_initialized = 1;
} }
...@@ -4039,6 +4074,11 @@ Needs to be here because ns_initialize_display_info () uses AppKit classes. ...@@ -4039,6 +4074,11 @@ Needs to be here because ns_initialize_display_info () uses AppKit classes.
return NULL; return NULL;
[NSApp setDelegate: NSApp]; [NSApp setDelegate: NSApp];
/* Start the select thread. */
[NSThread detachNewThreadSelector:@selector (fd_handler:)
toTarget:NSApp
withObject:nil];
/* debugging: log all notifications */ /* debugging: log all notifications */
/* [[NSNotificationCenter defaultCenter] addObserver: NSApp /* [[NSNotificationCenter defaultCenter] addObserver: NSApp
selector: @selector (logNotification:) selector: @selector (logNotification:)
...@@ -4547,26 +4587,91 @@ - (void)timeout_handler: (NSTimer *)timedEntry ...@@ -4547,26 +4587,91 @@ - (void)timeout_handler: (NSTimer *)timedEntry
ns_send_appdefined (-2); ns_send_appdefined (-2);
} }
- (void)fd_handler: (NSTimer *) fdEntry - (void)fd_handler:(id)unused
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Check data waiting on file descriptors and terminate if so Check data waiting on file descriptors and terminate if so
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
{ {
int result; int result;
struct timespec select_timeout; int waiting = 1, nfds;
/* NSTRACE (fd_handler); */ char c;
if (select_nfds == 0) SELECT_TYPE readfds, writefds, *wfds;
return; EMACS_TIME timeout, *tmo;
memcpy (&t_readfds, &select_readfds, sizeof (fd_set)); /* NSTRACE (fd_handler); */
select_timeout.tv_sec = select_timeout.tv_nsec = 0; for (;;)
result = pselect (select_nfds, &t_readfds, NULL, NULL, &select_timeout, NULL);
if (result)
{ {
memcpy (&select_readfds, &t_readfds, sizeof (fd_set)); if (waiting)
ns_send_appdefined (result); {
SELECT_TYPE fds;
FD_SET (selfds[0], &fds);
result = select (selfds[0]+1, &fds, NULL, NULL, NULL);
if (result > 0)
{
read (selfds[0], &c, 1);
if (c == 'g') waiting = 0;
}
}
else
{
pthread_mutex_lock (&select_mutex);
nfds = select_nfds;
if (select_valid & SELECT_HAVE_READ)
readfds = select_readfds;
else
FD_ZERO (&readfds);
if (select_valid & SELECT_HAVE_WRITE)
{
writefds = select_writefds;
wfds = &writefds;
}
else
wfds = NULL;
if (select_valid & SELECT_HAVE_TMO)
{
timeout = select_timeout;
tmo = &timeout;
}
else
tmo = NULL;
pthread_mutex_unlock (&select_mutex);
FD_SET (selfds[0], &readfds);
if (selfds[0] >= nfds) nfds = selfds[0]+1;
result = pselect (nfds, &readfds, wfds, NULL, tmo, NULL);
if (result == 0)
ns_send_appdefined (-2);
else if (result > 0)
{
if (FD_ISSET (selfds[0], &readfds))
{
read (selfds[0], &c, 1);
if (c == 's') waiting = 1;
}
else
{
pthread_mutex_lock (&select_mutex);
if (select_valid & SELECT_HAVE_READ)
select_readfds = readfds;
if (select_valid & SELECT_HAVE_WRITE)
select_writefds = writefds;
if (select_valid & SELECT_HAVE_TMO)
select_timeout = timeout;
pthread_mutex_unlock (&select_mutex);
ns_send_appdefined (result);
}
}
waiting = 1;
}
} }
} }
...@@ -6404,8 +6509,13 @@ - (void) sendScrollEventAtLoc: (float)loc fromEvent: (NSEvent *)e ...@@ -6404,8 +6509,13 @@ - (void) sendScrollEventAtLoc: (float)loc fromEvent: (NSEvent *)e
XSETINT (emacs_event->x, loc * pixel_height); XSETINT (emacs_event->x, loc * pixel_height);
XSETINT (emacs_event->y, pixel_height-20); XSETINT (emacs_event->y, pixel_height-20);
n_emacs_events_pending++; if (q_event_ptr)
kbd_buffer_store_event_hold (emacs_event, q_event_ptr); {
n_emacs_events_pending++;
kbd_buffer_store_event_hold (emacs_event, q_event_ptr);
}
else
kbd_buffer_store_event (emacs_event);
EVENT_INIT (*emacs_event); EVENT_INIT (*emacs_event);
ns_send_appdefined (-1); ns_send_appdefined (-1);
} }
......
Markdown is supported
0%