If the window is maximized, we can't change the size immediately. In
that case, we set a bool and wait for the state to change before
triggering the resize.
I'm tired of dealing with this frequent spawning of xdg-screensaver when
debugging and what not. xdg-screensaver was never a serious tool anyway,
it's more like some self-deprecating joke by FDO folks.
This will affect X11 on GNOME and other DEs. I'm singling out GNOME
though, because they are the ones actively sabotaging any sane
technical solutions and community cooperation.
I have been accused of taking it out on innocent GNOME users, while none
of this will reach GNOME developers. Of course that is not the
intention.
- remove VOCTRL_FULLSCREEN and VOCTRL_GET_FULLSCREEN
- have your own m_config_cache for the fullscreen option
(vo->opts_cache cannot be used because you lose per-option change
notifications, and it'd be a mess anyway)
- use VOCTRL_VO_OPTS_CHANGED to update it
(it's used for convenience)
- when updating it, check for the fullscreen option
(wasn't sure how to do it best; currently, it compares the raw
option pointers, but this could be changed)
- do not send VO_EVENT_FULLSCREEN_STATE on FS change
- instead write the option on FS change
(assign in opt. struct + m_config_cache_write_opt)
Use x11->opts instead of vo->opts. This doesn't matter currently, and
x11->opts is actually set to vo->opts. However, there's a chance that
either option access changes, or that the way backends integrate with
struct vo changes. This is just a preemptive change to make this less of
a mess, and it's generally a good idea to reduce accesses to struct vo
anyway.
To find the correct ICC profile X atom, the screen number was calculated
directly from the xrandr order of the screens.
But if a primary screen is set, it should be the first Xinerama screen,
even if it is not the first xrandr screen.
Calculate the the proper atom id for each screen.
Regression from 8e3308d687.
Broken cases were:
* --no-cursor-autohide acted like --cursor-autohide=always.
* --cursor-autohide-fs-only always hid the cursor if starting
non-fullscreen; entering fullscreen at least once fixed it.
This should actually cover all of them, if you take into account that
some unchanged GPL source files include header files with such checks.
Also this was done already for the libaf derived code.
This is only for "safety" and to avoid misunderstandings.
Scale the window by the assumed DPI scaling factor, using 96 DPI as
base. For example, a screen that reports 192 DPI is assumed to have a
DPI scale factor 2. The window will then be created with twice the size.
For robustness reasons, we accept only integer DPI scales between 1 and
9. We also error out if the X and Y scales are very different, as this
most likely indicates a multiscreen system with botched size reporting.
I'm not sure if reading the X server's DPI is such a good idea - maybe
the Xrdb "Xft.dpi" value should be used instead. The current method
follows what xdpyinfo does.
This can be disabled with --hidpi-window-scale=no.
So that the EGL code can use it too.
Also print the actual FB config ID, instead of nonsense. (I _think_ once
in the past a certain GLX implementation just used numeric config IDs
casted to EGLConfig - or at least that would explain this nonsense.)
It seems vo_x11_check_events() was supposed to return the currently
flagged events and reset them. But there are many places where
vo_x11_check_events() is called without checking its return value. This
could lead to forgotten events.
Change the code such that they can't get lost.
Don't just cause vo_opengl to update the ICC profile every time the
window is moved. Instead, explicitly check if the screen was changed.
Mostly untested.
Reduces VO access and makes the code more self-contained. (One day the
windowing backend code should not access the VO anymore. We're just not
quite there yet.)
It always was a weird artifact - VOCTRLs are meant _not_ to require
special handling in the code that passes them through (like in vo.c).
Removing it is also interesting to further reduce the dependency of
backends on struct vo. Just get rid of it.
Removing it is somewhat inconvenient, because in many situations the UI
window is created after the first VOCTRL_UPDATE_WINDOW_TITLE. This means
these backends have to store it in a new field in their own context.
glXCreateContextAttribsARB() by design can throw some X11 errors. We
ignore these, but we generally still print error messages to the
terminal. This was confusing/annoying users, so silence it. The stupid
part is that the Xlib error handler is global, so we have to be slightly
careful here.
This gets rid of an old hack, VOFLAG_HIDDEN. Although handling of it has
been sane for a while, it used to cause much pain, and is still
unintuitive and weird even today.
The main reason for this hack is that OpenGL selects a X11 Visual for
you, and you're supposed to use this Visual when creating the X window
for the OpenGL context. Which means the X window can't be created early
in the common X11 init code, but the OpenGL code needs to do something
before that. API-wise you need separate functions for X11 init and X11
window creation. The VOFLAG_HIDDEN hack conflated window creation and
the entrypoint for resizing on video resolution change into one
function, vo_x11_config_vo_window(). This required all platform backends
to handle this flag, even if they didn't need this mechanism.
Wayland still uses this for minor reasons (alpha support?), so the
wayland backend must be changed before the flag can be entirely removed.
If the drag and drop action is anything other than
XdndActionCopy, append the dropped files rather than
replacing the existing playlist. With most file managers,
this will mean at least pressing shift while dropping.
Less code, and avoids a black flash on start.
In theory it could happen that we map the window, and then don't have a
frame to draw - but mapping the window is done in the exact moment we
have a new frame to display.
It sometimes happens on exit, and it's probably a bad idea. If the
process hangs on exit (possibly due to stupid hardcoded timeouts it's
doing), mpv will also hang now, unfortunately.
We already use 2 screensaver APIs when attempting to disable the
screensaver: XResetScreenSaver() (from xlib) and XScreenSaverSuspend
(from the X11 Screen Saver extension). None of these actually work.
On modern desktop Linux, we are expected to make dbus calls using some
freedesktop-defined protocol (and possibly we'd have to fallback to a
Gnome specific one). At least xscreensaver doesn't respect the "old"
APIs either.
Solve this by running the xdg-screensaver script. It's a terrible, ugly
piece of shit (just read the script if you disagree), but at least it
appears to work everywhere. It's also simpler than involving various
dbus client libraries.
I hope this can replace the --heartbeat-cmd option, and maybe we could
remove our own DPMS/XSS code too.
This queries the _ICC_PROFILE property on the root window. It also tries
to reload the ICC when it changes, or if the mpv window changes the
monitor. (If multiple monitors are covered, mpv will randomly select one
of them.)
The official spec is a dead link on freedesktop.org, so don't blame me
for any bugs.
Note that this assumes that Xinerama screen numbers match the way mpv
enumerates the xrandr monitors. Although there is some chance that this
matches, it most likely doesn't, and we actually have to do complicated
things to map the screen numbers. If it turns out that this is required,
I will fix it as soon as someone with a suitable setup for testing the
fix reports it.
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.
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.
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.
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.
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.
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.
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
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.
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