OS X Quartz problems/bugs

I’m currently trying to port some of our titles to OS X/Quartz using the
Cocoa layer (instead of the Carbon layer). As a reference point, our
games are successfully deployed on Linux using SDL, so I’m pretty
confident we’ve got most of the SDL bit down.

The first problem is the easiest one. BACKSPACE (and probably some
other keys) puts 127 into key.unicode in QZ_DoKey(). I don’t know if
this is expected behaviour, but under Linux I don’t believe this is the
case. I’ve been looking at key.unicode for ctrl-H for backspace. This
is easy enough to fix on the application end by looking at key.sym or,
if it helps with consistency, by putting key.sum into key.unicode if
key.unicode == 127 in QZ_DoKey() (or a similar type hack).

The second problem is significantly gnarlier, and has to do with the
following sequence:

  • start app in fullscreen
  • switch to windowed

Doing window -> fullscreen -> window or window -> fullscreen does not
manifest this problem.

My initial take is that this is a problem with Quartz/Cocoa, not SDL,
but I’ll describe it here just so others can take a look at it.

The initial problem was that when I was back in windowed mode, my mouse
"y" value was always 0. Further research showed it was always getting
clipped. Even further investigation showed that something really,
really wacky was going on.

To do some basic sanity checks, I called [[NSScreen mainScreen] frame]
first thing in SetVideoModeWindowed(), and it reported origin = 0,0 and
size = 640,480. Except I was running 1280x1024, and everything else
checked out and looked fine. Theory: CGDisplayRelease or a related call
isn’t “flushing” some state that NSScreen is referencing. It’s like
[NSScreen mainScreen] is updated on CGDisplaySetMode, but not updated on
when it’s unset.

So that was/is a problem.

Then, as a second sanity check, I called [qz_window frame] origin.y was
ranging from 0 to -screenheight, in other words, halfway down the screen
the window’s origin would be 0,-768 or something similar.

Cocoa uses an inverted coordinate system from what most people are used
to with 2D display devices. (0,0) is at the bottom left of the screen.
So what this means is that apparently qz_window thinks it’s below the
bottom of the screen. Or, another way of thinking about this, it thinks
that (0,0) is at the top left of the screen, but that +Y goes up.

As an adjunct to this, calling [qz_window convertScreenToBase] gives
bizarre results, but which are expected once the values are examined.
When things are working, for example, with a screen point of 0,500 and a
window origin of 0,200, “convertScreenToBase” should report an output of
0,300 (I think).

However, in my case, when stepping through, I find that I’ll have screen
coordinate of (0,200) and after calling [qz_window convertScreenToBase],
I’ll have a number like 0,600 because qz_window’s origin is at 0,-400
(!) even though it’s displayed correctly on the monitor. Bizarre.

I’m hesitant to say this is an SDL implementation bug, since it works
just fine in the other cases mentioned. It definitely feels like a
problem with Quartz. Of course, I’m sure Apple will blame SDL =/

I’ve posted to mac-games and cocoa-dev @lists.apple.com, but no answer
yet. Anyway, if someone has an idea what might be causing this, I would
love to hear any directions to investigate.

Thanks,

Brian

Apparently no one else is suffering from this problem (no response on
mac-games-dev or cocoa-dev), but here’s the hack I came up with to fix
this.

At the beginning QZ_SetVideoFullScreen I added:

static bool s_bHackWindowMode = false;

if ( !s_bHackWindowMode )
{
s_bHackWindowMode = true;

//If this is the first time we're going into fullscreen, force a 
//a regular window to be made and destroyed so that when we 
//return to windowed mode, NSScreen isn't confused.  Technically
//I think we only have to do this if we're going into fullscreen
//and have never created a window
QZ_SetVideoWindowed( this, current, width, height, bpp, flags );
QZ_UnsetVideoMode( this );

}

I’ve tested this with our games, and it seems to work fine. I’m not
sure what the underlying reason for this is, but I’m glad it works
either way.

Brian> -----Original Message-----

From: sdl-admin at libsdl.org [mailto:sdl-admin at libsdl.org] On
Behalf Of Brian Hook
Sent: Wednesday, August 07, 2002 5:06 PM
To: sdl at libsdl.org
Subject: [SDL] OS X Quartz problems/bugs

I’m currently trying to port some of our titles to OS
X/Quartz using the Cocoa layer (instead of the Carbon layer).
As a reference point, our games are successfully deployed on
Linux using SDL, so I’m pretty confident we’ve got most of
the SDL bit down.

The first problem is the easiest one. BACKSPACE (and
probably some other keys) puts 127 into key.unicode in
QZ_DoKey(). I don’t know if this is expected behaviour, but
under Linux I don’t believe this is the case. I’ve been
looking at key.unicode for ctrl-H for backspace. This is
easy enough to fix on the application end by looking at
key.sym or, if it helps with consistency, by putting key.sum
into key.unicode if key.unicode == 127 in QZ_DoKey() (or a
similar type hack).

The second problem is significantly gnarlier, and has to do
with the following sequence:

  • start app in fullscreen
  • switch to windowed

Doing window -> fullscreen -> window or window -> fullscreen
does not manifest this problem.

My initial take is that this is a problem with Quartz/Cocoa,
not SDL, but I’ll describe it here just so others can take a
look at it.

The initial problem was that when I was back in windowed
mode, my mouse “y” value was always 0. Further research
showed it was always getting clipped. Even further
investigation showed that something really, really wacky was going on.

To do some basic sanity checks, I called [[NSScreen
mainScreen] frame] first thing in SetVideoModeWindowed(), and
it reported origin = 0,0 and size = 640,480. Except I was
running 1280x1024, and everything else checked out and looked
fine. Theory: CGDisplayRelease or a related call isn’t
"flushing" some state that NSScreen is referencing. It’s
like [NSScreen mainScreen] is updated on CGDisplaySetMode,
but not updated on when it’s unset.

So that was/is a problem.

Then, as a second sanity check, I called [qz_window frame]
origin.y was ranging from 0 to -screenheight, in other words,
halfway down the screen the window’s origin would be 0,-768
or something similar.

Cocoa uses an inverted coordinate system from what most
people are used to with 2D display devices. (0,0) is at the
bottom left of the screen. So what this means is that
apparently qz_window thinks it’s below the bottom of the
screen. Or, another way of thinking about this, it thinks
that (0,0) is at the top left of the screen, but that +Y goes up.

As an adjunct to this, calling [qz_window
convertScreenToBase] gives bizarre results, but which are
expected once the values are examined. When things are
working, for example, with a screen point of 0,500 and a
window origin of 0,200, “convertScreenToBase” should report
an output of 0,300 (I think).

However, in my case, when stepping through, I find that I’ll
have screen coordinate of (0,200) and after calling
[qz_window convertScreenToBase], I’ll have a number like
0,600 because qz_window’s origin is at 0,-400
(!) even though it’s displayed correctly on the monitor. Bizarre.

I’m hesitant to say this is an SDL implementation bug, since
it works just fine in the other cases mentioned. It
definitely feels like a problem with Quartz. Of course, I’m
sure Apple will blame SDL =/

I’ve posted to mac-games and cocoa-dev @lists.apple.com, but
no answer yet. Anyway, if someone has an idea what might be
causing this, I would love to hear any directions to investigate.

Thanks,

Brian


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

I’m currently trying to port some of our titles to OS X/Quartz using the
Cocoa layer (instead of the Carbon layer). As a reference point, our
games are successfully deployed on Linux using SDL, so I’m pretty
confident we’ve got most of the SDL bit down.

The first problem is the easiest one. BACKSPACE (and probably some
other keys) puts 127 into key.unicode in QZ_DoKey(). I don’t know if
this is expected behaviour, but under Linux I don’t believe this is the
case. I’ve been looking at key.unicode for ctrl-H for backspace. This
is easy enough to fix on the application end by looking at key.sym or,
if it helps with consistency, by putting key.sum into key.unicode if
key.unicode == 127 in QZ_DoKey() (or a similar type hack).

The second problem is significantly gnarlier, and has to do with the
following sequence:

  • start app in fullscreen
  • switch to windowed

Doing window -> fullscreen -> window or window -> fullscreen does not
manifest this problem.

My initial take is that this is a problem with Quartz/Cocoa, not SDL,
but I’ll describe it here just so others can take a look at it.

The initial problem was that when I was back in windowed mode, my mouse
"y" value was always 0. Further research showed it was always getting
clipped. Even further investigation showed that something really,
really wacky was going on.

To do some basic sanity checks, I called [[NSScreen mainScreen] frame]
first thing in SetVideoModeWindowed(), and it reported origin = 0,0 and
size = 640,480. Except I was running 1280x1024, and everything else
checked out and looked fine. Theory: CGDisplayRelease or a related call
isn’t “flushing” some state that NSScreen is referencing. It’s like
[NSScreen mainScreen] is updated on CGDisplaySetMode, but not updated on
when it’s unset.

So that was/is a problem.

Are you sure? I can’t seem to reproduce this (see attached test case).
Maybe I’m not testing the right thing. Send me a simplified test case
that demonstrates the bug if you can.

Then, as a second sanity check, I called [qz_window frame] origin.y was
ranging from 0 to -screenheight, in other words, halfway down the screen
the window’s origin would be 0,-768 or something similar.

Cocoa uses an inverted coordinate system from what most people are used
to with 2D display devices. (0,0) is at the bottom left of the screen.
So what this means is that apparently qz_window thinks it’s below the
bottom of the screen. Or, another way of thinking about this, it thinks
that (0,0) is at the top left of the screen, but that +Y goes up.

As an adjunct to this, calling [qz_window convertScreenToBase] gives
bizarre results, but which are expected once the values are examined.
When things are working, for example, with a screen point of 0,500 and a
window origin of 0,200, “convertScreenToBase” should report an output of
0,300 (I think).

Yup.

However, in my case, when stepping through, I find that I’ll have screen
coordinate of (0,200) and after calling [qz_window convertScreenToBase],
I’ll have a number like 0,600 because qz_window’s origin is at 0,-400
(!) even though it’s displayed correctly on the monitor. Bizarre.

Well if the screen rectangle is incorrect, it stands to reason that all
these things should be incorrect too.

just fine in the other cases mentioned. It definitely feels like a
problem with Quartz. Of course, I’m sure Apple will blame SDL =/

Until I can get a test case to reproduce it, I’m not going to make any
assumptions :wink: I’ve seen way too many strange bugs to jump to
conclusions.

One strange thing I have noticed in another SDL app was that after
fullscreen -> window the window wasn’t centered quite right on the
display. Might be a related.

Check out this test case; maybe you can change it to demonstrate the bug
you are seeing.

-------------- next part --------------
A non-text attachment was scrubbed…
Name: main.m
Type: application/octet-stream
Size: 2294 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020808/b3153ed9/attachment.objOn Wednesday, August 7, 2002, at 07:05 PM, Brian Hook wrote:

Are you sure?

In the words of Indiana Jones: “pretty sure” =)

Maybe I’m not testing the right thing. Send me a simplified test case
that demonstrates the bug if you can.

Your test case actually demonstrates this and corroborates a comment
made by someone else, although there are a couple other problems that
cropped up.

I had to #undef main, not sure if that just slipped by or if I’m doing
something wrong.

In addition, it doesn’t get key presses at all – maybe this is related
to the fact I’m running on a multimon system? It sees the mouse motion
just fine though. Odd.

So to test, comment out the calls to “doWaitForKey()”. Now, look at the
output of printNSScreenRect() – on my system, it says 1280x1024 after
going into fullscreen 640x480
.

Then when it goes into SDL_SetVideoMode() for windowed mode, it crashes
when trying to flush a port buffer. If this doesn’t happen on your
system, let me know and I’ll get you the line, etc.

Now, relating to my previous comments about someone else commenting on
this – he said he issued a bug report and that the Apple engineers said
that AppKit doesn’t see a mode change until it receives the appropriate
event. This means that if you do a bunch of mode changes without
pumping the event loop, AppKit gets confused and what NSScreen, etc.
will report will not match, which also means that NSWindow -center won’t
work and that most everything else will get confused.

However, I’m not sure the right way to test this theory since
doWaitForKey() doesn’t work for me.

My system is a G4/867 tower, 640MB RAM, 10.1.5, using PB 1.x and the
last released dev tools (i.e. not the beta PB 2.x/GCC 3.1 stuff). It’s
a multimon configuration, but that shouldn’t matter (Rage Pro, Radeon
and GF2MX/AGP).

Brian

Are you sure?

In the words of Indiana Jones: “pretty sure” =)

Maybe I’m not testing the right thing. Send me a simplified test case
that demonstrates the bug if you can.

Your test case actually demonstrates this and corroborates a comment
made by someone else, although there are a couple other problems that
cropped up.

I had to #undef main, not sure if that just slipped by or if I’m doing
something wrong.

Noooo! Make sure SDLMain.m/SDLMain.h are in your project!

In addition, it doesn’t get key presses at all – maybe this is related
to the fact I’m running on a multimon system? It sees the mouse motion
just fine though. Odd.

That’s because you #undef main in my code. Read the FAQ on this if you
haven’t already.

So to test, comment out the calls to “doWaitForKey()”. Now, look at the
output of printNSScreenRect() – on my system, it says 1280x1024 after
going into fullscreen 640x480
.

I #undef main and still can’t reproduce this. I could at one point but
now I can’t get the second window to come up at all. This is on an iMac
G4 and Beige G3/233.

Then when it goes into SDL_SetVideoMode() for windowed mode, it crashes
when trying to flush a port buffer. If this doesn’t happen on your
system, let me know and I’ll get you the line, etc.

Oh yes, this is because you #undef main

Now, relating to my previous comments about someone else commenting on
this – he said he issued a bug report and that the Apple engineers said
that AppKit doesn’t see a mode change until it receives the appropriate
event. This means that if you do a bunch of mode changes without
pumping the event loop, AppKit gets confused and what NSScreen, etc.
will report will not match, which also means that NSWindow -center won’t
work and that most everything else will get confused.

Yes, I read the post. Still can’t reproduce it though. I’m having the
same window centering bug, but I haven’t found the right sequence to
reproduce it every time. Later… Oh yes, launching the app from the
Terminal does the trick. No centering problems when launched from the
Finder or ProjectBuilder though. Go figure…

My system is a G4/867 tower, 640MB RAM, 10.1.5, using PB 1.x and the
last released dev tools (i.e. not the beta PB 2.x/GCC 3.1 stuff). It’s
a multimon configuration, but that shouldn’t matter (Rage Pro, Radeon
and GF2MX/AGP).

Shouldn’t matter…well perhaps it requires multiple monitors.On Friday, August 9, 2002, at 01:55 PM, Brian Hook wrote:

Noooo! Make sure SDLMain.m/SDLMain.h are in your project!

Sorry, I’m an SDL newbie – the SDL codebase was written by other coders
who are definitely not SDL newbies =)

Let me give this another look over.

Brian

Noooo! Make sure SDLMain.m/SDLMain.h are in your project!

Okay, did that.

It doesn’t crash anymore, BUT:

  • after setting fullscreen it reports that the screen is 1280x1024. In
    fact, it always thinks that’s the case.

  • after switching to running windowed, the mouse coordinates are
    reported from 0…640 and 0…480. Different than the problem I’m having,
    but I would imagine this is still a bug?

  • mouse values are clamped to the main screen when the cursor is pulled
    across multiple monitors. Not a big deal though, but I thought I’d let
    you know =)

I’m using the latest CVS 1.2.x I think.

Yes, I read the post. Still can’t reproduce it though. I’m having the
same window centering bug, but I haven’t found the right sequence to
reproduce it every time. Later… Oh yes, launching the app from the
Terminal does the trick. No centering problems when launched from the
Finder or ProjectBuilder though. Go figure…

I get it in either case.

Brian

Noooo! Make sure SDLMain.m/SDLMain.h are in your project!

Okay, did that.

It doesn’t crash anymore, BUT:

  • after setting fullscreen it reports that the screen is 1280x1024. In
    fact, it always thinks that’s the case.

That’s good. That’s what it should be doing.

  • after switching to running windowed, the mouse coordinates are
    reported from 0…640 and 0…480. Different than the problem I’m having,
    but I would imagine this is still a bug?

If the window is 640x480, it sounds like it is behaving correctly. The
mouse coordinates are relative to the window. (in SDL terms, the
coordinates are relative to the surface).

  • mouse values are clamped to the main screen when the cursor is pulled
    across multiple monitors. Not a big deal though, but I thought I’d let
    you know =)

I wasn’t aware of that specific problem, but nothing has been done (in
the code) to support multiple monitors yet.On Friday, August 9, 2002, at 04:38 PM, Brian Hook wrote:

I’m using the latest CVS 1.2.x I think.

Yes, I read the post. Still can’t reproduce it though. I’m having the
same window centering bug, but I haven’t found the right sequence to
reproduce it every time. Later… Oh yes, launching the app from the
Terminal does the trick. No centering problems when launched from the
Finder or ProjectBuilder though. Go figure…

I get it in either case.

Brian


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

It doesn’t crash anymore, BUT:

  • after setting fullscreen it reports that the screen is 1280x1024. In
    fact, it always thinks that’s the case.

That’s good. That’s what it should be doing.

Hmm… what was I thinking? No, it doesn’t make sense, and actually
helps explain a bug I saw when writing the event code. That is, I found
that NSEvent’s mouse location was completely bogus. So I switched to
using the Carbon GetMouseLocation() to determine mouse movement. So
although this is wrong, it will still work. But it is good to know since
I can probably avoid the polling behavior in the current mouse motion
handling by manually changing the main screen’s rect.

Cheers,
DarrellOn Friday, August 9, 2002, at 05:18 PM, Darrell Walisser wrote:

On Friday, August 9, 2002, at 04:38 PM, Brian Hook wrote:

  • after setting fullscreen it reports that the screen is
    1280x1024.
    In fact, it always thinks that’s the case.

That’s good. That’s what it should be doing.

Okay, I’m confused now – when I’m in fullscreen mode at 640x480,
[[NSScreen mainScreen] frame] is supposed to be reporting 1280x1024?

If the window is 640x480, it sounds like it is behaving
correctly. The mouse coordinates are relative to the window. (in SDL
terms, the
coordinates are relative to the surface).

Ah, okay, I must have been thinking of something else when it came to
the screen coordinates vs. local coordinates.

Brian