From fa7902c362d5df0c2c0b45fa7ebf084a2ca84dcc Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 26 Sep 2018 10:11:52 +0200 Subject: [PATCH 1/4] Fixed argument check for floatbar events. --- client/X11/xf_floatbar.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/client/X11/xf_floatbar.c b/client/X11/xf_floatbar.c index aabfbfb86..33df89142 100644 --- a/client/X11/xf_floatbar.c +++ b/client/X11/xf_floatbar.c @@ -110,7 +110,6 @@ void xf_floatbar_set_root_y(xfContext* xfc, int y) { xfFloatbar* floatbar; floatbar = xfc->window->floatbar; - floatbar->last_motion_y_root = y; } @@ -206,12 +205,11 @@ xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window) int i, width; floatbar = (xfFloatbar*) calloc(1, sizeof(xfFloatbar)); floatbar->locked = TRUE; - XGetWindowAttributes(xfc->display, window, &attr); - for(i = 0; i < xfc->vscreen.nmonitors; i++) + for (i = 0; i < xfc->vscreen.nmonitors; i++) { - if(attr.x >= xfc->vscreen.monitors[i].area.left && attr.x <= xfc->vscreen.monitors[i].area.right) + if (attr.x >= xfc->vscreen.monitors[i].area.left && attr.x <= xfc->vscreen.monitors[i].area.right) { width = xfc->vscreen.monitors[i].area.right - xfc->vscreen.monitors[i].area.left; floatbar->x = width / 2 + xfc->vscreen.monitors[i].area.left - FLOATBAR_DEFAULT_WIDTH / 2; @@ -581,7 +579,11 @@ BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event) { xfFloatbar* floatbar; xfFloatbarButton* button; - int i, size; + size_t i, size; + + if (!xfc || !event || !xfc->window) + return FALSE; + floatbar = xfc->window->floatbar; if (event->xany.window == floatbar->handle) @@ -603,6 +605,10 @@ BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event) BOOL xf_floatbar_event_process(xfContext* xfc, XEvent* event) { xfFloatbar* floatbar; + + if (!xfc || !xfc->window || !event) + return FALSE; + floatbar = xfc->window->floatbar; switch (event->type) @@ -686,7 +692,7 @@ static void xf_floatbar_button_free(xfContext* xfc, xfFloatbarButton* button) void xf_floatbar_free(xfContext* xfc, xfWindow* window, xfFloatbar* floatbar) { - int i, size; + size_t i, size; size = ARRAYSIZE(floatbar->buttons); if (!floatbar) From 316eed1fbf6db65beb2d8e98f6876c3414baff55 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 26 Sep 2018 11:13:06 +0200 Subject: [PATCH 2/4] Menus are no longer popup windows but dropdown menus. --- client/X11/xf_client.c | 2 ++ client/X11/xf_window.c | 16 +--------------- client/X11/xfreerdp.h | 1 + 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index a0804a92e..2492a2d4a 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1858,6 +1858,8 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) "_NET_WM_WINDOW_TYPE_DIALOG", False); xfc->_NET_WM_WINDOW_TYPE_POPUP = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_POPUP", False); + xfc->_NET_WM_WINDOW_TYPE_POPUP_MENU = XInternAtom(xfc->display, + "_NET_WM_WINDOW_TYPE_POPUP_MENU", False); xfc->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_UTILITY", False); xfc->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(xfc->display, diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 7a575909c..2aa9f6b09 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -616,7 +616,6 @@ void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, } XSetWMNormalHints(xfc->display, window->handle, size_hints); - XFree(size_hints); } @@ -659,22 +658,9 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, if ((ex_style & WS_EX_NOACTIVATE) || (ex_style & WS_EX_TOOLWINDOW)) { - /* - * Tooltips and menu items should be unmanaged windows - * (called "override redirect" in X windows parlance) - * If they are managed, there are issues with window focus that - * cause the windows to behave improperly. For example, a mouse - * press will dismiss a drop-down menu because the RDP server - * sees that as a focus out event from the window owning the - * dropdown. - */ - XSetWindowAttributes attrs; - attrs.override_redirect = True; - XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, - &attrs); appWindow->is_transient = TRUE; xf_SetWindowUnlisted(xfc, appWindow->handle); - window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP; + window_type = xfc->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU; } /* * TOPMOST window that is not a tool window is treated like a regular window (i.e. task manager). diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 0faf50f24..f9248918c 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -204,6 +204,7 @@ struct xf_context Atom _NET_WM_WINDOW_TYPE_DIALOG; Atom _NET_WM_WINDOW_TYPE_UTILITY; Atom _NET_WM_WINDOW_TYPE_POPUP; + Atom _NET_WM_WINDOW_TYPE_POPUP_MENU; Atom _NET_WM_WINDOW_TYPE_DROPDOWN_MENU; Atom _NET_WM_MOVERESIZE; From a5b689b35dbad536452450a33ad505eb93667b4a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 26 Sep 2018 11:27:57 +0200 Subject: [PATCH 3/4] Readded override redirect but reset on focus loss. --- client/X11/xf_rail.c | 5 +++++ client/X11/xf_window.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index d03c9fb4b..a39f63624 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -91,6 +91,11 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled) if (!appWindow) return; + if (enabled) + xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle); + else + xf_SetWindowStyle(xfc, appWindow, 0, 0); + activate.windowId = appWindow->windowId; activate.enabled = enabled; xfc->rail->ClientActivate(xfc->rail, &activate); diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 2aa9f6b09..2b639f5ca 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -655,9 +655,11 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style) { Atom window_type; + BOOL redirect = FALSE; if ((ex_style & WS_EX_NOACTIVATE) || (ex_style & WS_EX_TOOLWINDOW)) { + redirect = TRUE; appWindow->is_transient = TRUE; xf_SetWindowUnlisted(xfc, appWindow->handle); window_type = xfc->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU; @@ -682,6 +684,22 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL; } + { + /* + * Tooltips and menu items should be unmanaged windows + * (called "override redirect" in X windows parlance) + * If they are managed, there are issues with window focus that + * cause the windows to behave improperly. For example, a mouse + * press will dismiss a drop-down menu because the RDP server + * sees that as a focus out event from the window owning the + * dropdown. + */ + XSetWindowAttributes attrs; + attrs.override_redirect = redirect ? True : False; + XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, + &attrs); + } + XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1); } From 046d2296a013e346d597da6fb67cf68005f36c33 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 1 Oct 2018 10:49:30 +0200 Subject: [PATCH 4/4] Fixed floatbar X11 leak. --- client/X11/xf_floatbar.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/X11/xf_floatbar.c b/client/X11/xf_floatbar.c index 33df89142..dceb08a92 100644 --- a/client/X11/xf_floatbar.c +++ b/client/X11/xf_floatbar.c @@ -203,6 +203,9 @@ xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window) xfFloatbar* floatbar; XWindowAttributes attr; int i, width; + if (!xfc) + return NULL; + floatbar = (xfFloatbar*) calloc(1, sizeof(xfFloatbar)); floatbar->locked = TRUE; XGetWindowAttributes(xfc->display, window, &attr); @@ -297,6 +300,8 @@ static void xf_floatbar_event_expose(xfContext* xfc, XEvent* event) XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_FOREGROUND)); XDrawString(xfc->display, floatbar->handle, gc, floatbar->width / 2 - len * 2, 15, xfc->context.settings->ServerHostname, len); + XFreeGC(xfc->display, gc); + XFreeGC(xfc->display, shape_gc); } static xfFloatbarButton* xf_floatbar_get_button(xfContext* xfc, XEvent* event)