Custom context/popup menus stay on screen

Fix maximized/restored window state
Add support for window allowed actions
This commit is contained in:
toreonify 2024-05-03 08:31:40 +03:00 committed by akallabeth
parent 9b6fcf728a
commit 6ea047558e
5 changed files with 80 additions and 8 deletions

View File

@ -1930,6 +1930,20 @@ BOOL xf_setup_x11(xfContext* xfc)
xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False);
xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds, WINPR_FD_READ);
xfc->_NET_WM_ALLOWED_ACTIONS = XInternAtom(xfc->display, "_NET_WM_ALLOWED_ACTIONS", False);
xfc->_NET_WM_ACTION_CLOSE = XInternAtom(xfc->display, "_NET_WM_ACTION_CLOSE", False);
xfc->_NET_WM_ACTION_MINIMIZE = XInternAtom(xfc->display, "_NET_WM_ACTION_MINIMIZE", False);
xfc->_NET_WM_ACTION_MOVE = XInternAtom(xfc->display, "_NET_WM_ACTION_MOVE", False);
xfc->_NET_WM_ACTION_RESIZE = XInternAtom(xfc->display, "_NET_WM_ACTION_RESIZE", False);
xfc->_NET_WM_ACTION_MAXIMIZE_HORZ =
XInternAtom(xfc->display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False);
xfc->_NET_WM_ACTION_MAXIMIZE_VERT =
XInternAtom(xfc->display, "_NET_WM_ACTION_MAXIMIZE_VERT", False);
xfc->_NET_WM_ACTION_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_ACTION_FULLSCREEN", False);
xfc->_NET_WM_ACTION_CHANGE_DESKTOP =
XInternAtom(xfc->display, "_NET_WM_ACTION_CHANGE_DESKTOP", False);
if (!xfc->x11event)
{
WLog_ERR(TAG, "Could not create xfds event");

View File

@ -106,8 +106,6 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
if (enabled)
xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle);
else
xf_SetWindowStyle(xfc, appWindow, 0, 0);
activate.windowId = appWindow->windowId;
activate.enabled = enabled;
@ -550,6 +548,13 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
visibilityRectsOffsetY, appWindow->visibilityRects,
appWindow->numVisibilityRects);
}
if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
{
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, _NET_WM_STATE_ADD,
xfc->_NET_WM_STATE_MAXIMIZED_VERT, xfc->_NET_WM_STATE_MAXIMIZED_HORZ,
0, 0);
}
}
/* We should only be using the visibility rects for shaping the window */

View File

@ -699,6 +699,8 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
Atom window_type = 0;
BOOL redirect = FALSE;
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
if ((ex_style & WS_EX_NOACTIVATE) || (ex_style & WS_EX_TOOLWINDOW))
{
redirect = TRUE;
@ -714,16 +716,25 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
{
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
}
else if (style & WS_POPUP)
if (style & WS_POPUP)
{
/* this includes dialogs, popups, etc, that need to be full-fledged windows */
appWindow->is_transient = TRUE;
window_type = xfc->_NET_WM_WINDOW_TYPE_DIALOG;
xf_SetWindowUnlisted(xfc, appWindow->handle);
/* this includes dialogs, popups, etc, that need to be full-fledged windows */
if (!((ex_style & WS_EX_DLGMODALFRAME) || (ex_style & WS_EX_LAYERED) ||
(style & WS_SYSMENU)))
{
appWindow->is_transient = TRUE;
redirect = TRUE;
xf_SetWindowUnlisted(xfc, appWindow->handle);
}
}
else
if (!(style == 0 && ex_style == 0))
{
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
xf_SetWindowActions(xfc, appWindow);
}
{
@ -745,6 +756,35 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
XA_ATOM, 32, PropModeReplace, (BYTE*)&window_type, 1);
}
void xf_SetWindowActions(xfContext* xfc, xfAppWindow* appWindow)
{
Atom allowed_actions[] = {
xfc->_NET_WM_ACTION_CLOSE, xfc->_NET_WM_ACTION_MINIMIZE,
xfc->_NET_WM_ACTION_MOVE, xfc->_NET_WM_ACTION_RESIZE,
xfc->_NET_WM_ACTION_MAXIMIZE_HORZ, xfc->_NET_WM_ACTION_MAXIMIZE_VERT,
xfc->_NET_WM_ACTION_FULLSCREEN, xfc->_NET_WM_ACTION_CHANGE_DESKTOP
};
if (!(appWindow->dwStyle & WS_SYSMENU))
allowed_actions[0] = 0;
if (!(appWindow->dwStyle & WS_MINIMIZEBOX))
allowed_actions[1] = 0;
if (!(appWindow->dwStyle & WS_SIZEBOX))
allowed_actions[3] = 0;
if (!(appWindow->dwStyle & WS_MAXIMIZEBOX))
{
allowed_actions[4] = 0;
allowed_actions[5] = 0;
allowed_actions[6] = 0;
}
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_ALLOWED_ACTIONS, XA_ATOM, 32,
PropModeReplace, (unsigned char*)&allowed_actions, 8);
}
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, const char* name)
{
xf_SetWindowTitleText(xfc, appWindow->handle, name);

View File

@ -192,6 +192,7 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX,
UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects);
void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style);
void xf_SetWindowActions(xfContext* xfc, xfAppWindow* appWindow);
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width,
int height);
UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface);

View File

@ -256,6 +256,18 @@ struct xf_context
Atom WM_PROTOCOLS;
Atom WM_DELETE_WINDOW;
/* Allow actions */
Atom _NET_WM_ALLOWED_ACTIONS;
Atom _NET_WM_ACTION_CLOSE;
Atom _NET_WM_ACTION_MINIMIZE;
Atom _NET_WM_ACTION_MOVE;
Atom _NET_WM_ACTION_RESIZE;
Atom _NET_WM_ACTION_MAXIMIZE_HORZ;
Atom _NET_WM_ACTION_MAXIMIZE_VERT;
Atom _NET_WM_ACTION_FULLSCREEN;
Atom _NET_WM_ACTION_CHANGE_DESKTOP;
/* Channels */
#if defined(CHANNEL_TSMF_CLIENT)
TsmfClientContext* tsmf;