For some reason, when using window embedding, and the window manager is
OpenBox, calling XSetWMNormalHints() before the window is mapped, the
initial window position will be off. It leaves some vertical space,
instead of placing it on the top/left corner. Suspiciously, the vertical
space is as much as a the height of normal window decoration.
I don't know what kind of issue this is. Possibly an OpenBox bug, but
then this happens even if the override-redirect flag is set. (This flag
basically tells the X server to ignore the window manager. Normally we
don't set it.) On other window managers, it works fine. So I don't know
why this is happening.
But this is easy to workaround. XSetWMNormalHints() isn't needed at all
if embedding.
Should fix#1235.
Always include the window position in winrc, even if the window
embedded. This should give the correct positions for things which still
interact with global coordinates, such as the xrandr code.
XRRGetOutputInfo contains a "name" element which corresponds to to the
display names given to the user by the "xrandr" command line
utility. Copy it into the xrandr_display struct for each display.
On VOCTRL_GET_DISPLAY_NAMES, send a copy of the names
of the displays spanned by the mpv window on.
In interlaced modes, we output fields, not complete frames, so the
framerate doubles.
The method to calculate this was borrowed from xrandr code.
Hopefully fixes#1224.
Instead of letting the window-scale property return the old value until
X11 actually executed the resize, just set the new assumed internal
window size immediately. This avoids a "lag" between setting and reading
the window-scale property, like OSD controls typically do.
Remove the additional calls from vo_x11_highlevel_resize() - they're
pointless and slightly wrong, and resize events will take care of
updating these things correctly anyway.
Fixes#1176.
("window-scale" works via VOCTRL_[S|G]ET_UNFS_WINDOW_SIZE.)
This can hang if the window was destroyed externally (or that's what I
suspect happens), and we somehow didn't receive the DestroyNotify event.
I'm not sure why we wouldn't receive this event (since it should just be
in the xlib event queue), but on the other hand there's no real need to
wait for window destruction.
This essentially reverts 97fc74e2.
Worryingly wrong. Fixes#1162.
Also fix another issue (window title was set anyway), which was why I
didn't notice this and testing it seemed to be fine.
--x11-netwm=yes now forces NetWM fullscreen, while --x11-netwm=auto
(detect whether NetWM fullsctreen support is available) is the old
behavior and still the default.
See #888.
Another fallout resulting from the changes whether or not to wait for
mapping the window. In this case, it obviously makes no sense to wait
for mapping, because the root window is always mapped. Mapping will
never happen, and it would wait forever.
Fixes#1139.
CC: @mpv-player/stable
At least on kwin, we decide to proceed without waiting for the window
being mapped (due to the frame exts hack, see commit 8c002b79). But that
leaves us with a window size of 0x0, which causes VdpOutputSurfaceCreate
to fail. This prints some warnings, although vo_vdpau recovers later and
this has no other bad consequences.
Do the following things to deal with this:
- set the "known" window size to the suggested window size before the
window is even created
- allow calling XGetGeometry on the window even if the window is not
mapped yet (this should work just fine)
- make the output surface minimum size 1x1
Strictly speaking, only one of these would be required to make the
warning disappear, but they're all valid changes and increase robustness
and correctness. At no point we use a window size of 0x0 as magic value
for "unset" or unknown size, so keeping it unset has no purpose anyway.
CC: @mpv-player/stable
Commit 64b7811c tried to do the "right thing" with respect to whether
keyboard input should be enabled or not. It turns out that X11 does
something stupid by design. All modern toolkits work around this native
X11 behavior, but embedding breaks these workarounds.
The only way to handle this correctly is the XEmbed protocol. It needs
to be supported by the toolkit, and probably also some mpv support. But
Qt has inconsistent support for it. In Qt 4, a X11 specific embedding
widget was needed. Qt 5.0 doesn't support it at all. Qt 5.1 apparently
supports it via QWindow, but if it really does, I couldn't get it to
work.
So add a hack instead. The new --input-x11-keyboard option controls
whether mpv should enable keyboard input on the X11 window or not. In
the command line player, it's enabled by default, but in libmpv it's
disabled.
This hack has the same problem as all previous embedding had: move the
mouse outside of the window, and you don't get keyboard input anymore.
Likewise, mpv will steal all keyboard input from the parent application
as long as the mouse is inside of the mpv window.
Also see issue #1090.
Some window managers can prevent mapping of a window as a feature. i3
can put new windows on a certain workspace (with "assign"), so if mpv is
started on a different workspace, the window will never be mapped.
mpv currently waits until the window is mapped (blocking almost all of
the player), in order to avoid race conditions regarding the window
size. We don't want to remove this, but on the other hand we also don't
want to block the player forever in these situations.
So what we need is a way to know when the window manager is "done" with
processing the map request. Unfortunately, there doesn't seem to be a
standard way for this. So, instead we could do some arbitrary
communication with the WM, that may act as "barrier" after map request
and the "immediate" mapping of the window. If the window is not mapped
after this barrier, it means the window manager decided to delay the
mapping indefinitely. Use the _NET_REQUEST_FRAME_EXTENTS message as such
a barrier. WMs supporting this message must set the _NET_FRAME_EXTENTS
property on the mpv window, and we receive a PropertyNotify event. If
that happens, we always continue and cancel waiting for the MapNotify
event.
I don't know if this is sane or if there's a better mechanism. Also,
this works only for WMs which support this message, which are not many.
But at least it appears to work on i3. It may reintroduce flickering on
fullscreen with other WMs, though.
When embedding a X window, it's hard to control whether it receives
mouse/keyboard input or not. It seems the X protocol itself makes this
hard (basically due to the outdated design mismatching with modern
toolkits), and we have to take care of these things explicitly.
Simply do this by manually querying and using the parent window event
flags.
This restores some MPlayer behavior (it doesn't add back exactly the
same code, but it's very similar).
This probably has some potential to interfere with libmpv embedding, so
bump the client API minor.
CC: @mpv-player/stable (if applied, client-api-changes.rst has to be
adjusted to include the 0.5.2 release)
bstr.c doesn't really deserve its own directory, and compat had just
a few files, most of which may as well be in osdep. There isn't really
any justification for these extra directories, so get rid of them.
The compat/libav.h was empty - just delete it. We changed our approach
to API compatibility, and will likely not need it anymore.
If the Xrandr configuration changes, re-read it. So if you change
display modes or screen configuration, it will update the framedrop
refresh rate accordingly.
This passes the rootwin to XRRSelectInput(), which may or may not be
allowed. But it works, and the documentation (which is worse than used
toilet paper, great job Xorg) doesn't forbid it, or in fact say anything
about what the window parameter is even used for.
This is always included in the Xorg development headers. Strictly
speaking it's not necessarily available with other X implementations,
but these are hopefully all dead.
Drop use of the ancient XF86VM, and use the slightly less ancient Xrandr
extension to retrieve the refresh rate. Xrandr has the advantage that it
supports multiple monitors (at least the modern version of it).
For now, we don't attempt any dynamic reconfiguration. We don't request
and listen to Xrandr events, and we don't notify the VO code of changes
in the refresh rate. (The later works by assuming that X coordinates map
directly to Xrandr coordinates, which probably is wrong with compositing
window manager, at least if these use complicated transformations. But I
know of no API to handle this.)
It would be nice to drop use of the Xinerama extension too, but
unfortunately, at least one EWMH feature uses Xinerama screen numbers,
and I don't know how that maps to Xrandr outputs.
This mostly uses the same idea as with vo_vdpau.c, but much simplified.
On X11, it tries to get the display framerate with XF86VM, and limits
the frequency of new video frames against it. Note that this is an old
extension, and is confirmed not to work correctly with multi-monitor
setups. But we're using it because it was already around (it is also
used by vo_vdpau).
This attempts to predict the next vsync event by using the time of the
last frame and the display FPS. Even if that goes completely wrong,
the results are still relatively good.
On other systems, or if the X11 code doesn't return a display FPS, a
framerate of 1000 is assumed. This is infinite for all practical
purposes, and means that only frames which are definitely too late are
dropped. This probably has worse results, but is still useful.
"--framedrop=yes" is basically replaced with "--framedrop=decoder". The
old framedropping mode is kept around, and should perhaps be improved.
Dropping on the decoder level is still useful if decoding itself is too
slow.
Xlib is not thread-safe. Or actually it is, but it's an incomprehensible
hack that was added later, and which needs to be acitvated manually
(this makes no sense). And it appears that the vdpau accesses X from the
decoder thread if GLX interop is used (and not in any other situations -
this doesn't make too much sense either).
So, just call the magic function that enables Xlib thread-safety.
Cast away the "extra" bits (since apparently Window/XID is always
32 bit unsigned). This is not striclty needed, because you're not
supposed to pass garbage to --wid, just because the upper bits are
possibly not interpreted. But if you do so, this change increases
consistency in behavior and removes a strange behavior that was
thought to be a bug.
Also see github issue #906.
Apparently clearing on every map can cause problems with vdpau when
switching virtual desktops and such. This was observed with at least
XMonad and nvidia-340.17. It's not observed on some other setups without
XMonad.
It's not clear why this happens. Normally, the window background is not
saved, so clearing should have no additional affect. It's a complete
mystery. Possible, the use of legacy X drawing commands (used to clear
the window) interferes with vdpau operation in non-trivial ways.
Work this around by clearing on initial map only. This probably only
hides the underlying issue, but good enough.
Closes#897.
CC: @mpv-player/stable
While I'm not very fond of "const", it's important for declarations
(it decides whether a symbol is emitted in a read-only or read/write
section). Fix all these cases, so we have writeable global data only
when we really need.
It seems we can't really get rid of this. There are no other hints to
remove decorations that work across all reasonable WMs, so we're stuck
with the ugly motif stuff.
But at least we can make the code for it less ugly.
Setting this property was added 12 years ago, and the code was always
incorrect. The underlying data type is "long", not "pid_t". It's well
possible that the data types are different, and the pointer to the pid
variable is directly passed to XChangeProperty, possibly invoking
undefined behavior.
It's funny, because in theory using pid_t for PIDs sounds more correct.
_WIN_LAYER is apparently an old GNOME thing (also explains why there is
a function vo_x11_get_gnome_layer() involved in this code). Prefer the
NetWM hints over this. This just moves the NetWM case if-body over the
_WIN_LAYER one.
You can't use identifiers starting with "_" and an uppercase letter in
application programs. They are reserved by the C standard.
Unrelated change: drop unused/misleading vo_wm_NETWM define.
I can only assume the old code was wrong. EWMH does not document
anything with _WIN_LAYER. Instead, you have to toggle the state using a
client message. We also remove these weird non-sense fallbacks, like
using _NET_WM_STATE_BELOW - what the hell?
This works around an issue in OpenBox: OpenBox apparently sizes the
normal window incorrectly if aspect ratio hints are set, and the window
size is off by 1 pixel. Then, when going fullscreen and leaving
fullscreen again, mpv sets the hints based on OpenBox' broken window
size, and as result, OpenBox sizes the window incorrectly and is off by
1 pixel again - so it's 2 pixels off in total. The error gets more
visible, the more often you toggle fullscreen mode.
Work this around by not setting the window hints if we don't need to.
Actually we only need to do this when the video is resized during
fullscreen, which happens rarely. Under normal circumstances, leaving
fullscreen mode requires that the WM restores the old state.
As such, this commit is not only a workaround, but actually a cleanup.
Note that we do need to set the hints when leaving fullscreen if the
window has resized: even though we set the hints in
vo_x11_highlevel_resize (called by vo_x11_config_vo_window), this
doesn't seem to have an effect (at least on IceWM), so we have to do it
after that.
Side note: ot seems commit 625ad57a strangely triggered the OpenBox
issue according to user reports; I'm not sure why.
Before this commit, this was somehow polled (i.e. not the right way).
Also, selects the correct window when doing --wid=0 (which is another
weird special-case).
Enabling DPMS even though you disabled it globally is pretty unfriendly,
so don't do it. Instead, we only disable DPMS if it was enabled, and
only enable it if we disabled it ourselves.
The other way should never happen (disabling DPMS permanently), unless
mpv crashes during playback.
Reduces some code-duplication.
Just call DPMSEnable/DPMSDisable, instead of DPMSForceLevel when
reenabling DPMS. "Force" sounds evil, and messing with DPMS is already
pretty evil. I'm not even sure that we should.
XGetWindowProperty is a really bad API, almost as if the NSA designed
it. The wrapper takes care of verifying the return values and handle
corner cases.
The window "gravity" influences how placement interacts with WM added
borders (i.e. from decorations). This is probably what the code removed
in commit c14721c8 was about.
In theory, we'd probably want to set the gravity depending on the
relative placement requested by the user (so that it's possible to line
up the top/left video pixel with the monitor corner, as well as the
bottom/right pixel - but that would be too complicated, and who cares
after all?).
I'm also not sure whether CenterGravity really uses the top/left corner
as reference point (instead of making coordinates relative to the window
center), but empirically it's correct.
Try to get the "new" code path (using NetWM/EWMH) free of hacks done for
the sake of old WMs or the no-WM case.
Implement --fs-screen using _NET_WM_FULLSCREEN_MONITORS.
Keeps the window centered on resize. Seems nicer. (Although it's worse
if 1. the default placement of the WM puts it into a monitor corner,
and 2. you switch to a larger video.)
It was added with 3813c685 in 2004. I'm not really sure why this gravity
stuff would be needed; apparently it has to do with misplacements with
broken WMs and had to be changed on fullscreen. Just get rid of it; it
works perfectly fine without on modern WMs.
The thread discussing this is here:
http://mplayerhq.hu/pipermail/mplayer-dev-eng/2004-July/027674.html
This should get rid of some flickering. Since this actually skips all
the wacky fullscreening code on startup, this might lead to certain
wacky features to stop working. In this case, you'll have to use the
--x11-fstype option, and disable _NETWM_STATE_FULLSCREEN usage.
vo_x11_map_window() was attempting to clear the window on map. However,
it did so immediately after the map request. It probably assumed that
the drawing calls for clearing the window would be queued along with the
map request, and then executed in the right order. However, this
assumption was wrong - the map request first has to go to the window
manager (I guess?), so a lot of things happen before the window is even
mapped.
Fix this by moving the call to the MapNotify message handler, when the
window (apparently) becomes really visible.
I also tried to set CWBackPixel to black instead, but this seemed to
result in flickering on manual resizing.
This blocks everything, until the window is actually reported as mapped.
This fixes the race condition between VO initialization and mapping the
window, which resulted in possibly different window sizes, leading to an
immediate redraw, visible as flashing.
Note that if the map event never comes for some reason, we're out of
luck and will block forever.
Fix all include statements of the form:
#include "libav.../..."
These come from MPlayer times, when FFmpeg was somehow part of the
MPlayer build tree, and this form was needed to prefer the local files
over system FFmpeg.
In some cases, the include statement wasn't needed or could be replaced
with mpv defined symbols.
There were some bad interactions with the OSC.
For one, dragging the OSC bar, and then moving the mouse outside of the
OSC (while mouse button still held) would suddenly initiate window
dragging. This was because win_drag_button1_down was not reset when
sending a normal mouse event, which means the window dragging code can
become active even after we've basically decided that the preceding
click didn't initiate window dragging.
Second, dragging the window and clicking on the OSC bar after that did
nothing. This was because no mouse button up event was sent to the core,
even though a mouse down event was sent. So make sure the key state is
erased with MP_INPUT_RELEASE_ALL.
We don't check whether the WM supports _NET_WM_MOVERESIZE_MOVE, but
if it doesn't, nothing bad happens. There might be a race condition
when pressing a button, and then moving the mouse and releasing the
button at the same time; then the WM might get the message to initiate
moving the window after the mouse button has been released, in which
case the result will probably be annoying. This could possibly be fixed
by sending _NET_WM_MOVERESIZE_CANCEL on button release, but on the
other hand, we probably won't receive a button release event in this
situation, so ignore this problem.
The dragging is initiated only when moving the mouse pointer after a
click in order to reduce annoying behavior when the user is e.g.
doubleclicking.
Closes#608.
This was done incorrectly in the previous commit: the fallback size used
the window size as requested with the first config call, which is the
size of the hidden window in the vo_opengl case. (That damn hidden
window again...)
This code essentially does nothing. As far as I could find out, this
actually used to do something. Then it was removed with commit efe7c39f,
leaving some leftover code that didn't do anything useful. This happened
12 years ago!
Also remove a commented debug printf.
vo_opengl creates a hidden X11 window to probe the OpenGL context. It
must do that before creating a visible window, because VO creation and
VO config are separate phases.
There's a race condition involving the hidden window: when starting with
--fs, and then leaving fullscreen, the unfullscreened window is
sometimes set to the aspect ratio of the hidden window. I'm not sure why
the window size itself uses the correct size (but corrupted by the wrong
aspect), but that's perhaps because the window manager is free to ignore
the size hint while honoring the aspect, or something equally messed up.
It turns out this happens because x11_common.c thinks the size of the
hidden window is the size of the unfullscreened window. This in turn
happens because vo_x11_update_geometry() reads the size of the hidden
window when called in vo_x11_fullscreen() (called from
vo_x11_config_vo_window()) when mapping the fullscreen window. At that
point, the window could be mapped, but not necessarily. If it's not
mapped, it will get the size of the unfullscreened window... I think.
One could fix this by actively waiting until the window is mapped. Try
to pick a less hacky approach instead, and never read the window size
until MapNotify is received.
vo_x11_create_window() needs a hack, because we'd possibly set the VO's
size to 0, resulting e.g. in vdpau to fail initialization. (It'll print
error messages until a proper resize is received.)
Doesn't make any sense anymore. X11 (which was mentioned in the manpage)
autodetects it, and everything else ignored the option values.
Since for incomprehensible reasons the backends and vo.c still need to
exchange information about the screensize using the option fields,
they're not removed yet.
For some reason, this made all VO backends both set the screen
resolution in opts->screenwidth/height, and call
aspect_save_screenres(). Remove the latter. Move the code to calculate
the PAR-corrected window size from aspect.c to vo.c, and make it so that
the monitor PAR is recalculated when it makes sense.
Both X11 and Wayland support the same format for drag & drop operations
(text/uri-list), and the code for that was copied from x11_common.c to
wayland_common.c. Factor it out.
Drag and drop is pretty complicated (just note how the number of Atoms
in use almost doubles), so I'm not sure whether this works everywhere.
This has been written by looking at the specification [1] or what looks
like the specification, and some external example code [2]. (The latter
one has no code license, but we didn't copy any code.)
We completely ignore the "requirement" of the spec. that the filename
"must" include username and hostname, e.g. "file://user@host/path/file".
In theory, this is required because X is network transparent, but at
this point the so called network transparency is a complete joke, and
Konqueror for one didn't include hostnames in "file://" URIs.
Tested with konqueror as drop source.
[1] http://www.newplanetsoftware.com/xdnd/
[2] http://www.edwardrosten.com/code/dist/x_clipboard-1.1/paste.cc
This reverts commit 877303aaa9.
The OpenGL 2.1 fallback for vo_opengl didn't work. Two things come
together: 1. trying to create an OpenGL 3.0 context will fail with
a GLXBadFBConfig error, and 2. X errors are fatal by default. Since
the reverted commit removed the X error handler, the mpv process was
killed, instead of continuing for the fallback.
(Note that this commit is not an exact inverse commit, since mp_msg
changed, but it does about the same thing.)
This has similar problems as the ALSA message callback, though in theory
we could use the Display handle to find the right mpv instance from the
global callback. It still wouldn't work if another library happens to
set the error handler at the same time. There doesn't seem much of an
advantage overriding the error handler (though it used to be required),
so remove it.
Since m_option.h and options.h are extremely often included, a lot of
files have to be changed.
Moving path.c/h to options/ is a bit questionable, but since this is
mainly about access to config files (which are also handled in
options/), it's probably ok.
The tmsg stuff was for the internal gettext() based translation system,
which nobody ever attempted to use and thus was removed. mp_gtext() and
set_osd_tmsg() were also for this.
mp_dbg was once enabled in debug mode only, but since we have log level
for enabling debug messages, it seems utterly useless.
This commit adds a new build system based on waf. configure and Makefile
are deprecated effective immediately and someday in the future they will be
removed (they are still available by running ./old-configure).
You can find how the choice for waf came to be in `DOCS/waf-buildsystem.rst`.
TL;DR: we couldn't get the same level of abstraction and customization with
other build systems we tried (CMake and autotools).
For guidance on how to build the software now, take a look at README.md
and the cross compilation guide.
CREDITS:
This is a squash of ~250 commits. Some of them are not by me, so here is the
deserved attribution:
- @wm4 contributed some Windows fixes, renamed configure to old-configure
and contributed to the bootstrap script. Also, GNU/Linux testing.
- @lachs0r contributed some Windows fixes and the bootstrap script.
- @Nikoli contributed a lot of testing and discovered many bugs.
- @CrimsonVoid contributed changes to the bootstrap script.
The configure followed 5 different convetions of defines because the next guy
always wanted to introduce a new better way to uniform it[1]. For an
hypothetic feature 'hurr' you could have had:
* #define HAVE_HURR 1 / #undef HAVE_DURR
* #define HAVE_HURR / #undef HAVE_DURR
* #define CONFIG_HURR 1 / #undef CONFIG_DURR
* #define HAVE_HURR 1 / #define HAVE_DURR 0
* #define CONFIG_HURR 1 / #define CONFIG_DURR 0
All is now uniform and uses:
* #define HAVE_HURR 1
* #define HAVE_DURR 0
We like definining to 0 as opposed to `undef` bcause it can help spot typos
and is very helpful when doing big reorganizations in the code.
[1]: http://xkcd.com/927/ related
As preparation for resizing the window with input commands in the
following commit.
Since there are already so many functions which somehow resize the
window, add the word "highlevel" to the name of this new function.
This stopped working when the code was changed to create a window even
if --wid is used.
It appears we can't create our own window in this case, because in X11
there is no difference between a window with the root window as parent,
and a window that is managed by the WM. So make this (kind of worthless)
special case use the root window itself.
Trying to toggle the border during fullscreen (with "cycle border")
would leave the window stuck without border, and it couldn't be
restored. This was because vo_x11_decoration() always excepted to be
called when toggling the state, and thus confusing the contents of the
olddecor variable. Add got_motif_hints to hopefully prevent this.
Also, when changing the border, don't take fs in account. May break on
older/broken WMs, but all in all is in fact more robust and simpler,
because you do not need to update the border state manually when
returning from fullscreen.
This could cause the OSC to be displayed without mouse interaction: for
example, starting mpv with --fs, and putting the mouse to where the OSC
area is beforehand, would cause the OSC to appear and stay visible. We
don't want that. The simplest solution is not generating artificial
mouse move events from mouse enter events, because they make the OSC
think the mouse was actually moved.
Also see commit 0c7978c, where handling of mouse enter events was added.
This was supposed to fix certain corner cases, but they're not relevant
anymore due to changes in OSC behavior.
Commit 9777047 fixed this as well (by resetting the mouse state on
MOUSE_LEAVE), but all the behavior reverted with this commit as perhaps
a bad idea. It wasn't very robust, made it hard to distinguish real
events from artificial ones, and finally made the mouse cursor more
often visible than needed. (Now switching between workspaces doesn't
make the cursor visible again when switching to a fullscreened mpv.)
vo_x11 had a clever trick to implement a video equalizer: it requested a
DirectColor visual. This is a X11 mechanism which allows you to specify
a lookup table for each color channel. Effectively, this is a safe
override for the graphic card's gamma ramp. If X thinks the window
deserves priority over other windows in the system, X would temporarily
switch the gamma ramp so that DirectColor visuals can be displayed as
the application intends. (I'm not sure what the exact policy is, but in
practice, this meant the equalizer worked when the mouse button was
inside the window.)
But all in all, this is just lots of useless code for a feature that is
rarely ever useful. Remove it and use the libswscale equalizer instead.
(This comes without a cost, since vo_x11 already uses libswscale.)
One worry was that using DirectColor could have made it work better in
8-bit paletted mode. But this is not the case: there's no difference,
and in both cases, the video looks equally bad.
Normally, we need this for Xutf8LookupString(). But we can just fall
back to XLookupString(). In fact, the code for this was already there,
the code was just never tested and was actually crashing when active
(see commit 2115c4a).
XOpenIM can fail to find a valid input method, in which case it
returns NULL. Passing a NULL pointer to XCreateIC would cause a
crash, so fail VO init before that happens.
This is supposed to reduce the amount of useless error messages shown
during initialization of vo_opengl. If multiple backends are compiled,
usually only one of them will work. For example, on Linux both X and
Wayland backends can be compiled, but usually either Wayland or X is
running. Then, if Wayland is not running, but X is, trying to initialize
the Wayland backend should not spam the terminal with error messages.
Signed-off-by: Andreas Sinz <andreas.sinz@aon.at>
icon_size is the number of array items of type long, not bytes. Change
the type of icon_size to int, because size_t makes you think of byte
quantities too quickly.
As an unrelated change, change the (char *) cast to (unsigned char *),
because it matches the common XChangeProperty idiom better.
The png file added to etc/ are taken from the link mentioned in commit
303096b, except that they have been converted to 16 bit, sRGB (with
color profile info dropped, if there was one), and transparent pixels
reset for better compression.
The file x11_icon.bin is generated by gen-x11-icon.sh. I'm adding it to
the git repo directly, because the script requires ImageMagick, and we
don't want to make building even more complicated.
The way how this is done is basically a compromise between effort
required in x11_common.c and in gen-x11-icon.sh. Ideally, x11_icon.bin
would be directly in the format as required by _NET_WM_ICON, but trying
to write the binary width/height values from shell would probably be a
nightmare, so here we go.
The zlib code in x11_common.c is lifted from demux_mkv.c, with some
modifications (like accepting a gzip header, because I don't know how to
make gzip write raw compressed data).
If the mpv window is unfocus, clicking on the OSC should focus the
window (done by the window manager) and allow interaction with the OSC.
But somehow X sends a spurious LeaveNotify event, immediately followed
by an EnterNotify event. This happens at least with IceWM. The result is
that the OSC will disappear (due to receiving MOUSE_LEAVE). The OSC will
stay invisible, because EnterNotify isn't handled, and there's nothing
that could make the OSC appear again.
Solve this by handling EnterNotify. We cause a redundant MOUSE_MOVE
event to be sent, which triggers the code to make the OSC visible. We
have to remove the code from input.c, which ignores redundant mouse move
events.
Since the code ignoring redundant mouse move events is still needed on
Windows, move that code to w32_common.c. The need for this is documented
in the code, also see commit 03fd2fe. (The original idea was to save
some code by having this code in the core, but now it turns out that
this didn't quite work out.)
These keys can be found on various "multimedia" and "internet" keyboard.
X defines many keycodes, so I'm not adding all, just what I found on my
own keyboard.
Other key codes can be added on request.
Disable the hack by default, because it's interfering with some more
modern WMs. MWM (Motif Window Manager) is probably pretty dead, but
we still allow enabling the old hack with "--fstype=mwm_hack".
See github issue #179.
There was a MPOpts fullscreen field, a mp_vo_opts.fs field, and
VOFLAG_FULLSCREEN. Remove all these and introduce a
mp_vo_opts.fullscreen flag instead.
When VOs receive VOCTRL_FULLSCREEN, they are supposed to set the
current fullscreen mode to the state in mp_vo_opts.fullscreen. They
also should do this implicitly on config().
VOs which are capable of doing so can update the mp_vo_opts.fullscreen
if the actual fullscreen mode changes (e.g. if the user uses the
window manager controls). If fullscreen mode switching fails, they
can also set mp_vo_opts.fullscreen to the actual state.
Note that the X11 backend does almost none of this, and it has a
private fs flag to store the fullscreen flag, instead of getting it
from the WM. (Possibly because it has to deal with broken WMs.)
The fullscreen option has to be checked on config() to deal with
the -fs option, especially with something like:
mpv --fs file1.mkv --{ --no-fs file2.mkv --}
(It should start in fullscreen mode, but go to windowed mode when
playing file2.mkv.)
Wayland changes by: Alexander Preisinger <alexander.preisinger@gmail.com>
Cocoa changes by: Stefano Pigozzi <stefano.pigozzi@gmail.com>
Making key up events implicit was sort-of a nice idea, but it's too
tricky and unreliable and makes the key lookup code (interpret_keys())
hard to reason about. See e.g. previous commit for subtle bugs and
issues this caused.
Make key-up events explicit instead. Add key up events to all VOs.
Any time MP_KEY_STATE_DOWN is used, the matching key up event must
use MP_KEY_STATE_UP.
Rewrite the key lookup code. It should be simpler and more robust now.
(Even though the LOC increases, because the new code is less "compact".)
Also, implement mouse leave events for X11. But evne on other
platforms, these events will be generated if mouse crosses a section's
mouse area boundaries within the mpv window.
Instead of implicitly changing the window title on config(), do it as
part of the new VOCTRL.
At first I wanted to make all VOs use the VOCTRL argument directly, but
on a second thought it appears vo_get_window_title() is much more useful
for some (namely, if the window is created lazily on first config()).
Not all VOs are changed. Wayland and OSX have to follow.
Use the recently introduced screensaver VOCTRLs to control the
screensaver in the X11 backend. This means the behavior when paused
changes: the old code always kept the screensaver disabled, but now the
screensaver is reenabled on pausing.
Rename the --stop-xscreensaver option to --stop-screensaver and make it
more generic. Now it affects all backends that respond to the
screensaver VOCTRLs.
GetTimer() is generally replaced with mp_time_us(). Both calls return
microseconds, but the latter uses int64_t, us defined to never wrap,
and never returns 0 or negative values.
GetTimerMS() has no direct replacement. Instead the other functions are
used.
For some code, switch to mp_time_sec(), which returns the time as double
float value in seconds. The returned time is offset to program start
time, so there is enough precision left to deliver microsecond
resolution for at least 100 years. Unless it's casted to a float
(or the CPU reduces precision), which is why we still use mp_time_us()
out of paranoia in places where precision is clearly needed.
Always switch to the correct time. The whole point of the new timer
calls is that they don't wrap, and storing microseconds in unsigned int
variables would negate this.
In some cases, remove wrap-around handling for time values.
Instead of having separate callbacks for each backend-handled feature
(like MPGLContext.fullscreen, MPGLContext.border, etc.), pass the
VOCTRL responsible for this directly to the backend. This allows
removing a bunch of callbacks, that currently must be set even for
optional/lesser features (like VOCTRL_BORDER).
This requires changes to all VOs using gl_common, as well as all
backends that support gl_common.
Also introduce VOCTRL_CHECK_EVENTS. vo.check_events is now optional.
VO backends can use VOCTRL_CHECK_EVENTS instead to implementing
check_events. This has the advantage that the event handling code in
VOs doesn't have to be duplicated if vo_control() is used.
Block X11's native key repeat, and use mpv's key repeat handling in
input.c instead.
No configure check for XKB. Even though it's an extension, it has been
part of most (all?) xlibs since 1996. If XKB appears to be missing,
just refuse enabling x11.
This is a potentially controversial change. mpv will use its own key
repeat rate, instead of X11's. This should be better, because seeking
will have a standardized "speed" (seek events per seconds when keeping
a seek key held down). It will also allow disabling key repears for
certain commands, though this is not done anywhere yet.
The new behavior can be disabled with the --native-keyrepeat option.
The vo_x11_clearwindow_part() function assumed that the video is always
centered. Replace it with a new vo_x11_clear_background() function
instead, which essentially does the same as the old function. It takes
the video rectangle instead of just the video size, and doesn't have to
make the assumption that the video rectangle is centered.
Also make vo_x11 use it (seems advantageous).
Separate the video output options from the big MPOpts structure and also only
pass the new mp_vo_opts structure to the vo backend.
Move video_driver_list into mp_vo_opts
Removes almost every global variabel in vo.h and puts them in a special struct
in MPOpts for video output related options.
Also we completly remove the options/globals pts and refresh rate because
they were unused.
When paused, --cursor-autohide worked with a precision of 500ms, which
is the main loop's default sleep time when paused. Cursor hiding is
polled in x11_common, and the main loop never called the X11 code at
the right time. Fix this by allowing the VO to set a time when it
should be called next.
vo_opengl creates an invisible window with VOFLAG_HIDDEN in order to
test whether the OpenGL context is useable. The visible window is
created at a later point. This has been broken forever (in vo_gl,
now called vo_opengl_old, it could be avoided by disabling auto-
detection explicitly using the "yuv" sub-option). Avoiding
VOFLAG_HIDDEN only mitigates the issue, and a related bug can still
happen with some window managers (see below).
As a hack, code was added to vo_gl to destroy the (hidden) window so
that all state was destroyed. Later, more hacks were added to deal with
some caveats that came with recreating the window, such as probing for
the context up to 4 times.
Attempt to fix the problem properly. There were two problems: first,
the window was not resized to video size before mapping. This was the
main cause for the placement issue, e.g. mapping the window as 320x200,
and then resizing it. Second, mpv tried to force the window position
with XSetWMNormalHints and PPosition with values it just read with
XGetGeometry. This messes up the window manager's default placement.
It seems to be a race condition, and behavior is different across
various WMs too: with IceWM, the window manager's placement is usually
preferred, and with Fluxbox, mpv's position is preferred. mpv's default
position is centering the window on the screen, which is much nicer for
video in general than typical WM default placement, so it's possible
that this bug was perceived as a feature. (Users who want this have to
use --geometry="50%:50%", doing this by default is probably not safe
with all WMs.)
Since the old code was hard to follow and full of issues, it's easier
to redo it. Move general window creation stuff out of the
vo_x11_config_vo_window function, and move the resize logic into it.
This has been tested on IcwWM, Fluxbox, awesome, Unity/Compiz.
Store the window state (position and size) in vo_x11_state, instead of
in vo->dx/dy/dwidth/dheight. The VO variables are overwritten by vo.c on
every vo_config() call, which is extremely not helpful.
Now vo->dx/dy are mostly unused (except for passing the position forced
by the --geometry option), and vo->dwidth/dheight are set for the VO,
and otherwise read for resize detection only.
In the long term, the way vo_config() handles the --geometry option
should be changed, and vo->dx/dy should be removed.
Remove some useless stuff: VO_EVENT_MOVE and VO_EVENT_KEYPRESS were
generated, but unused. Wayland changes by Alexander Preisinger.
This allowed making the player switch the monitor video mode when
creating the video window. This was a questionable feature, and with
today's LCD screens certainly not useful anymore. Switching to a random
video mode (going by video width/height) doesn't sound too useful
either.
I'm not sure about the win32 implementation, but the X part had several
bugs. Even in mplayer-svn (where x11_common.c hasn't been receiving any
larger changes for a long time), this code is buggy and doesn't do the
right thing anyway. (And what the hell _did_ it do when using multiple
physical monitors?)
If you really want this, write a shell script that calls xrandr before
and after calling mpv.
vo_sdl still can do mode switching, because SDL has native support for
it, and using it is trivial. Add a new sub-option for this.
The --wid switch (for embedding the player into other applications)
didn't create a new window, and instead tried to use the window that
was passed via --wid directly. This made the code more complex, caused
strange X errors (mpv and host application fighting for exclusive X
resources), and actually could cause issues if the --wid window wasn't
created with the X Visual needed for OpenGL.
Always create a window instead. This makes it always possible to embed
the player into foreign windows. --geometry doesn't work anymore - the
controlling application should always create a new window to place the
player inside it, and can control the video window by moving and
resizing this window.
w32_common.c actually did this right, and always creates a new window.
create_window is really bad naming, because this function can be called
multiple times, while the name implies that it always creates a new
window. At least the name config_window is not actively misleading.
You can just use --wid=0 if you really want this.
This only worked/works for X11, and even then it might interact badly
with most desktop environments. All the option did was setting --wid to
0, and the property did nothing.
`--fs-screen` allows to decide what display to go fullscreen into. The
semantics of `--screen` changed and now it is only used to select the windowed
display when starting the application.
This is useful for people using mpv with an external TV. They will start
windowed on their laptop's screen and switch to fullscreen on the TV.
@wm4 worked on the x11 and w32 parts of the code. All is squashed in one
commit for history clarity.
Also some other cosmetic changes. And reformat the two remaining doxygen
comments.
Removing MSGLEN in x11_errorhandler() is technically not just a cosmetic
change, but the result is the same anyway.