Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mouse cursor can be incorrectly hidden when interacting with close button on Windows #1388

Closed
connorjclark opened this issue Nov 30, 2022 · 1 comment · Fixed by #1403
Closed
Milestone

Comments

@connorjclark
Copy link
Contributor

If the mouse cursor is hidden when the user goes into the window title bar, the cursor is made visible. It is set to be re-hidden when the cursor goes back into the window client area. This behavior is from https://github.com/liballeg/allegro5/blob/master/src/win/wwindow.c (see all the usages of we_hid_the_mouse).

This presents a problem when the cursor should be made visible because of an action the application performs on ALLEGRO_EVENT_DISPLAY_CLOSE. This mouse state internal to wwindow.c has no idea the application has changed that the cursor should now be visible, so when the mouse re-enters the window client area it is incorrectly hidden.

I've provided an example program.


This program has been adapted from an allegro example. You can just copy over ex_mouse_cursor.cpp and build that target.

Include is some commented out code that provides a partial workaround. The cursor can still act funny when on the very edge of the display as it re-enters, but it at least is not hidden when it should be shown.

#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include "allegro5/allegro_image.h"

#include "common.c"


#define MARGIN_LEFT  20
#define MARGIN_TOP   20

bool state = false;

ALLEGRO_DISPLAY *display;
ALLEGRO_FONT *font;

static void draw_display()
{
   int th;

   if (state)
      al_hide_mouse_cursor(display);
   else
      al_show_mouse_cursor(display);

   if (state)
      al_clear_to_color(al_map_rgb(255,114,118));
   else
      al_clear_to_color(al_map_rgb(128, 128, 128));

   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
   th = al_get_font_line_height(font);

   al_draw_text(font, al_map_rgba_f(0, 0, 0, 1),
      MARGIN_LEFT, MARGIN_TOP + 5 * th, 0,
      "Press S/H to show/hide cursor. Q to quit.");
   
   al_draw_text(font, al_map_rgba_f(0, 0, 0, 1),
      MARGIN_LEFT, MARGIN_TOP + 7 * th, 0,
      "For bug, try close win w/ cursor.");   
   al_draw_text(font, al_map_rgba_f(0, 0, 0, 1),
      MARGIN_LEFT, MARGIN_TOP + 8 * th, 0,
      " visible and move mouse down.");
   
   al_draw_text(font, al_map_rgba_f(0, 0, 0, 1),
      MARGIN_LEFT, MARGIN_TOP + 10 * th, 0,
      state ? "HIDDEN" : "VISIBLE");

   al_flip_display();
}

static void set_state(bool s)
{
   state = s;
   draw_display();
}

int main(int argc, char **argv)
{
   ALLEGRO_BITMAP *bmp;
   ALLEGRO_BITMAP *shrunk_bmp;
   ALLEGRO_MOUSE_CURSOR *custom_cursor;
   ALLEGRO_EVENT_QUEUE *queue;
   ALLEGRO_EVENT event;

   (void)argc;
   (void)argv;

   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
   }

   al_init_image_addon();
   init_platform_specific();

   if (!al_install_mouse()) {
      abort_example("Error installing mouse\n");
   }

   if (!al_install_keyboard()) {
      abort_example("Error installing keyboard\n");
   }

   al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS);
   display = al_create_display(400, 400);
   if (!display) {
      abort_example("Error creating display\n");
   }

   bmp = al_load_bitmap("data/allegro.pcx");
   if (!bmp) {
      abort_example("Error loading data/allegro.pcx\n");
   }

   font = al_load_bitmap_font("data/fixed_font.tga");
   if (!font) {
      abort_example("Error loading data/fixed_font.tga\n");
   }

   shrunk_bmp = al_create_bitmap(32, 32);
   if (!shrunk_bmp) {
      abort_example("Error creating shrunk_bmp\n");
   }

   al_set_target_bitmap(shrunk_bmp);
   al_draw_scaled_bitmap(bmp,
      0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp),
      0, 0, 32, 32,
      0);

   custom_cursor = al_create_mouse_cursor(shrunk_bmp, 0, 0);
   if (!custom_cursor) {
      abort_example("Error creating mouse cursor\n");
   }

   al_set_target_bitmap(NULL);
   al_destroy_bitmap(shrunk_bmp);
   al_destroy_bitmap(bmp);
   shrunk_bmp = NULL;
   bmp = NULL;

   queue = al_create_event_queue();
   if (!queue) {
      abort_example("Error creating event queue\n");
   }

   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_mouse_event_source());
   al_register_event_source(queue, al_get_display_event_source(display));

   al_set_target_backbuffer(display);
   draw_display(font);

   while (1) {
      al_wait_for_event(queue, &event);
      if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         set_state(!state);
         continue;
      }
      if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) {
         al_set_target_backbuffer(event.display.source);
         draw_display(font);
         continue;
      }
      // Uncomment for partial bug workaround.
      // if (event.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY)
      // {
      //    if (state)
      //       al_hide_mouse_cursor(event.mouse.display);
      //    else
      //       al_show_mouse_cursor(event.mouse.display);
      // }
      if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
         switch (event.keyboard.unichar) {
            case 27: /* escape */
               goto Quit;
            case 'h':
               set_state(true);
               break;
            case 's':
               set_state(false);
               break;
            case 'q':
               goto Quit;
            default:
               break;
         }
      }
      if (event.type == ALLEGRO_EVENT_MOUSE_AXES) {
         static bool done = false;
         if (!done)
         {
            al_set_mouse_cursor(event.mouse.display, custom_cursor);
            done = true;
         }
      }
   }

Quit:

   al_destroy_mouse_cursor(custom_cursor);

   return 0;
}
@SiegeLord SiegeLord added this to the 5.2.9 milestone Jan 31, 2023
SiegeLord pushed a commit to SiegeLord/allegro5 that referenced this issue Feb 1, 2023
We do this by tracking this state next to the usual one and
properly resetting it when needed.

Fixes liballeg#1388
SiegeLord pushed a commit to SiegeLord/allegro5 that referenced this issue Feb 1, 2023
We do this by tracking this state next to the usual one and
properly resetting it when needed.

Fixes liballeg#1388
SiegeLord pushed a commit that referenced this issue Feb 1, 2023
We do this by tracking this state next to the usual one and
properly resetting it when needed.

Fixes #1388
@SiegeLord
Copy link
Member

Thanks for the example program, it made it easy to debug!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants