Bug?: Task Switching Routine Called Twice
Kris Asick

Allegro Version: 4.2.1
Operating System: Windows 98 SE

I have no idea what's causing this, even after looking through the Allegro source, or if it's limited to Windows 98 or not, but under the following circumstances, any routines I've registered with set_display_switch_callback() get processed twice!

  • Must be windowed. (Won't happen fullscreen.)

  • Only happens with SWITCH_IN, not with SWITCH_OUT.

  • Only happens when restoring a minimized application. (It's not enough that it's in the background, it must be minimized.)

I spent an hour looking through the Allegro source and haven't the foggiest idea what's causing this. I spent even longer than that debugging my code to see if perhaps it was something I was doing but my code checks out too, especially considering the specific circumstances outlined. If any one of those situations is not true, the problem doesn't happen.

I managed to make a work-around in my code that prevents this from being an issue, but still, it's particularly weird that it would happen at all. I'm really not sure if this is a bug or a glitch with my system or what... it's too strange...

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Thomas Fjellstrom

It would seem to me that its windows sending some message to allegro about the un minimize, then the "to front" actions. But that's just a wild guess.

Matthew Leverton

I confirm that this happens on a minimalistic example under Vista. Two "in" calls are triggered at the time focus is restored after a minimize.

It happens with SWITCH_BACKGROUND. Does not happen with SWITCH_PAUSE. (Only two modes supported in a windowed environment.)

Milan Mimica

I don't know if this is relevent here, but you should be aware that set_gfx_mode() induces a SWITCH_IN event, which is fine. So if you restore a graphic mode via set_gfx_mode() in a display switch callback routine, you'll have another SWITCH_IN callback.

EDIT: The above is not the case here.
The thing is that WM_ACTIVATE event is sent twice when deminimizing a window. Fortunatly, there is a way to distinguish the two events. The following patch ignores the first event:

Index: src/win/wwnd.c
===================================================================
--- src/win/wwnd.c      (revision 7814)
+++ src/win/wwnd.c      (working copy)
@@ -261,6 +261,10 @@
             _win_switch_out();
          }
          else {
+           /* Ignore the WM_ACTIVATE event if the window is minimized. */
+           if (HIWORD(wparam))
+              break;
+
             if (gfx_driver && !gfx_driver->windowed) {
                /* 1.2s delay to let Windows complete the switch in fullscreen mode */
                SetTimer(allegro_wnd, SWITCH_TIMER, 1200, NULL);

I tested it on exswitch.exe example and it works fine.
Obviously, programs using workaround for this bug will become broken.

Matthew Leverton

Does returning 0 instead of breaking do anything? MSDN says that you should return 0 if you handle the event. Maybe that would get rid of the double event? I'd try it, but MinGW is broken under Vista and I cannot easily compile Allegro.

Quote:

Obviously, programs using workaround for this bug will become broken.

Not necessarily:

int foo = 0;
void switch_in()
{
  if (foo)
  {
    foo = 0;
  }
}

void switch_out()
{
  foo = 1;
}

But this is a bug and should be fixed regardless if it breaks hacks. People should report bugs, not work around them in user code.

Milan Mimica
Quote:

Does returning 0 instead of breaking do anything?

No.

Matthew Leverton

Then I'd say your patch should be applied.

Thread #590937. Printed from Allegro.cc