diff --git a/configure b/configure index 76b8a9222b..2f33e80974 100755 --- a/configure +++ b/configure @@ -1829,7 +1829,7 @@ if test "$_x11" = auto && test "$_x11_headers" = yes ; then else _ld_tmp="$I -lXext -lX11 $_ld_pthread" fi - statement_check X11/Xutil.h 'XCreateWindow(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)' $_ld_tmp && + statement_check_broken X11/Xutil.h X11/XKBlib.h 'XCreateWindow(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)' $_ld_tmp && _x11=yes # Check that there aren't conflicting headers between ApplicationServices # and X11. On versions of Mac OSX prior to 10.7 the deprecated QuickDraw API diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h index 8e0563e380..156835fd07 100644 --- a/core/cfg-mplayer.h +++ b/core/cfg-mplayer.h @@ -574,6 +574,7 @@ const m_option_t mplayer_opts[]={ OPT_INTRANGE("fsmode-dontuse", vo.fsmode, 0, 31, 4096), OPT_INT("colorkey", vo.colorkey, 0), OPT_FLAG_STORE("no-colorkey", vo.colorkey, 0, 0x1000000), + OPT_FLAG("native-keyrepeat", vo.native_keyrepeat, 0), OPT_FLOATRANGE("panscan", vo.panscan, 0, 0.0, 1.0), OPT_FLOATRANGE("panscanrange", vo.panscanrange, 0, -19.0, 99.0), OPT_FLAG("force-rgba-osd-rendering", force_rgba_osd, 0), diff --git a/core/options.h b/core/options.h index 0f57381f30..35d0329b7a 100644 --- a/core/options.h +++ b/core/options.h @@ -17,6 +17,7 @@ typedef struct mp_vo_opts { int stop_screensaver; char *winname; char** fstype_list; + int native_keyrepeat; float panscan; float panscanrange; diff --git a/video/out/x11_common.c b/video/out/x11_common.c index a08f95d822..2e5f14f8d1 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -44,6 +44,7 @@ #include #include #include +#include #ifdef CONFIG_XSS #include @@ -450,6 +451,12 @@ int vo_x11_init(struct vo *vo) x11->screen = DefaultScreen(x11->display); // screen ID x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID + if (!opts->native_keyrepeat) { + Bool ok = False; + XkbSetDetectableAutoRepeat(x11->display, True, &ok); + x11->no_autorepeat = ok; + } + x11->xim = XOpenIM(x11->display, NULL, NULL, NULL); init_atoms(vo->x11); @@ -629,6 +636,8 @@ void vo_x11_uninit(struct vo *vo) struct vo_x11_state *x11 = vo->x11; assert(x11); + mplayer_put_key(vo->key_fifo, MP_INPUT_RELEASE_ALL); + saver_on(x11); if (x11->window != None) vo_showcursor(vo, x11->display, x11->window); @@ -721,6 +730,8 @@ int vo_x11_check_events(struct vo *vo) char buf[100]; KeySym keySym = 0; int modifiers = 0; + if (x11->no_autorepeat) + modifiers |= MP_KEY_STATE_DOWN; if (Event.xkey.state & ShiftMask) modifiers |= MP_KEY_MODIFIER_SHIFT; if (Event.xkey.state & ControlMask) @@ -747,8 +758,17 @@ int vo_x11_check_events(struct vo *vo) if (mpkey) mplayer_put_key(vo->key_fifo, mpkey | modifiers); } + break; + } + // Releasing all keys in these situations is simpler and ensures no + // keys can be get "stuck". + case FocusOut: + case KeyRelease: + { + if (x11->no_autorepeat) + mplayer_put_key(vo->key_fifo, MP_INPUT_RELEASE_ALL); + break; } - break; case MotionNotify: vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y); vo_x11_unhide_cursor(vo); @@ -981,7 +1001,8 @@ static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h) vo_x11_decoration(vo, 0); // map window vo_x11_selectinput_witherr(vo, x11->display, x11->window, - StructureNotifyMask | KeyPressMask | + StructureNotifyMask | + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask); XMapWindow(x11->display, x11->window); diff --git a/video/out/x11_common.h b/video/out/x11_common.h index 2ac3da2864..88a52e1953 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -44,6 +44,7 @@ struct vo_x11_state { XIM xim; XIC xic; + bool no_autorepeat; GC f_gc; // used to paint background GC vo_gc; // used to paint video