This is the first of a series of commits that will change the Cocoa way in a
way that is easily embeddable inside parent views. To reach that point common
code must avoid referencing the parent NSWindow since that could be the host
application's window.
This is just temporary code but is a good base for future work (and baby
steps are required for these changes). The 'final destination' is embedding
the video view into any NSView but that requires some more work (the mechanism
will be the same: pass the view's pointer casted to int64_t through -wid).
For instance we will need to remove as much usage of the window instance
as possible, and use nil guards where not possible. For this reason I will
remove stuff like the mission control fullscreen feature (it's a cute feature
but annoying to support and quite limited, go make your GUIs), and a way to
lookup the current screen directly from the NSView absolute coordinates
(this is needed for ICC detection mostly, and reporting back the screen to
mpv's core).
Moreover the current view.m will need to be separated into 2 views: the actual
video view that will be embedded, and a parent view that will not be embedded
and will be responsibile for tracking events.
This could be dangerous because we initialize the window asynchronously and
return immediately from config, but since the OpenGL context is already
created, this seems to work correctly and doesn't cause weird deadlock cases.
This doesn't look to be needed anymore. Fullscreening with both the NSView
and the NSWindow API works correctly. I guess this was forgotten in from older
code which changed presentation options directly for going fullscreen.
Unfortunately using dispatch_sync for synchronization turned out to be really
bad for us. It caused a wide array of race conditions, deadlocks, etc.
Moving to a very simple mutex. It's not clear to me how to do liveresizing
with this, for now it just flickers with is unacceptable (maybe I'll draw
black instead).
This should fix all the threading cocoa bugs. Reopen if it's not the case!
Fixes#751Fixes#1129
This approach is similar to what other vo_opengl backends do. It can also be
used in the future to create another cocoa backend that renders offscreen
with IOSurfaces or FBOs.
Not all the hardware supports kCGLPFASupportsAutomaticGraphicsSwitching
(apparently all Mid-2010 and before MacBooks do not work with it), so fallback
to not asking for this attribute in the GL pixel format.
This extracts the scheduling logic to a single function which is nicer to keep
it consistent.
Additionally make sure we don't schedule sync operations from a sync operation
itself since that could cause deadlocks (even if it should not be happening
with the current code).
This fixes a couple of issues with the Cocoa `--native-fs` mode, primarily:
- A ghost titlebar at the top of the screen in full screen:
This was caused by the window constraining code kicking in during
fullscreen. Simply returning the unconstrained rect from the constraining
method fixes the problem.
- Incorrect behavior when using the titlebar buttons to enter/exit
fullscreen, as opposed to the OSD button.
This was caused by mpv's internal fullscreen state going out of sync with
the NSWindow's one. This was the case because `toggleFullScreen:`
completely bypassed the normal event flow that mpv expects.
Signed-off-by: Ryan Goulden <percontation@gmail.com>
Change style for mpv, simplify and refactor some of the constraining code.
Signed-off-by: Stefano Pigozzi <stefano.pigozzi@gmail.com>
This commit adds support for automatic selection of color profiles based on
the display where mpv is initialized, and automatically changes the color
profile when display is changed or the profile itself is changed from
System Preferences.
@UliZappe was responsible with the testing and implementation of a lot of this
commit, including the original implementation of `cocoa_get_icc_profile_path`
(See #594).
Fixes#594
Rename vo_get_src_dst_rects() to mp_get_src_dst_rects() and make it
independent from the VO (it takes a comical amount of parameters now to
pass all required state). Add a convenience wrapper with the name
vo_get_src_dst_rects() to vo.c. Replace all aspdat and vo usages with
immediate parameters.
Functionally, nothing should change, except that the window size is
clamped to a minimum of size 1 much earlier, and some log messages
change the prefix (don't bother with vo.vo_log stuff).
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.
For a long time the cocoa backend set the xinerama_x/y and used dx/dy from the
VO instance. This somewhat worked with some workarounds but wasn't really
what was supposed to be happening. Moreover 27e4360, which touched this
workaround introduced a regression.
New code doesn't set the xinerama_x/y values so that dx/dy are offsets in the
current screen (not a virtual screen composed of all the screens). The screen
reference detected during VOCTRL_UPDATE_SCREENINFO is also passed down to the
window initialization code.
Fixes#472
If the utf8 string used to create the NSString for title was invalid utf8,
-stringWithUTF8String returned nil and triggered an assertion in Cocoa's
framework code.
Sanitize the utf8 string and if the sanitation wasn't enough just avoid
crashing by not setting a title.
Fixes#406
The code did not set and unset the current context inside sync sections. I am
not sure if this was an actual problem but this is better since the context is
linked to a single thread. In my brief tests this seems to avoid garbage to
show up in fullscreen.
This only shows any differences when mpv isn't frontmost and is in fullscreen.
Cmd+Tab overlay is still at a higher level as to avoid complete usability fail.
After rebasing my dev branch it turned out that the code deadlocked on
recursive calls of `vo_control`. Make the locking code a little bit smarter
by making always skip locking/unlocking if we are executing a chunck of
code that is already synchronized with `dispatch_sync`.
Split the code to several files. The GUI elements now each have they own files
and private state. The original code was a mess to respect the retarded mplayer
convention of having everything in a single file.
This commit also seems to fix the long running bug of artifacts showing
randomly when going fullscreen using nVidia GPUs.
This is mainly to avoid spurious cursor states due to the mouse moving inside
or outside the window as a result of the window resize (with cmd-0/1/2).
This avoids complex logic and triggers a mouse move so that the player
recomputes the correct cursor state based on the autohide configuration of
the user.
This keeps the state in sync with the current state in cocoa_common. Infact the
cocoa code in mpv can decide wether it really wants to hide the cursor based on
the result of the `canHideCursor` method (this is so that the cursor is only
hidden when hovering on the video window).
This is mostly related to the fullscreen behaviour. cecbd8864 introduces an
option to make mpv behave like a OSX user would expect. This commit changes
the Cocoa parts of the code to be consistent with the behaviour on X11. Old
behaviour is still available through the option mentioned in cecbd8864.
There is still custom logic in the cocoa backend and it can probably be moved
to core:
* Don't perform autohide if the mouse is down
* Don't perform autohide outside of the video window
Fixes#218 (by accident)
Generate a mouse down event on the first click so that one can interact
with the OSC directly as opposed to wasting the first click in order to focus
the window.
cocoa_common contains some locking calls to support video outputs that support
live resizing (at this moment only vo=opengl).
These should not be used unless the VO declares it is multithreaded by
registering the resize_redraw callback used for live resizing.
Fixes#200
Regression since ff3b98d11c. The window positioning code relied on the
visibleFrame's height without taking into account the dock's presence.
Also moved the constraining code to the proper method that overrides the
original NSWindow behaviour. This avoids having to check for border since the
constraining is performed by Cocoa only for titled windows.
Fixes#190
This adds precise scrolling support. I ran some tests and it seems a little
bit smoother and well.. precise. The defaults are rebindable using: AXIS_UP,
AXIS_DOWN, AXIS_LEFT and AXIS_RIGHT.
This introduces some changes in resize behaviour. Most importantly the window
frame is not constrained to it's screen's `visibleFrame`. Anyone who still wants
that kind of behaviour when opening a video, can use `--autofit-larger`.
Even though the size of the window is not constrained, it's position is, so
that the titlebar will always be visible. When using `--no-border` even the
position will not be constrained in any way.
This change which also flipse the coordinate system of the view, greatly
simplifies the mouse event handling code.
There are still some uglities mostly related to the cursor visibility
code. For instance the core doesn't show the cursor when it receives a mouse
leave event.
This was more roundabout than expected, since it looks like the framework
caches isMovabileByWindowBackground so in mpv's case it's needed to set it
with setMovableByWindowBackground.
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".)
A redraw forces recalculation of panscan and other stuff not accounted for in
the resize_redraw codepath. This is actually a hack but works really well in
my tests.
Thanks @wm4 and @Cpuroast for the idea.
Fixes#86
[ci skip]
Recent work in the OS X parts of the code started using clang's support for
Obj-C's support for Literals and Subscripting. These particular language
features remove a lot of boilerplate code and allow to interact with
collections as consicely as one would do in scripting languages like Ruby or
Python.
Even if these are compiler features, Subscripting needs some runtime support.
This is provided with libarclite (coming with the compiler), but we need to
add the proper method definitions since the 10.7 SDK headers do not include
them. That is because 10.7 shipped before this language features.
This will cause some warnings when compiling with the 10.7 SDK because the
commit also redefines BOOL to make autoboxing/unboxing of BOOL literals to
work.
If you need to test this for whatever reason on 10.8, just pass in the correct
SDK to configure's extra cflags:
./configure --extra-cflags='-mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk'
Fixes#117
This is slightly better because VOCTRL_RESUME/VOCTRL_PAUSE are usually
needed by VOs to know whether video is actually being played (for
whatever reason), and they wouldn't be passed to the backend's VOCTRL
handler, like vo_x11_control().
Also try to make sure that these flags (both pause state and screensaver
state) are set consistently in some corner cases. For example, it seems
enabling video in the middle of playing a file while the player is
paused would not set the paused flag.
If codec initialization fails, destroy the VO instead of keeping it
around to make sure the state is consistent.
Framestepping is implemented by unpausing the player for the duration of
a frame. Remove the special handling of VOCTRL_PAUSE/RESUME in these
cases. It was most likely needed because these VOCTRLs used to be
important for screen redrawing (blatant guess), which is now handled
completely differently. The only potentially bad side-effect is that the
screensaver will be disabled/reenabled for the duration of one frame.
`enterFullScreenMode:withOptions:` creates another window so set the level on
both the windowed window and current window.
Also remove NSFullScreenModeWindowLevel as it seems to be superfluous.
Now that Cocoa's input handling is done on a separate thread from the playloop
it is ridicolously simple to have longer asynchronous sleeps when paused.
On OSX with Cocoa enabled keyDown events are now handled with
addLocalMonitorForEventsMatchingMask:handler:. This allows to respond to
events even when there is no VO initialized but the GUI is focused.
Autohide the menubar and/or dock only if they are present in the screen the
player is going to go fullscreen into. I thought the GUI would handle this for
me when I switched 0057aa476 but lack of hardware to test made me embarass
myself yet again.
I reimplemented this feature with nicer code and behaviour. The code checks
separately wether to hide menubar and dock separatly, while the old code used
a single check possibly hiding stuff without need.
Added the key checks as a some category additions to NSScreen for readability.
This takes an approach similar to the wayland OpenGL backend. VOFLAG_HIDDEN
flag semantics doesn't mean "hide the window" but is simply ever used only to
do detection of available OpenGL extensions. On OSX it's possibile to
accomplish this task just by creating the OpenGL context without attaching
it to a drawable.
Using `enterFullScreenMode:withOptions:` with a screen handle than the current
screen doesn't hide the current window in the current screen. This is a bug in
Cocoa (preparing an isolated test case and sending the rdar later).
To work around this, manually hide/show the window that the toolkit should
hide/show for us.
This bug was the result of crappy position detection in the previous code
combined with the commits moving autohide delay out of the cocoa backend and
into the core.
The hit detection was improved and now takes also account of interactions with
the Dock and Menubar. Moreover VOCTRL_SET_CURSOR_VISIBILITY now has an effect
only if the mouse position matches with this improved hit detection. This means
that both interaction with the Dock and Menubar are considered as well as
moving the mouse inside another screen.
This removes a bit of ugly code and bookeeping which is never bad. `drawRect`
needs to guard against different window instances since in fullscreen the view
is wrapped in a fullscreen window provided by the toolkit (a instance of
NSFullScreenWindow to be precise).
The event handling was moved to the view so that it can still get all the
events when in the fullscreen window. Ideally these should be moved to
some NSResponder subclass within macosx_application and made available even
when no window is present. I refrained from this because "small steps".
At this point 10.6 is pretty old and we don't want to supporting old platforms.
I'm killing all the 10.6 compatibility code before doing more refactorings.
Next commits will also use newer Objective-C syntax such as literals and
@autoreleasepool.