diff mbox

Fixes fullscreen aspect ratio and leaving fullscreen mode problem on Mac OS X

Message ID B85DFDA4-86C4-41AE-9389-91E6050D1962@gmail.com
State New
Headers show

Commit Message

Programmingkid Dec. 30, 2014, 4:17 a.m. UTC
This patch fixes these problems for QEMU on Mac OS X:
- fullscreen mode not having the correct aspect ratio
- the inability to leave fullscreen mode

signed-off-by: John Arbuckle <programmingkidx@gmail.com>

From 5baa57950e03ed18afbb63b4b500bbde95baad5c Mon Sep 17 00:00:00 2001
From: John Arbuckle <programmingkidx@gmail.com>
Date: Mon, 29 Dec 2014 22:47:56 -0500
Subject: [PATCH] Fixes fullscreen aspect ratio and leaving fullscreen mode
 problem.

signed-off-by: John Arbuckle <programmingkidx@gmail.com>

---
 configure  |    2 +-
 ui/cocoa.m |   19 +++++++++++++++++--
 2 files changed, 18 insertions(+), 3 deletions(-)

Comments

Peter Maydell Dec. 31, 2014, 11:19 p.m. UTC | #1
On 30 December 2014 at 04:17, Programmingkid <programmingkidx@gmail.com> wrote:
> This patch fixes these problems for QEMU on Mac OS X:
> - fullscreen mode not having the correct aspect ratio
> - the inability to leave fullscreen mode
>
> signed-off-by: John Arbuckle <programmingkidx@gmail.com>

So how do you get into full screen mode in the first place?
For me, the View->Enter Full Screen menu item is always greyed
out, both before and after this patch...

(This is with OSX 10.9.5; I tried both an x86_64 image
and an ARM one.)

-- PMM
Peter Maydell Jan. 1, 2015, 2:55 p.m. UTC | #2
On 30 December 2014 at 04:17, Programmingkid <programmingkidx@gmail.com> wrote:
> This patch fixes these problems for QEMU on Mac OS X:
> - fullscreen mode not having the correct aspect ratio

What is the bug being fixed here? For me on 10.9.5 the fullscreen
behaviour is the same with or without this patch: the fullscreen
window is of the same size as the non-fullscreened version, with
a plain background behind it, so there's no aspect ratio issue.
I'm guessing that 10.6 behaved differently (the Lion fullscreen
changes were pretty drastic).

> - the inability to leave fullscreen mode
>
> signed-off-by: John Arbuckle <programmingkidx@gmail.com>

This patch provokes a bunch of deprecation warnings:
  OBJC  ui/cocoa.o
/Users/pm215/src/qemu/ui/cocoa.m:490:25: warning:
'CGDisplayCurrentMode' is deprecated: first deprecated in OS X 10.6
[-Wdeprecated-declarations]
        original_mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
                        ^
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:455:27:
note: 'CGDisplayCurrentMode' has been explicitly marked deprecated
here
CG_EXTERN CFDictionaryRef CGDisplayCurrentMode(CGDirectDisplayID display)
                          ^
/Users/pm215/src/qemu/ui/cocoa.m:494:13: warning:
'CGDisplaySwitchToMode' is deprecated: first deprecated in OS X 10.6
[-Wdeprecated-declarations]
            CGDisplaySwitchToMode(kCGDirectMainDisplay, original_mode);
            ^
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:460:19:
note: 'CGDisplaySwitchToMode' has been explicitly marked deprecated
here
CG_EXTERN CGError CGDisplaySwitchToMode(CGDirectDisplayID display,
                  ^
/Users/pm215/src/qemu/ui/cocoa.m:515:32: warning:
'CGDisplayBestModeForParameters' is deprecated: first deprecated in OS
X 10.6 [-Wdeprecated-declarations]
        CFDictionaryRef mode =
CGDisplayBestModeForParameters(kCGDirectMainDisplay,
desired_bit_depth, cw, ch, &exact_match);
                               ^
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:442:27:
note: 'CGDisplayBestModeForParameters' has been explicitly marked
deprecated here
CG_EXTERN CFDictionaryRef CGDisplayBestModeForParameters(CGDirectDisplayID
                          ^
/Users/pm215/src/qemu/ui/cocoa.m:517:13: warning:
'CGDisplaySwitchToMode' is deprecated: first deprecated in OS X 10.6
[-Wdeprecated-declarations]
            CGDisplaySwitchToMode(kCGDirectMainDisplay, mode);
            ^
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:460:19:
note: 'CGDisplaySwitchToMode' has been explicitly marked deprecated
here
CG_EXTERN CGError CGDisplaySwitchToMode(CGDirectDisplayID display,
                  ^
4 warnings generated.

which suggests we need a pre-10.6 codepath and a post-10.6 one
(unless we decide to trust that Apple will never ever delete
a deprecated API and turn off the warnings, which seems kinda
risky to me).

We also seem to need some 10.7-or-later code: I need at least
this patch to get fullscreen enabled at all:

@@ -833,6 +835,9 @@ QemuCocoaView *cocoaView;
         [normalWindow makeKeyAndOrderFront:self];
         [normalWindow center];

+        [normalWindow setCollectionBehavior:
+                        NSWindowCollectionBehaviorFullScreenPrimary];
+
     }
     return self;
 }

(that probably needs to be guarded with "if 10.7 or later" ifdefs).

and there are other problems with fullscreen still -- for instance
if you fullscreen the window before the guest changes its
resolution and then unfullscreen it afterwards, we forget about
the fact the resolution changed and revert to the pre-change size.

Another oddity: on fullscreening, the window's titlebar remains
visible, up until the point where the guest changes its screen
resolution, at which point it disappears. I'm guessing we shouldn't
display it at all in fullscreen.

I need to check whether we get the mouse coordinates right in
fullscreen mode, given that the window doesn't actually cover
the whole screen area.

If we're allowing mouse-ungrab in fullscreen mode, maybe we
should remove the "if (!isFullscreen)" guard from the code that
updates the window title with the "Press ctrl + alt to release
mouse" string? Slightly academic, though, since by definition
you can't read it if we're fullscreen...

thanks
-- PMM
Programmingkid Jan. 1, 2015, 4:05 p.m. UTC | #3
On Jan 1, 2015, at 9:55 AM, Peter Maydell wrote:

> On 30 December 2014 at 04:17, Programmingkid <programmingkidx@gmail.com> wrote:
>> This patch fixes these problems for QEMU on Mac OS X:
>> - fullscreen mode not having the correct aspect ratio
> 
> What is the bug being fixed here? For me on 10.9.5 the fullscreen
> behaviour is the same with or without this patch: the fullscreen
> window is of the same size as the non-fullscreened version, with
> a plain background behind it, so there's no aspect ratio issue.
> I'm guessing that 10.6 behaved differently (the Lion fullscreen
> changes were pretty drastic).

When you look at the openbios prompt in full screen mode, you can see the text is all messed up looking. That is because the aspect ratio isn't being preserved. 

Bad aspect ratio. The letters here are stretched out.
Correct aspect ratio. You can notice that the letters here look sharper.
I took these pictures using qemu-system-ppc. 


> 
>> - the inability to leave fullscreen mode
>> 
>> signed-off-by: John Arbuckle <programmingkidx@gmail.com>
> 
> This patch provokes a bunch of deprecation warnings:
>  OBJC  ui/cocoa.o
> /Users/pm215/src/qemu/ui/cocoa.m:490:25: warning:
> 'CGDisplayCurrentMode' is deprecated: first deprecated in OS X 10.6
> [-Wdeprecated-declarations]
>        original_mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
>                        ^
> /System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:455:27:
> note: 'CGDisplayCurrentMode' has been explicitly marked deprecated
> here
> CG_EXTERN CFDictionaryRef CGDisplayCurrentMode(CGDirectDisplayID display)
>                          ^
> /Users/pm215/src/qemu/ui/cocoa.m:494:13: warning:
> 'CGDisplaySwitchToMode' is deprecated: first deprecated in OS X 10.6
> [-Wdeprecated-declarations]
>            CGDisplaySwitchToMode(kCGDirectMainDisplay, original_mode);
>            ^
> /System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:460:19:
> note: 'CGDisplaySwitchToMode' has been explicitly marked deprecated
> here
> CG_EXTERN CGError CGDisplaySwitchToMode(CGDirectDisplayID display,
>                  ^
> /Users/pm215/src/qemu/ui/cocoa.m:515:32: warning:
> 'CGDisplayBestModeForParameters' is deprecated: first deprecated in OS
> X 10.6 [-Wdeprecated-declarations]
>        CFDictionaryRef mode =
> CGDisplayBestModeForParameters(kCGDirectMainDisplay,
> desired_bit_depth, cw, ch, &exact_match);
>                               ^
> /System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:442:27:
> note: 'CGDisplayBestModeForParameters' has been explicitly marked
> deprecated here
> CG_EXTERN CFDictionaryRef CGDisplayBestModeForParameters(CGDirectDisplayID
>                          ^
> /Users/pm215/src/qemu/ui/cocoa.m:517:13: warning:
> 'CGDisplaySwitchToMode' is deprecated: first deprecated in OS X 10.6
> [-Wdeprecated-declarations]
>            CGDisplaySwitchToMode(kCGDirectMainDisplay, mode);
>            ^
> /System/Library/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:460:19:
> note: 'CGDisplaySwitchToMode' has been explicitly marked deprecated
> here
> CG_EXTERN CGError CGDisplaySwitchToMode(CGDirectDisplayID display,
>                  ^
> 4 warnings generated.
> 
> which suggests we need a pre-10.6 codepath and a post-10.6 one
> (unless we decide to trust that Apple will never ever delete
> a deprecated API and turn off the warnings, which seems kinda
> risky to me).

Ok, I will fix this problem. Your idea of pre and post 10.6 code will be implemented.

> 
> We also seem to need some 10.7-or-later code: I need at least
> this patch to get fullscreen enabled at all:
> 
> @@ -833,6 +835,9 @@ QemuCocoaView *cocoaView;
>         [normalWindow makeKeyAndOrderFront:self];
>         [normalWindow center];
> 
> +        [normalWindow setCollectionBehavior:
> +                        NSWindowCollectionBehaviorFullScreenPrimary];
> +
>     }
>     return self;
> }
> 
> (that probably needs to be guarded with "if 10.7 or later" ifdefs).

Ok, I will implement this in my patch also.


> and there are other problems with fullscreen still -- for instance
> if you fullscreen the window before the guest changes its
> resolution and then unfullscreen it afterwards, we forget about
> the fact the resolution changed and revert to the pre-change size.

I haven't noticed this issue. Which machine emulator are you using?


> 
> Another oddity: on fullscreening, the window's titlebar remains
> visible, up until the point where the guest changes its screen
> resolution, at which point it disappears. I'm guessing we shouldn't
> display it at all in fullscreen.

When qemu-system-ppc goes full screen, the menubar disappears over here. 

> 
> I need to check whether we get the mouse coordinates right in
> fullscreen mode, given that the window doesn't actually cover
> the whole screen area.

I haven't noticed any mouse coordinate problems on Mac OS 10.6. I will try my code out on other versions of Mac OS X to see if I can reproduce your issues.

> 
> If we're allowing mouse-ungrab in fullscreen mode, maybe we
> should remove the "if (!isFullscreen)" guard from the code that
> updates the window title with the "Press ctrl + alt to release
> mouse" string? Slightly academic, though, since by definition
> you can't read it if we're fullscreen...


Sounds like a good plan to me.
Peter Maydell Jan. 1, 2015, 4:48 p.m. UTC | #4
On 1 January 2015 at 16:05, Programmingkid <programmingkidx@gmail.com> wrote:
>
> On Jan 1, 2015, at 9:55 AM, Peter Maydell wrote:
>
>> On 30 December 2014 at 04:17, Programmingkid <programmingkidx@gmail.com> wrote:
>>> This patch fixes these problems for QEMU on Mac OS X:
>>> - fullscreen mode not having the correct aspect ratio
>>
>> What is the bug being fixed here? For me on 10.9.5 the fullscreen
>> behaviour is the same with or without this patch: the fullscreen
>> window is of the same size as the non-fullscreened version, with
>> a plain background behind it, so there's no aspect ratio issue.
>> I'm guessing that 10.6 behaved differently (the Lion fullscreen
>> changes were pretty drastic).
>
> When you look at the openbios prompt in full screen mode, you can
> see the text is all messed up looking. That is because the aspect
> ratio isn't being preserved.

So is it actually expanding the window to fill the whole of the
screen, rather than keeping it at the same resolution but just
the only window being displayed? That's definitely different from
the Lion-and-up behaviour...

>> and there are other problems with fullscreen still -- for instance
>> if you fullscreen the window before the guest changes its
>> resolution and then unfullscreen it afterwards, we forget about
>> the fact the resolution changed and revert to the pre-change size.
>
> I haven't noticed this issue. Which machine emulator are you using?

I use vexpress-a15, where it's quite easy to see because the
screen resolution changes a little way into kernel bootup,
so it's easy to fullscreen it before it gets there. You can
also see this with qemu-system-ppc if you're quick about hitting
the fullscreen button before it resizes. (In that case the
behaviour is different -- we fail to change the size of the
fullscreened window, so the openbios prompt isn't visible, and
switching back out of fullscreen it's still just a plain
yellow screen.)

http://people.linaro.org/~peter.maydell/vexpress-3.8.tgz
is a guest image which should demonstrate this, I think.

>> Another oddity: on fullscreening, the window's titlebar remains
>> visible, up until the point where the guest changes its screen
>> resolution, at which point it disappears. I'm guessing we shouldn't
>> display it at all in fullscreen.
>
> When qemu-system-ppc goes full screen, the menubar disappears over here.

I didn't mean the menubar (which does disappear); I meant the
title bar. Screenshot:
http://www.chiark.greenend.org.uk/~pmaydell/misc/qemu-screenshot.png

> I haven't noticed any mouse coordinate problems on Mac OS 10.6.
> I will try my code out on other versions of Mac OS X to see if
> I can reproduce your issues.

If you have access to a Lion-or-later version that would
definitely be helpful.

thanks
-- PMM
diff mbox

Patch

diff --git a/configure b/configure
index cae588c..32d3d3f 100755
--- a/configure
+++ b/configure
@@ -611,7 +611,7 @@  Darwin)
   cocoa="yes"
   audio_drv_list="coreaudio"
   audio_possible_drivers="coreaudio sdl fmod"
-  LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS"
+  LDFLAGS="-framework CoreFoundation -framework IOKit -framework ApplicationServices $LDFLAGS"
   libs_softmmu="-F/System/Library/Frameworks -framework Cocoa -framework IOKit $libs_softmmu"
   # Disable attempts to use ObjectiveC features in os/object.h since they
   # won't work when we're compiling with gcc as a C compiler.
diff --git a/ui/cocoa.m b/ui/cocoa.m
index d37c29b..d1bebb9 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -29,6 +29,7 @@ 
 #include "ui/console.h"
 #include "ui/input.h"
 #include "sysemu/sysemu.h"
+#import <ApplicationServices/ApplicationServices.h>
 
 #ifndef MAC_OS_X_VERSION_10_4
 #define MAC_OS_X_VERSION_10_4 1040
@@ -482,8 +483,16 @@  QemuCocoaView *cocoaView;
 - (void) toggleFullScreen:(id)sender
 {
     COCOA_DEBUG("QemuCocoaView: toggleFullScreen\n");
-
+    static CFDictionaryRef original_mode;
+
+    // initialize original_mode only once - before the resolution has been changed
+    if (!original_mode) {
+        original_mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
+    }
     if (isFullscreen) { // switch from fullscreen to desktop
+        if (original_mode != nil) {
+            CGDisplaySwitchToMode(kCGDirectMainDisplay, original_mode);
+        }
         isFullscreen = FALSE;
         [self ungrabMouse];
         [self setContentDimensions];
@@ -501,6 +510,12 @@  QemuCocoaView *cocoaView;
         }
 #endif
     } else { // switch from desktop to fullscreen
+        size_t desired_bit_depth = 32;
+        boolean_t exact_match;
+        CFDictionaryRef mode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, desired_bit_depth, cw, ch, &exact_match);
+        if (mode != nil) {
+            CGDisplaySwitchToMode(kCGDirectMainDisplay, mode);
+        }
         isFullscreen = TRUE;
         [self grabMouse];
         [self setContentDimensions];
@@ -561,7 +576,7 @@  QemuCocoaView *cocoaView;
             }
 
             // release Mouse grab when pressing ctrl+alt
-            if (!isFullscreen && ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
+            if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
                 [self ungrabMouse];
             }
             break;