Merge pull request #10629 from akallabeth/rail-modal
[client,X11] Fix RAILS modal dialog handling
This commit is contained in:
commit
d3a7629734
@ -1938,11 +1938,21 @@ BOOL xf_setup_x11(xfContext* xfc)
|
||||
Logging_XInternAtom(xfc->log, xfc->display, "_NET_CURRENT_DESKTOP", False);
|
||||
xfc->_NET_WORKAREA = Logging_XInternAtom(xfc->log, xfc->display, "_NET_WORKAREA", False);
|
||||
xfc->_NET_WM_STATE = get_supported_atom(xfc, "_NET_WM_STATE");
|
||||
xfc->_NET_WM_STATE_FULLSCREEN = get_supported_atom(xfc, "_NET_WM_STATE_FULLSCREEN");
|
||||
xfc->_NET_WM_STATE_MODAL = get_supported_atom(xfc, "_NET_WM_STATE_MODAL");
|
||||
xfc->_NET_WM_STATE_STICKY = get_supported_atom(xfc, "_NET_WM_STATE_STICKY");
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_HORZ =
|
||||
Logging_XInternAtom(xfc->log, xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_VERT =
|
||||
Logging_XInternAtom(xfc->log, xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
xfc->_NET_WM_STATE_SHADED = get_supported_atom(xfc, "_NET_WM_STATE_SHADED");
|
||||
xfc->_NET_WM_STATE_SKIP_TASKBAR = get_supported_atom(xfc, "_NET_WM_STATE_SKIP_TASKBAR");
|
||||
xfc->_NET_WM_STATE_SKIP_PAGER = get_supported_atom(xfc, "_NET_WM_STATE_SKIP_PAGER");
|
||||
xfc->_NET_WM_STATE_HIDDEN = get_supported_atom(xfc, "_NET_WM_STATE_HIDDEN");
|
||||
xfc->_NET_WM_STATE_FULLSCREEN = get_supported_atom(xfc, "_NET_WM_STATE_FULLSCREEN");
|
||||
xfc->_NET_WM_STATE_ABOVE = get_supported_atom(xfc, "_NET_WM_STATE_ABOVE");
|
||||
xfc->_NET_WM_STATE_BELOW = get_supported_atom(xfc, "_NET_WM_STATE_BELOW");
|
||||
xfc->_NET_WM_STATE_DEMANDS_ATTENTION =
|
||||
get_supported_atom(xfc, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||
xfc->_NET_WM_FULLSCREEN_MONITORS = get_supported_atom(xfc, "_NET_WM_FULLSCREEN_MONITORS");
|
||||
xfc->_NET_WM_NAME = Logging_XInternAtom(xfc->log, xfc->display, "_NET_WM_NAME", False);
|
||||
xfc->_NET_WM_PID = Logging_XInternAtom(xfc->log, xfc->display, "_NET_WM_PID", False);
|
||||
|
@ -273,6 +273,27 @@ BOOL xf_rail_paint(xfContext* xfc, const RECTANGLE_16* rect)
|
||||
return HashTable_Foreach(xfc->railWindows, rail_paint_fn, &arg);
|
||||
}
|
||||
|
||||
#define window_state_log_style(log, windowState) \
|
||||
window_state_log_style_int((log), (windowState), __FILE__, __func__, __LINE__)
|
||||
static void window_state_log_style_int(wLog* log, const WINDOW_STATE_ORDER* windowState,
|
||||
const char* file, const char* fkt, size_t line)
|
||||
{
|
||||
const DWORD log_level = WLOG_DEBUG;
|
||||
|
||||
WINPR_ASSERT(log);
|
||||
WINPR_ASSERT(windowState);
|
||||
if (WLog_IsLevelActive(log, log_level))
|
||||
{
|
||||
char buffer1[128] = { 0 };
|
||||
char buffer2[128] = { 0 };
|
||||
|
||||
window_styles_to_string(windowState->style, buffer1, sizeof(buffer1));
|
||||
window_styles_ex_to_string(windowState->extendedStyle, buffer2, sizeof(buffer2));
|
||||
WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, log_level, line, file, fkt,
|
||||
"windowStyle={%s, %s}", buffer1, buffer2);
|
||||
}
|
||||
}
|
||||
|
||||
/* RemoteApp Core Protocol Extension */
|
||||
|
||||
static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
||||
@ -296,6 +317,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
|
||||
appWindow->dwStyle = windowState->style;
|
||||
appWindow->dwExStyle = windowState->extendedStyle;
|
||||
window_state_log_style(xfc->log, windowState);
|
||||
|
||||
/* Ensure window always gets a window title */
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
|
||||
@ -390,6 +412,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
{
|
||||
appWindow->dwStyle = windowState->style;
|
||||
appWindow->dwExStyle = windowState->extendedStyle;
|
||||
window_state_log_style(xfc->log, windowState);
|
||||
}
|
||||
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
|
||||
@ -557,6 +580,9 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
}
|
||||
}
|
||||
|
||||
if ((fieldFlags & WINDOW_ORDER_STATE_NEW) == 0)
|
||||
xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle);
|
||||
|
||||
/* We should only be using the visibility rects for shaping the window */
|
||||
/*if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
|
||||
{
|
||||
|
@ -226,3 +226,13 @@ fail:
|
||||
pclose(keyScript);
|
||||
return rc;
|
||||
}
|
||||
|
||||
const char* x11_error_to_string(xfContext* xfc, int error, char* buffer, size_t size)
|
||||
{
|
||||
WINPR_ASSERT(xfc);
|
||||
WINPR_ASSERT(size <= INT32_MAX);
|
||||
const int rc = XGetErrorText(xfc->display, error, buffer, (int)size);
|
||||
if (rc)
|
||||
WLog_WARN(TAG, "XGetErrorText returned %d", rc);
|
||||
return buffer;
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include "xfreerdp.h"
|
||||
|
||||
const char* x11_error_to_string(xfContext* xfc, int error, char* buffer, size_t size);
|
||||
|
||||
#define X_GET_ATOM_VAR_NAME(x) #x
|
||||
#define Safe_XGetAtomName(log, display, atom) \
|
||||
Safe_XGetAtomNameEx((log), (display), (atom), X_GET_ATOM_VAR_NAME(atom))
|
||||
|
@ -99,6 +99,10 @@
|
||||
|
||||
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
|
||||
|
||||
#define ENTRY(x) \
|
||||
case x: \
|
||||
return #x
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -108,6 +112,114 @@ typedef struct
|
||||
unsigned long status;
|
||||
} PropMotifWmHints;
|
||||
|
||||
static void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window);
|
||||
|
||||
static const char* window_style_to_string(UINT32 style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
ENTRY(WS_NONE);
|
||||
ENTRY(WS_BORDER);
|
||||
ENTRY(WS_CAPTION);
|
||||
ENTRY(WS_CHILD);
|
||||
ENTRY(WS_CLIPCHILDREN);
|
||||
ENTRY(WS_CLIPSIBLINGS);
|
||||
ENTRY(WS_DISABLED);
|
||||
ENTRY(WS_DLGFRAME);
|
||||
ENTRY(WS_GROUP);
|
||||
ENTRY(WS_HSCROLL);
|
||||
ENTRY(WS_MAXIMIZE);
|
||||
ENTRY(WS_MAXIMIZEBOX);
|
||||
ENTRY(WS_MINIMIZE);
|
||||
ENTRY(WS_OVERLAPPEDWINDOW);
|
||||
ENTRY(WS_POPUP);
|
||||
ENTRY(WS_POPUPWINDOW);
|
||||
ENTRY(WS_SIZEBOX);
|
||||
ENTRY(WS_SYSMENU);
|
||||
ENTRY(WS_VISIBLE);
|
||||
ENTRY(WS_VSCROLL);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length)
|
||||
{
|
||||
(void)_snprintf(buffer, length, "style[0x%08" PRIx32 "] {", style);
|
||||
const char* sep = "";
|
||||
for (size_t x = 0; x < 32; x++)
|
||||
{
|
||||
const UINT32 val = 1 << x;
|
||||
if ((style & val) != 0)
|
||||
{
|
||||
const char* str = window_style_to_string(val);
|
||||
if (str)
|
||||
{
|
||||
winpr_str_append(str, buffer, length, sep);
|
||||
sep = "|";
|
||||
}
|
||||
}
|
||||
}
|
||||
winpr_str_append("}", buffer, length, "");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char* window_style_ex_to_string(UINT32 styleEx)
|
||||
{
|
||||
switch (styleEx)
|
||||
{
|
||||
ENTRY(WS_EX_ACCEPTFILES);
|
||||
ENTRY(WS_EX_APPWINDOW);
|
||||
ENTRY(WS_EX_CLIENTEDGE);
|
||||
ENTRY(WS_EX_COMPOSITED);
|
||||
ENTRY(WS_EX_CONTEXTHELP);
|
||||
ENTRY(WS_EX_CONTROLPARENT);
|
||||
ENTRY(WS_EX_DLGMODALFRAME);
|
||||
ENTRY(WS_EX_LAYERED);
|
||||
ENTRY(WS_EX_LAYOUTRTL);
|
||||
ENTRY(WS_EX_LEFTSCROLLBAR);
|
||||
ENTRY(WS_EX_MDICHILD);
|
||||
ENTRY(WS_EX_NOACTIVATE);
|
||||
ENTRY(WS_EX_NOINHERITLAYOUT);
|
||||
ENTRY(WS_EX_NOPARENTNOTIFY);
|
||||
ENTRY(WS_EX_OVERLAPPEDWINDOW);
|
||||
ENTRY(WS_EX_PALETTEWINDOW);
|
||||
ENTRY(WS_EX_RIGHT);
|
||||
ENTRY(WS_EX_RIGHTSCROLLBAR);
|
||||
ENTRY(WS_EX_RTLREADING);
|
||||
ENTRY(WS_EX_STATICEDGE);
|
||||
ENTRY(WS_EX_TOOLWINDOW);
|
||||
ENTRY(WS_EX_TOPMOST);
|
||||
ENTRY(WS_EX_TRANSPARENT);
|
||||
ENTRY(WS_EX_WINDOWEDGE);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* window_styles_ex_to_string(UINT32 styleEx, char* buffer, size_t length)
|
||||
{
|
||||
(void)_snprintf(buffer, length, "styleEx[0x%08" PRIx32 "] {", styleEx);
|
||||
const char* sep = "";
|
||||
for (size_t x = 0; x < 32; x++)
|
||||
{
|
||||
const UINT32 val = 1 << x;
|
||||
if ((styleEx & val) != 0)
|
||||
{
|
||||
const char* str = window_style_ex_to_string(val);
|
||||
if (str)
|
||||
{
|
||||
winpr_str_append(str, buffer, length, sep);
|
||||
sep = "|";
|
||||
}
|
||||
}
|
||||
}
|
||||
winpr_str_append("}", buffer, length, "");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void xf_SetWindowTitleText(xfContext* xfc, Window window, const char* name)
|
||||
{
|
||||
WINPR_ASSERT(xfc);
|
||||
@ -749,13 +861,27 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
|
||||
* sees that as a focus out event from the window owning the
|
||||
* dropdown.
|
||||
*/
|
||||
XSetWindowAttributes attrs;
|
||||
XSetWindowAttributes attrs = { 0 };
|
||||
attrs.override_redirect = redirect ? True : False;
|
||||
XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, &attrs);
|
||||
}
|
||||
|
||||
LogTagAndXChangeProperty(TAG, xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
|
||||
XA_ATOM, 32, PropModeReplace, (BYTE*)&window_type, 1);
|
||||
|
||||
if (ex_style & (WS_EX_CONTROLPARENT | WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME))
|
||||
xf_XSetTransientForHint(xfc, appWindow);
|
||||
|
||||
if (((ex_style & WS_EX_TOPMOST) != 0) && ((ex_style & WS_EX_TOOLWINDOW) == 0))
|
||||
{
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, _NET_WM_STATE_ADD,
|
||||
xfc->_NET_WM_STATE_ABOVE, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, _NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_ABOVE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_SetWindowActions(xfContext* xfc, xfAppWindow* appWindow)
|
||||
@ -1364,3 +1490,24 @@ BOOL xf_AppWindowResize(xfContext* xfc, xfAppWindow* appWindow)
|
||||
|
||||
return appWindow->pixmap != 0;
|
||||
}
|
||||
|
||||
void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
|
||||
{
|
||||
WINPR_ASSERT(xfc);
|
||||
WINPR_ASSERT(window);
|
||||
|
||||
if (window->ownerWindowId == 0)
|
||||
return;
|
||||
|
||||
xfAppWindow* parent = xf_rail_get_window(xfc, window->ownerWindowId);
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
const int rc = XSetTransientForHint(xfc->display, window->handle, parent->handle);
|
||||
if (rc)
|
||||
{
|
||||
char buffer[128] = { 0 };
|
||||
WLog_WARN(TAG, "XSetTransientForHint [%d]{%s}", rc,
|
||||
x11_error_to_string(xfc, rc, buffer, sizeof(buffer)));
|
||||
}
|
||||
}
|
||||
|
@ -205,4 +205,7 @@ void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction
|
||||
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
|
||||
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd);
|
||||
|
||||
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length);
|
||||
const char* window_styles_ex_to_string(UINT32 styleEx, char* buffer, size_t length);
|
||||
|
||||
#endif /* FREERDP_CLIENT_X11_WINDOW_H */
|
||||
|
@ -230,11 +230,18 @@ struct xf_context
|
||||
Atom _NET_SUPPORTING_WM_CHECK;
|
||||
|
||||
Atom _NET_WM_STATE;
|
||||
Atom _NET_WM_STATE_FULLSCREEN;
|
||||
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
Atom _NET_WM_STATE_MODAL;
|
||||
Atom _NET_WM_STATE_STICKY;
|
||||
Atom _NET_WM_STATE_MAXIMIZED_VERT;
|
||||
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||
Atom _NET_WM_STATE_SHADED;
|
||||
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||
Atom _NET_WM_STATE_HIDDEN;
|
||||
Atom _NET_WM_STATE_FULLSCREEN;
|
||||
Atom _NET_WM_STATE_ABOVE;
|
||||
Atom _NET_WM_STATE_BELOW;
|
||||
Atom _NET_WM_STATE_DEMANDS_ATTENTION;
|
||||
|
||||
Atom _NET_WM_FULLSCREEN_MONITORS;
|
||||
|
||||
|
@ -80,9 +80,11 @@
|
||||
|
||||
/* Window Styles */
|
||||
#ifndef _WIN32
|
||||
#define WS_NONE 0x00000000
|
||||
#define WS_BORDER 0x00800000
|
||||
#define WS_CAPTION 0x00C00000
|
||||
#define WS_CHILD 0x40000000
|
||||
#define WS_CHILDWINDOW 0x40000000
|
||||
#define WS_CLIPCHILDREN 0x02000000
|
||||
#define WS_CLIPSIBLINGS 0x04000000
|
||||
#define WS_DISABLED 0x08000000
|
||||
@ -105,10 +107,13 @@
|
||||
#define WS_THICKFRAME 0x00040000
|
||||
#define WS_VISIBLE 0x10000000
|
||||
#define WS_VSCROLL 0x00200000
|
||||
#define WS_TILEDWINDOW \
|
||||
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
|
||||
#endif
|
||||
|
||||
/* Extended Window Styles */
|
||||
#ifndef _WIN32
|
||||
#define WS_EX_NONE 0x00000000
|
||||
#define WS_EX_ACCEPTFILES 0x00000010
|
||||
#define WS_EX_APPWINDOW 0x00040000
|
||||
#define WS_EX_CLIENTEDGE 0x00000200
|
||||
@ -125,6 +130,7 @@
|
||||
#define WS_EX_NOACTIVATE 0x08000000
|
||||
#define WS_EX_NOINHERITLAYOUT 0x00100000
|
||||
#define WS_EX_NOPARENTNOTIFY 0x00000004
|
||||
#define WS_EX_NOREDIRECTIONBITMAP 0x00200000
|
||||
#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
|
||||
#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
|
||||
#define WS_EX_RIGHT 0x00001000
|
||||
|
Loading…
Reference in New Issue
Block a user