cocoa_events: remove this functionality

This functionality looked smart but created problems with some kinds of
multi touch events. Moreover some events coming from the windows server – like
hovering a corner for window resize – didn't cause the player to wake up
immediately.

The "correct" non hacky way to implement async event polling with cocoa would
be having the vanilla cocoa event loop driving the player and setting up mpv's
terminal FDs as event sources for the cocoa event loop.

Fixes #20
This commit is contained in:
Stefano Pigozzi 2013-02-02 14:20:24 +01:00
parent 6e4a45476f
commit 68fa3c49db
5 changed files with 2 additions and 185 deletions

View File

@ -48,8 +48,7 @@ SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c
SOURCES-$(MACOSX_FINDER) += osdep/macosx_finder_args.m
SOURCES-$(MACOSX_BUNDLE) += osdep/macosx_bundle.m
SOURCES-$(COCOA) += video/out/osx_common.m \
video/out/cocoa_common.m \
osdep/cocoa_events.m
video/out/cocoa_common.m
SOURCES-$(MNG) += demux/demux_mng.c
SOURCES-$(MPG123) += audio/decode/ad_mpg123.c

View File

@ -61,10 +61,6 @@
#include "ar.h"
#ifdef CONFIG_COCOA
#include "osdep/cocoa_events.h"
#endif
#define MP_MAX_KEY_DOWN 32
struct cmd_bind {
@ -1505,11 +1501,7 @@ static void read_all_fd_events(struct input_ctx *ictx, int time)
static void read_all_events(struct input_ctx *ictx, int time)
{
getch2_poll();
#ifdef CONFIG_COCOA
cocoa_events_read_all_events(ictx, time);
#else
read_all_fd_events(ictx, time);
#endif
}
int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd)
@ -1774,10 +1766,6 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf)
parse_config(ictx, true, bstr0(builtin_input_conf), "<default>");
#ifdef CONFIG_COCOA
cocoa_events_init(ictx, read_all_fd_events);
#endif
#ifndef __MINGW32__
long ret = pipe(ictx->wakeup_pipe);
for (int i = 0; i < 2 && ret >= 0; i++) {
@ -1890,10 +1878,6 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf)
void mp_input_uninit(struct input_ctx *ictx)
{
#ifdef CONFIG_COCOA
cocoa_events_uninit();
#endif
if (!ictx)
return;

View File

@ -1,30 +0,0 @@
/*
* Cocoa Event Handling
*
* This file is part of mplayer2.
*
* mplayer2 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mplayer2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mplayer2. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MPLAYER_COCOA_EVENTS_H
#define MPLAYER_COCOA_EVENTS_H
#include "core/input/input.h"
void cocoa_events_init(struct input_ctx *ictx,
void (*read_all_fd_events)(struct input_ctx *ictx, int time));
void cocoa_events_uninit(void);
void cocoa_events_read_all_events(struct input_ctx *ictx, int time);
#endif /* MPLAYER_COCOA_EVENTS_H */

View File

@ -1,137 +0,0 @@
/*
* Cocoa Event Handling
*
* This file is part of mplayer2.
*
* mplayer2 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mplayer2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mplayer2. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Implementation details:
* This file deals with custom event polling on MacOSX. When mplayer2 is paused
* it will asynchronously poll for events using select. This works correctly on
* Linux with X11 since the events are notified through the file descriptors
* where mplayer2 is listening on. On the other hand, the OSX window server
* notifies the processes for events using mach ports.
*
* The code below uses functionality from Cocoa that abstracts the async polling
* of events from the window server. When a Cocoa event comes in, the polling is
* interrupted and the event is dealt with in the next vo_check_events.
*
* To keep the select fd polling code working, that functionality is executed
* from another thread. Whoever finishes polling before the given time, be it
* Cocoa or the original select code, notifies the other for an immediate wake.
*/
#include "cocoa_events.h"
#include "video/out/cocoa_common.h"
#include "talloc.h"
#import <Cocoa/Cocoa.h>
#include <dispatch/dispatch.h>
// Bogus event subtype to wake the Cocoa code from polling state
#define MP_EVENT_SUBTYPE_WAKE_EVENTLOOP 100
// This is the threshold in milliseconds below which the Cocoa polling is not
// executed. There is some overhead caused by the synchronization between
// threads. Even if in practice it isn't noticeable, we try to avoid the useless
// waste of resources.
#define MP_ASYNC_THRESHOLD 50
struct priv {
dispatch_queue_t select_queue;
bool is_runloop_polling;
void (*read_all_fd_events)(struct input_ctx *ictx, int time);
};
static struct priv *p;
static void cocoa_wait_events(int mssleeptime)
{
NSTimeInterval sleeptime = mssleeptime / 1000.0;
NSEvent *event;
p->is_runloop_polling = YES;
event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate dateWithTimeIntervalSinceNow:sleeptime]
inMode:NSEventTrackingRunLoopMode dequeue:NO];
// dequeue the next event if it is a fake to wake the cocoa polling
if (event && [event type] == NSApplicationDefined &&
[event subtype] == MP_EVENT_SUBTYPE_WAKE_EVENTLOOP) {
[NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
inMode:NSEventTrackingRunLoopMode dequeue:YES];
}
p->is_runloop_polling = NO;
}
static void cocoa_wake_runloop()
{
if (p->is_runloop_polling) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSEvent *event;
/* Post an event so we'll wake the run loop that is async polling */
event = [NSEvent otherEventWithType: NSApplicationDefined
location: NSZeroPoint
modifierFlags: 0
timestamp: 0
windowNumber: 0
context: nil
subtype: MP_EVENT_SUBTYPE_WAKE_EVENTLOOP
data1: 0
data2: 0];
[NSApp postEvent:event atStart:NO];
[pool release];
}
}
void cocoa_events_init(struct input_ctx *ictx,
void (*read_all_fd_events)(struct input_ctx *ictx, int time))
{
NSApplicationLoad();
p = talloc_ptrtype(NULL, p);
*p = (struct priv){
.is_runloop_polling = NO,
.read_all_fd_events = read_all_fd_events,
.select_queue = dispatch_queue_create("org.mpv.select_queue",
NULL),
};
}
void cocoa_events_uninit(void)
{
talloc_free(p);
}
void cocoa_events_read_all_events(struct input_ctx *ictx, int time)
{
// don't bother delegating the select to the async queue if the blocking
// time is really low or if we are not running a GUI
if (time > MP_ASYNC_THRESHOLD && vo_cocoa_gui_running()) {
dispatch_async(p->select_queue, ^{
p->read_all_fd_events(ictx, time);
cocoa_wake_runloop();
});
cocoa_wait_events(time);
mp_input_wakeup(ictx);
// wait for the async queue to get empty.
dispatch_sync(p->select_queue, ^{});
} else {
p->read_all_fd_events(ictx, time);
}
}

View File

@ -196,6 +196,7 @@ static void disable_power_management(struct vo *vo)
int vo_cocoa_init(struct vo *vo)
{
vo->cocoa = vo_cocoa_init_state(vo);
vo->wakeup_period = 0.02;
_instances++;
NSApplicationLoad();