21#include <X11/extensions/shape.h>
22#include <X11/cursorfont.h>
24#include <winpr/assert.h>
25#include <winpr/cast.h>
27#include "xf_floatbar.h"
29#include "resource/close.xbm"
30#include "resource/lock.xbm"
31#include "resource/unlock.xbm"
32#include "resource/minimize.xbm"
33#include "resource/restore.xbm"
35#include <freerdp/log.h>
36#define TAG CLIENT_TAG("x11")
38#define FLOATBAR_HEIGHT 26
39#define FLOATBAR_DEFAULT_WIDTH 576
40#define FLOATBAR_MIN_WIDTH 200
41#define FLOATBAR_BORDER 24
42#define FLOATBAR_BUTTON_WIDTH 24
43#define FLOATBAR_COLOR_BACKGROUND "RGB:31/6c/a9"
44#define FLOATBAR_COLOR_BORDER "RGB:75/9a/c8"
45#define FLOATBAR_COLOR_FOREGROUND "RGB:FF/FF/FF"
47#define XF_FLOATBAR_FLAG_POSITION_MASK 0x00C0
48#define XF_FLOATBAR_FLAG_POSITION_LEFT 0x0040
49#define XF_FLOATBAR_FLAG_POSITION_RIGHT 0x0080
51#define XF_FLOATBAR_MODE_NONE 0
52#define XF_FLOATBAR_MODE_DRAGGING 1
53#define XF_FLOATBAR_MODE_RESIZE_LEFT 2
54#define XF_FLOATBAR_MODE_RESIZE_RIGHT 3
56#define XF_FLOATBAR_BUTTON_CLOSE 1
57#define XF_FLOATBAR_BUTTON_RESTORE 2
58#define XF_FLOATBAR_BUTTON_MINIMIZE 3
59#define XF_FLOATBAR_BUTTON_LOCKED 4
61typedef BOOL (*OnClick)(xfFloatbar*);
81 int last_motion_x_root;
82 int last_motion_y_root;
84 xfFloatbarButton* buttons[4];
96static void xf_floatbar_button_free(xfContext* xfc, xfFloatbarButton* button);
98WINPR_ATTR_MALLOC(xf_floatbar_button_free, 1)
99static xfFloatbarButton* xf_floatbar_new_button(xfFloatbar* floatbar,
int type);
102static BOOL xf_floatbar_button_onclick_close(xfFloatbar* floatbar)
107 return freerdp_abort_connect_context(&floatbar->xfc->common.context);
111static BOOL xf_floatbar_button_onclick_minimize(xfFloatbar* floatbar)
113 xfContext* xfc =
nullptr;
115 if (!floatbar || !floatbar->xfc)
119 xf_SetWindowMinimized(xfc, xfc->window);
124static BOOL xf_floatbar_button_onclick_restore(xfFloatbar* floatbar)
129 xf_toggle_fullscreen(floatbar->xfc);
134static BOOL xf_floatbar_button_onclick_locked(xfFloatbar* floatbar)
139 floatbar->locked = !((floatbar->locked));
140 return xf_floatbar_hide_and_show(floatbar);
143BOOL xf_floatbar_set_root_y(xfFloatbar* floatbar,
int y)
148 floatbar->last_motion_y_root = y;
152BOOL xf_floatbar_hide_and_show(xfFloatbar* floatbar)
154 xfContext* xfc =
nullptr;
156 if (!floatbar || !floatbar->xfc)
159 if (!floatbar->created)
164 WINPR_ASSERT(xfc->display);
166 if (!floatbar->locked)
168 if ((floatbar->mode == XF_FLOATBAR_MODE_NONE) && (floatbar->last_motion_y_root > 10) &&
169 (floatbar->y > (FLOATBAR_HEIGHT * -1)))
171 floatbar->y = floatbar->y - 1;
172 LogDynAndXMoveWindow(xfc->log, xfc->display, floatbar->handle, floatbar->x,
175 else if (floatbar->y < 0 && (floatbar->last_motion_y_root < 10))
177 floatbar->y = floatbar->y + 1;
178 LogDynAndXMoveWindow(xfc->log, xfc->display, floatbar->handle, floatbar->x,
187static BOOL create_floatbar(xfFloatbar* floatbar)
189 xfContext* xfc =
nullptr;
191 XWindowAttributes attr = WINPR_C_ARRAY_INIT;
193 WINPR_ASSERT(floatbar);
194 if (floatbar->created)
199 WINPR_ASSERT(xfc->display);
201 status = LogDynAndXGetWindowAttributes(xfc->log, xfc->display, floatbar->root_window, &attr);
205 switch (floatbar->flags & XF_FLOATBAR_FLAG_POSITION_MASK)
207 case XF_FLOATBAR_FLAG_POSITION_LEFT:
211 case XF_FLOATBAR_FLAG_POSITION_RIGHT:
212 floatbar->x = attr.width - FLOATBAR_DEFAULT_WIDTH;
216 floatbar->x = attr.width / 2 - FLOATBAR_DEFAULT_WIDTH / 2;
226 if (((floatbar->flags & 0x0004) == 0) && !floatbar->locked)
227 floatbar->y = -FLOATBAR_HEIGHT + 1;
229 floatbar->handle = LogDynAndXCreateWindow(
230 xfc->log, xfc->display, floatbar->root_window, floatbar->x, 0, FLOATBAR_DEFAULT_WIDTH,
231 FLOATBAR_HEIGHT, 0, CopyFromParent, InputOutput, CopyFromParent, 0,
nullptr);
232 floatbar->width = FLOATBAR_DEFAULT_WIDTH;
233 floatbar->height = FLOATBAR_HEIGHT;
234 floatbar->mode = XF_FLOATBAR_MODE_NONE;
235 floatbar->buttons[0] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_CLOSE);
236 floatbar->buttons[1] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_RESTORE);
237 floatbar->buttons[2] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_MINIMIZE);
238 floatbar->buttons[3] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_LOCKED);
239 LogDynAndXSelectInput(xfc->log, xfc->display, floatbar->handle,
240 ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
241 FocusChangeMask | LeaveWindowMask | EnterWindowMask |
242 StructureNotifyMask | PropertyChangeMask);
243 floatbar->created = TRUE;
247BOOL xf_floatbar_toggle_fullscreen(xfFloatbar* floatbar,
bool fullscreen)
250 bool visible = False;
251 xfContext* xfc =
nullptr;
253 if (!floatbar || !floatbar->xfc)
257 WINPR_ASSERT(xfc->display);
260 if (floatbar->flags & 0x0001)
263 visible |= ((floatbar->flags & 0x0010) != 0) && fullscreen;
265 visible |= ((floatbar->flags & 0x0020) != 0) && !fullscreen;
270 if (!create_floatbar(floatbar))
273 LogDynAndXMapWindow(xfc->log, xfc->display, floatbar->handle);
274 size = ARRAYSIZE(floatbar->buttons);
276 for (
int i = 0; i < size; i++)
278 xfFloatbarButton* button = floatbar->buttons[i];
279 LogDynAndXMapWindow(xfc->log, xfc->display, button->handle);
283 if (((floatbar->flags & 0x0004) == 0) && !floatbar->locked)
284 floatbar->y = -FLOATBAR_HEIGHT + 1;
286 xf_floatbar_hide_and_show(floatbar);
288 else if (floatbar->created)
290 XUnmapSubwindows(xfc->display, floatbar->handle);
291 LogDynAndXUnmapWindow(xfc->log, xfc->display, floatbar->handle);
297xfFloatbarButton* xf_floatbar_new_button(xfFloatbar* floatbar,
int type)
299 xfFloatbarButton* button =
nullptr;
301 WINPR_ASSERT(floatbar);
302 WINPR_ASSERT(floatbar->xfc);
303 WINPR_ASSERT(floatbar->xfc->display);
304 WINPR_ASSERT(floatbar->handle);
306 button = (xfFloatbarButton*)calloc(1,
sizeof(xfFloatbarButton));
311 case XF_FLOATBAR_BUTTON_CLOSE:
312 button->x = floatbar->width - FLOATBAR_BORDER - FLOATBAR_BUTTON_WIDTH * type;
313 button->onclick = xf_floatbar_button_onclick_close;
316 case XF_FLOATBAR_BUTTON_RESTORE:
317 button->x = floatbar->width - FLOATBAR_BORDER - FLOATBAR_BUTTON_WIDTH * type;
318 button->onclick = xf_floatbar_button_onclick_restore;
321 case XF_FLOATBAR_BUTTON_MINIMIZE:
322 button->x = floatbar->width - FLOATBAR_BORDER - FLOATBAR_BUTTON_WIDTH * type;
323 button->onclick = xf_floatbar_button_onclick_minimize;
326 case XF_FLOATBAR_BUTTON_LOCKED:
327 button->x = FLOATBAR_BORDER;
328 button->onclick = xf_floatbar_button_onclick_locked;
336 button->focus = FALSE;
338 LogDynAndXCreateWindow(floatbar->xfc->log, floatbar->xfc->display, floatbar->handle,
339 button->x, 0, FLOATBAR_BUTTON_WIDTH, FLOATBAR_BUTTON_WIDTH, 0,
340 CopyFromParent, InputOutput, CopyFromParent, 0,
nullptr);
341 LogDynAndXSelectInput(floatbar->xfc->log, floatbar->xfc->display, button->handle,
342 ExposureMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
343 LeaveWindowMask | EnterWindowMask | StructureNotifyMask);
347xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window,
const char* title, DWORD flags)
350 WINPR_ASSERT(xfc->display);
354 if ((flags & 0x0001) == 0)
364 xfFloatbar* floatbar = (xfFloatbar*)calloc(1,
sizeof(xfFloatbar));
369 floatbar->title = _strdup(title);
371 if (!floatbar->title)
374 floatbar->root_window = window;
375 floatbar->flags = flags;
377 floatbar->locked = (flags & 0x0002) != 0;
378 xf_floatbar_toggle_fullscreen(floatbar, FALSE);
381 char** missingList =
nullptr;
382 int missingCount = 0;
383 char* defString =
nullptr;
384 floatbar->fontSet = XCreateFontSet(floatbar->xfc->display,
"-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
385 &missingList, &missingCount, &defString);
387 if (floatbar->fontSet ==
nullptr)
389 WLog_ERR(TAG,
"Failed to create fontset");
391 XFreeStringList(missingList);
395 WINPR_PRAGMA_DIAG_PUSH
396 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
397 xf_floatbar_free(floatbar);
398 WINPR_PRAGMA_DIAG_POP
403static unsigned long xf_floatbar_get_color(xfFloatbar* floatbar,
char* rgb_value)
407 WINPR_ASSERT(floatbar);
408 WINPR_ASSERT(floatbar->xfc);
410 Display* display = floatbar->xfc->display;
411 WINPR_ASSERT(display);
413 Colormap cmap = DefaultColormap(display, XDefaultScreen(display));
414 XParseColor(display, cmap, rgb_value, &color);
415 XAllocColor(display, cmap, &color);
419static void xf_floatbar_event_expose(xfFloatbar* floatbar)
422 GC shape_gc =
nullptr;
424 XPoint shape[5] = WINPR_C_ARRAY_INIT;
425 XPoint border[5] = WINPR_C_ARRAY_INIT;
427 WINPR_ASSERT(floatbar);
428 WINPR_ASSERT(floatbar->xfc);
430 Display* display = floatbar->xfc->display;
431 WINPR_ASSERT(display);
434 pmap = LogDynAndXCreatePixmap(floatbar->xfc->log, display, floatbar->handle,
435 WINPR_ASSERTING_INT_CAST(uint32_t, floatbar->width),
436 WINPR_ASSERTING_INT_CAST(uint32_t, floatbar->height), 1);
437 gc = LogDynAndXCreateGC(floatbar->xfc->log, display, floatbar->handle, 0, 0);
438 shape_gc = LogDynAndXCreateGC(floatbar->xfc->log, display, pmap, 0, 0);
442 shape[1].x = WINPR_ASSERTING_INT_CAST(
short, floatbar->width);
444 shape[2].x = WINPR_ASSERTING_INT_CAST(
short, shape[1].x - FLOATBAR_BORDER);
445 shape[2].y = FLOATBAR_HEIGHT;
446 shape[3].x = WINPR_ASSERTING_INT_CAST(
short, shape[0].x + FLOATBAR_BORDER);
447 shape[3].y = FLOATBAR_HEIGHT;
448 shape[4].x = shape[0].x;
449 shape[4].y = shape[0].y;
451 border[0].x = shape[0].x;
452 border[0].y = WINPR_ASSERTING_INT_CAST(
short, shape[0].y - 1);
453 border[1].x = WINPR_ASSERTING_INT_CAST(
short, shape[1].x - 1);
454 border[1].y = WINPR_ASSERTING_INT_CAST(
short, shape[1].y - 1);
455 border[2].x = shape[2].x;
456 border[2].y = WINPR_ASSERTING_INT_CAST(
short, shape[2].y - 1);
457 border[3].x = WINPR_ASSERTING_INT_CAST(
short, shape[3].x - 1);
458 border[3].y = WINPR_ASSERTING_INT_CAST(
short, shape[3].y - 1);
459 border[4].x = border[0].x;
460 border[4].y = border[0].y;
462 LogDynAndXSetForeground(floatbar->xfc->log, display, shape_gc, 0);
463 LogDynAndXFillRectangle(floatbar->xfc->log, display, pmap, shape_gc, 0, 0,
464 WINPR_ASSERTING_INT_CAST(uint32_t, floatbar->width),
465 WINPR_ASSERTING_INT_CAST(uint32_t, floatbar->height));
467 LogDynAndXSetForeground(floatbar->xfc->log, display, shape_gc, 1);
468 XFillPolygon(display, pmap, shape_gc, shape, 5, 0, CoordModeOrigin);
469 XShapeCombineMask(display, floatbar->handle, ShapeBounding, 0, 0, pmap, ShapeSet);
471 LogDynAndXSetForeground(floatbar->xfc->log, display, gc,
472 xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BACKGROUND));
473 XFillPolygon(display, floatbar->handle, gc, shape, 4, 0, CoordModeOrigin);
475 LogDynAndXSetForeground(floatbar->xfc->log, display, gc,
476 xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BORDER));
477 XDrawLines(display, floatbar->handle, gc, border, 5, CoordModeOrigin);
479 const size_t len = strnlen(floatbar->title, MAX_PATH);
480 LogDynAndXSetForeground(floatbar->xfc->log, display, gc,
481 xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_FOREGROUND));
483 WINPR_ASSERT(len <= INT32_MAX / 2);
484 const int fx = floatbar->width / 2 - (int)len * 2;
485 if (floatbar->fontSet !=
nullptr)
487 XmbDrawString(display, floatbar->handle, floatbar->fontSet, gc, fx, 15, floatbar->title,
492 XDrawString(display, floatbar->handle, gc, fx, 15, floatbar->title, (
int)len);
494 LogDynAndXFreeGC(floatbar->xfc->log, display, gc);
495 LogDynAndXFreeGC(floatbar->xfc->log, display, shape_gc);
499static xfFloatbarButton* xf_floatbar_get_button(xfFloatbar* floatbar, Window window)
501 WINPR_ASSERT(floatbar);
502 const size_t size = ARRAYSIZE(floatbar->buttons);
504 for (
size_t i = 0; i < size; i++)
506 xfFloatbarButton* button = floatbar->buttons[i];
507 if (button->handle == window)
516static void xf_floatbar_button_update_positon(xfFloatbar* floatbar)
518 xfFloatbarButton* button =
nullptr;
519 WINPR_ASSERT(floatbar);
520 xfContext* xfc = floatbar->xfc;
521 const size_t size = ARRAYSIZE(floatbar->buttons);
523 for (
size_t i = 0; i < size; i++)
525 button = floatbar->buttons[i];
527 switch (button->type)
529 case XF_FLOATBAR_BUTTON_CLOSE:
531 floatbar->width - FLOATBAR_BORDER - FLOATBAR_BUTTON_WIDTH * button->type;
534 case XF_FLOATBAR_BUTTON_RESTORE:
536 floatbar->width - FLOATBAR_BORDER - FLOATBAR_BUTTON_WIDTH * button->type;
539 case XF_FLOATBAR_BUTTON_MINIMIZE:
541 floatbar->width - FLOATBAR_BORDER - FLOATBAR_BUTTON_WIDTH * button->type;
549 WINPR_ASSERT(xfc->display);
550 LogDynAndXMoveWindow(xfc->log, xfc->display, button->handle, button->x, button->y);
551 xf_floatbar_event_expose(floatbar);
555static void xf_floatbar_button_event_expose(xfFloatbar* floatbar, Window window)
557 xfFloatbarButton* button = xf_floatbar_get_button(floatbar, window);
558 static unsigned char* bits;
561 xfContext* xfc = floatbar->xfc;
567 WINPR_ASSERT(xfc->display);
568 WINPR_ASSERT(xfc->window);
570 gc = LogDynAndXCreateGC(xfc->log, xfc->display, button->handle, 0, 0);
571 floatbar = xfc->window->floatbar;
572 WINPR_ASSERT(floatbar);
574 switch (button->type)
576 case XF_FLOATBAR_BUTTON_CLOSE:
580 case XF_FLOATBAR_BUTTON_RESTORE:
584 case XF_FLOATBAR_BUTTON_MINIMIZE:
585 bits = minimize_bits;
588 case XF_FLOATBAR_BUTTON_LOCKED:
589 if (floatbar->locked)
600 pattern = XCreateBitmapFromData(xfc->display, button->handle, (
const char*)bits,
601 FLOATBAR_BUTTON_WIDTH, FLOATBAR_BUTTON_WIDTH);
603 if (!(button->focus))
604 LogDynAndXSetForeground(floatbar->xfc->log, xfc->display, gc,
605 xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BACKGROUND));
607 LogDynAndXSetForeground(floatbar->xfc->log, xfc->display, gc,
608 xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BORDER));
610 LogDynAndXSetBackground(xfc->log, xfc->display, gc,
611 xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_FOREGROUND));
612 XCopyPlane(xfc->display, pattern, button->handle, gc, 0, 0, FLOATBAR_BUTTON_WIDTH,
613 FLOATBAR_BUTTON_WIDTH, 0, 0, 1);
614 LogDynAndXFreePixmap(xfc->log, xfc->display, pattern);
615 LogDynAndXFreeGC(xfc->log, xfc->display, gc);
618static void xf_floatbar_button_event_buttonpress(xfFloatbar* floatbar,
const XButtonEvent* event)
621 xfFloatbarButton* button = xf_floatbar_get_button(floatbar, event->window);
624 button->clicked = TRUE;
627static void xf_floatbar_button_event_buttonrelease(xfFloatbar* floatbar,
const XButtonEvent* event)
629 xfFloatbarButton* button =
nullptr;
631 WINPR_ASSERT(floatbar);
634 button = xf_floatbar_get_button(floatbar, event->window);
639 button->onclick(floatbar);
640 button->clicked = FALSE;
644static void xf_floatbar_event_buttonpress(xfFloatbar* floatbar,
const XButtonEvent* event)
646 WINPR_ASSERT(floatbar);
649 switch (event->button)
652 if (event->x <= FLOATBAR_BORDER)
653 floatbar->mode = XF_FLOATBAR_MODE_RESIZE_LEFT;
654 else if (event->x >= (floatbar->width - FLOATBAR_BORDER))
655 floatbar->mode = XF_FLOATBAR_MODE_RESIZE_RIGHT;
657 floatbar->mode = XF_FLOATBAR_MODE_DRAGGING;
666static void xf_floatbar_event_buttonrelease(xfFloatbar* floatbar,
const XButtonEvent* event)
668 WINPR_ASSERT(floatbar);
671 switch (event->button)
674 floatbar->mode = XF_FLOATBAR_MODE_NONE;
682static void xf_floatbar_resize(xfFloatbar* floatbar,
const XMotionEvent* event)
688 WINPR_ASSERT(floatbar);
691 xfContext* xfc = floatbar->xfc;
693 WINPR_ASSERT(xfc->display);
696 movement =
event->x_root - floatbar->last_motion_x_root;
699 if (floatbar->mode == XF_FLOATBAR_MODE_RESIZE_LEFT)
701 x = floatbar->x + movement;
702 width = floatbar->width + movement * -1;
707 width = floatbar->width + movement;
711 if (FLOATBAR_MIN_WIDTH < width)
713 LogDynAndXMoveResizeWindow(xfc->log, xfc->display, floatbar->handle, x, 0,
714 WINPR_ASSERTING_INT_CAST(uint32_t, width),
715 WINPR_ASSERTING_INT_CAST(uint32_t, floatbar->height));
717 floatbar->width = width;
721static void xf_floatbar_dragging(xfFloatbar* floatbar,
const XMotionEvent* event)
726 WINPR_ASSERT(floatbar);
728 xfContext* xfc = floatbar->xfc;
730 WINPR_ASSERT(xfc->window);
731 WINPR_ASSERT(xfc->display);
734 movement =
event->x_root - floatbar->last_motion_x_root;
735 x = floatbar->x + movement;
738 if (x < 0 || (x + floatbar->width) > xfc->window->width)
742 LogDynAndXMoveWindow(xfc->log, xfc->display, floatbar->handle, x, 0);
744 floatbar->last_motion_x_root = floatbar->last_motion_x_root + movement;
748static void xf_floatbar_event_motionnotify(xfFloatbar* floatbar,
const XMotionEvent* event)
753 WINPR_ASSERT(floatbar);
756 xfContext* xfc = floatbar->xfc;
758 WINPR_ASSERT(xfc->display);
760 mode = floatbar->mode;
761 cursor = XCreateFontCursor(xfc->display, XC_arrow);
763 if ((event->state & Button1Mask) && (mode > XF_FLOATBAR_MODE_DRAGGING))
765 xf_floatbar_resize(floatbar, event);
767 else if ((event->state & Button1Mask) && (mode == XF_FLOATBAR_MODE_DRAGGING))
769 xf_floatbar_dragging(floatbar, event);
773 if (event->x <= FLOATBAR_BORDER || event->x >= floatbar->width - FLOATBAR_BORDER)
774 cursor = XCreateFontCursor(xfc->display, XC_sb_h_double_arrow);
777 XDefineCursor(xfc->display, xfc->window->handle, cursor);
778 XFreeCursor(xfc->display, cursor);
779 floatbar->last_motion_x_root =
event->x_root;
782static void xf_floatbar_button_event_focusin(xfFloatbar* floatbar,
const XAnyEvent* event)
784 xfFloatbarButton* button =
nullptr;
786 WINPR_ASSERT(floatbar);
789 button = xf_floatbar_get_button(floatbar, event->window);
793 button->focus = TRUE;
794 xf_floatbar_button_event_expose(floatbar, event->window);
798static void xf_floatbar_button_event_focusout(xfFloatbar* floatbar,
const XAnyEvent* event)
800 xfFloatbarButton* button =
nullptr;
802 WINPR_ASSERT(floatbar);
805 button = xf_floatbar_get_button(floatbar, event->window);
809 button->focus = FALSE;
810 xf_floatbar_button_event_expose(floatbar, event->window);
814static void xf_floatbar_event_focusout(xfFloatbar* floatbar)
816 WINPR_ASSERT(floatbar);
817 xfContext* xfc = floatbar->xfc;
822 WINPR_ASSERT(xfc->window);
823 WINPR_ASSERT(xfc->pointer);
824 XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
828BOOL xf_floatbar_check_event(xfFloatbar* floatbar,
const XEvent* event)
830 if (!floatbar || !floatbar->xfc || !event)
833 if (!floatbar->created)
836 if (event->xany.window == floatbar->handle)
839 size_t size = ARRAYSIZE(floatbar->buttons);
841 for (
size_t i = 0; i < size; i++)
843 const xfFloatbarButton* button = floatbar->buttons[i];
845 if (event->xany.window == button->handle)
852BOOL xf_floatbar_event_process(xfFloatbar* floatbar,
const XEvent* event)
854 if (!floatbar || !floatbar->xfc || !event)
857 if (!floatbar->created)
863 if (event->xexpose.window == floatbar->handle)
864 xf_floatbar_event_expose(floatbar);
866 xf_floatbar_button_event_expose(floatbar, event->xexpose.window);
871 xf_floatbar_event_motionnotify(floatbar, &event->xmotion);
875 if (event->xany.window == floatbar->handle)
876 xf_floatbar_event_buttonpress(floatbar, &event->xbutton);
878 xf_floatbar_button_event_buttonpress(floatbar, &event->xbutton);
883 if (event->xany.window == floatbar->handle)
884 xf_floatbar_event_buttonrelease(floatbar, &event->xbutton);
886 xf_floatbar_button_event_buttonrelease(floatbar, &event->xbutton);
891 floatbar->entered = TRUE;
894 if (event->xany.window != floatbar->handle)
895 xf_floatbar_button_event_focusin(floatbar, &event->xany);
900 floatbar->entered = FALSE;
903 if (event->xany.window == floatbar->handle)
904 xf_floatbar_event_focusout(floatbar);
906 xf_floatbar_button_event_focusout(floatbar, &event->xany);
910 case ConfigureNotify:
911 if (event->xany.window == floatbar->handle)
912 xf_floatbar_button_update_positon(floatbar);
917 if (event->xany.window == floatbar->handle)
918 xf_floatbar_button_update_positon(floatbar);
926 return floatbar->handle ==
event->xany.window;
929void xf_floatbar_button_free(xfContext* xfc, xfFloatbarButton* button)
937 WINPR_ASSERT(xfc->display);
938 LogDynAndXUnmapWindow(xfc->log, xfc->display, button->handle);
939 LogDynAndXDestroyWindow(xfc->log, xfc->display, button->handle);
945void xf_floatbar_free(xfFloatbar* floatbar)
948 xfContext* xfc =
nullptr;
953 free(floatbar->title);
957 size = ARRAYSIZE(floatbar->buttons);
959 for (
size_t i = 0; i < size; i++)
961 xf_floatbar_button_free(xfc, floatbar->buttons[i]);
962 floatbar->buttons[i] =
nullptr;
965 if (floatbar->handle)
967 WINPR_ASSERT(xfc->display);
968 LogDynAndXUnmapWindow(xfc->log, xfc->display, floatbar->handle);
969 LogDynAndXDestroyWindow(xfc->log, xfc->display, floatbar->handle);
975BOOL xf_floatbar_is_locked(xfFloatbar* floatbar)
979 return floatbar->mode != XF_FLOATBAR_MODE_NONE;
982BOOL xf_floatbar_is_window(xfFloatbar* floatbar, Window window)
986 if (floatbar->handle == window)
988 return floatbar->entered;
991BOOL xfc_is_floatbar_window(xfContext* xfc, Window window)
993 if (!xfc || !xfc->window)
995 return xf_floatbar_is_window(xfc->window->floatbar, window);