Client-side decorations
Luka Aleksic

Hello everyone,

I want to make a frameless window with client-side decorations (i.e. not decorated by the window manager, but it draws its own frame that you can click on and drag to move the window, and that contains a close button etc.)

Attached is the source code to a small mockup I made that should allow clicking and dragging anywhere in the window to move it around. It works but is very jerky (difficult to explain in words, see recording here). I'm not sure what needs to be changed. Can anyone point me in the right direction?

Thanks,
Luka

Edgar Reynaldo

Greetings Luka,

The problem is that allegro tracks the mouse position relative to the window, so everytime you move the window, the mouse moves too, hence the flicker.

If you use absolute mouse coordinates, you won't have this problem.

I altered your code and it's working fine now.

Here's the altered code :

Note : you can use code tags to display code (<code>code goes here...</code>) :

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro5.h> 3#include <allegro5/allegro_font.h> 4 5 6#include <windows.h> 7 8int main() { 9 al_init(); 10 al_install_mouse(); 11 al_install_keyboard(); 12 13 ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); 14 15 ALLEGRO_DISPLAY* disp = al_create_display(32*11, 32*11); 16 al_set_display_flag(disp, ALLEGRO_FRAMELESS, true); 17 18 int win_x = 0; 19 int win_y = 0; 20 int mouse_x = 0; 21 int mouse_y = 0; 22 23 al_get_window_position(disp, &win_x, &win_y); 24 25 ALLEGRO_FONT* font = al_create_builtin_font(); 26 27 al_register_event_source(queue, al_get_display_event_source(disp)); 28 al_register_event_source(queue, al_get_mouse_event_source()); 29 al_register_event_source(queue , al_get_keyboard_event_source()); 30 31 bool should_quit = false; 32 33 ALLEGRO_EVENT event; 34 35 bool moving_window = false; 36 37 int movex = 0; 38 int movey = 0; 39 40 while (!should_quit) { 41 al_wait_for_event(queue, &event); 42 43 switch (event.type) { 44 case ALLEGRO_EVENT_DISPLAY_CLOSE: 45 should_quit = true; 46 break; 47 case ALLEGRO_EVENT_KEY_DOWN : 48 if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {should_quit = true;} 49 break; 50 case ALLEGRO_EVENT_MOUSE_AXES: 51 POINT p; 52 GetCursorPos(&p); 53 mouse_x = p.x; 54 mouse_y = p.y; 55 if(moving_window){ 56 al_set_window_position(disp, win_x + (mouse_x - movex) , win_y + (mouse_y - movey)); 57 } 58 break; 59 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 60 { 61/// al_get_window_position(disp, &win_x, &win_y); 62 movex = mouse_x; 63 movey = mouse_y; 64 printf("down\n"); 65 moving_window = true; 66 67 break; 68 } 69 case ALLEGRO_EVENT_MOUSE_BUTTON_UP: 70 { 71 printf("up\n"); 72 moving_window = false; 73 74 break; 75 } 76 default: 77 break; 78 } 79 80 if (al_is_event_queue_empty(queue)) 81 { 82// al_get_window_position(disp, &win_x, &win_y); 83 84 al_clear_to_color(al_map_rgb(0, 0, 0)); 85 al_draw_text(font, al_map_rgb(255, 255, 255), 0, 0, 0, "Hello, world!"); 86 al_flip_display(); 87 } 88 } 89 90 al_destroy_font(font); 91 al_destroy_display(disp); 92 al_destroy_event_queue(queue); 93 94 return 0; 95}

Luka Aleksic

Thanks very much!

Is there a way to get the absolute coordinates with some cross-platform Allegro function or is using platform-specific code necessary?

Edgar Reynaldo

Allegro doesn't provide a method to get the absolute mouse position, but as you can see, it only takes a single include and a single function call. You can easily separate out these things with an #ifdef ALLEGRO_WIN32, etc...

Thread #617851. Printed from Allegro.cc