Make popups transient, use local window manager for moves.
This fixes a number if issues on Ubuntu in particular.
This commit is contained in:
parent
31cbac201d
commit
8f38bdb87a
@ -24,6 +24,7 @@
|
|||||||
#include <freerdp/kbd/vkcodes.h>
|
#include <freerdp/kbd/vkcodes.h>
|
||||||
|
|
||||||
#include "xf_rail.h"
|
#include "xf_rail.h"
|
||||||
|
#include "xf_window.h"
|
||||||
#include "xf_cliprdr.h"
|
#include "xf_cliprdr.h"
|
||||||
|
|
||||||
#include "xf_event.h"
|
#include "xf_event.h"
|
||||||
@ -340,7 +341,7 @@ boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
xf_rail_send_activate(xfi, event->xany.window, true);
|
xf_rail_send_activate(xfi, event->xany.window, true);
|
||||||
xf_kbd_focus_in(xfi);
|
xf_kbd_focus_in(xfi);
|
||||||
|
|
||||||
if (xfi->remote_app != true)
|
if (app != true)
|
||||||
xf_cliprdr_check_owner(xfi);
|
xf_cliprdr_check_owner(xfi);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -462,7 +463,7 @@ boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
xfw->bottom = xfw->top + xfw->height - 1;
|
xfw->bottom = xfw->top + xfw->height - 1;
|
||||||
|
|
||||||
if (app)
|
if (app)
|
||||||
xf_rail_local_movesize(xfi, xfw);
|
xf_rail_adjust_position(xfi, window);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,7 +485,7 @@ boolean xf_event_MapNotify(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
/* local restore event */
|
/* local restore event */
|
||||||
xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE);
|
xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE);
|
||||||
xfWindow *xfw = (xfWindow*) window->extra;
|
xfWindow *xfw = (xfWindow*) window->extra;
|
||||||
xfw->isMapped = true;
|
xfw->is_mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -503,7 +504,7 @@ boolean xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
{
|
{
|
||||||
xfWindow *xfw = (xfWindow*) window->extra;
|
xfWindow *xfw = (xfWindow*) window->extra;
|
||||||
xfw->isMapped = false;
|
xfw->is_mapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -511,7 +512,7 @@ boolean xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
|
|
||||||
boolean xf_event_SelectionNotify(xfInfo* xfi, XEvent* event, boolean app)
|
boolean xf_event_SelectionNotify(xfInfo* xfi, XEvent* event, boolean app)
|
||||||
{
|
{
|
||||||
if (xfi->remote_app != true)
|
if (app != true)
|
||||||
{
|
{
|
||||||
if (xf_cliprdr_process_selection_notify(xfi, event))
|
if (xf_cliprdr_process_selection_notify(xfi, event))
|
||||||
return true;
|
return true;
|
||||||
@ -522,7 +523,7 @@ boolean xf_event_SelectionNotify(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
|
|
||||||
boolean xf_event_SelectionRequest(xfInfo* xfi, XEvent* event, boolean app)
|
boolean xf_event_SelectionRequest(xfInfo* xfi, XEvent* event, boolean app)
|
||||||
{
|
{
|
||||||
if (xfi->remote_app != true)
|
if (app != true)
|
||||||
{
|
{
|
||||||
if (xf_cliprdr_process_selection_request(xfi, event))
|
if (xf_cliprdr_process_selection_request(xfi, event))
|
||||||
return true;
|
return true;
|
||||||
@ -533,7 +534,7 @@ boolean xf_event_SelectionRequest(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
|
|
||||||
boolean xf_event_SelectionClear(xfInfo* xfi, XEvent* event, boolean app)
|
boolean xf_event_SelectionClear(xfInfo* xfi, XEvent* event, boolean app)
|
||||||
{
|
{
|
||||||
if (xfi->remote_app != true)
|
if (app != true)
|
||||||
{
|
{
|
||||||
if (xf_cliprdr_process_selection_clear(xfi, event))
|
if (xf_cliprdr_process_selection_clear(xfi, event))
|
||||||
return true;
|
return true;
|
||||||
@ -544,7 +545,7 @@ boolean xf_event_SelectionClear(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
|
|
||||||
boolean xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, boolean app)
|
boolean xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, boolean app)
|
||||||
{
|
{
|
||||||
if (xfi->remote_app != true)
|
if (app != true)
|
||||||
{
|
{
|
||||||
if (xf_cliprdr_process_property_notify(xfi, event))
|
if (xf_cliprdr_process_property_notify(xfi, event))
|
||||||
return true;
|
return true;
|
||||||
@ -555,20 +556,71 @@ boolean xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, boolean app)
|
|||||||
|
|
||||||
boolean xf_event_process(freerdp* instance, XEvent* event)
|
boolean xf_event_process(freerdp* instance, XEvent* event)
|
||||||
{
|
{
|
||||||
boolean app = false;
|
|
||||||
boolean status = true;
|
boolean status = true;
|
||||||
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
|
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
|
||||||
|
|
||||||
if (xfi->remote_app == true)
|
if (xfi->window && xfi->window->local_move.state == LMS_ACTIVE)
|
||||||
{
|
{
|
||||||
app = true;
|
xfWindow* xfw;
|
||||||
|
rdpWindow* window;
|
||||||
|
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
|
||||||
|
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
|
||||||
|
if (window != NULL)
|
||||||
|
{
|
||||||
|
xfw = (xfWindow*) window->extra;
|
||||||
|
xfi->window = xfw;
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case ButtonPress:
|
||||||
|
case ButtonRelease:
|
||||||
|
case KeyPress:
|
||||||
|
case KeyRelease:
|
||||||
|
case UnmapNotify:
|
||||||
|
{
|
||||||
|
// A button release event means the X window server did not grab the
|
||||||
|
// mouse before the user released it. In this case we must cancel
|
||||||
|
// the local move. The event will be processed below as normal, below.
|
||||||
|
xf_EndLocalMoveSize(xfi, xfw, true);
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
|
|
||||||
|
case FocusIn:
|
||||||
|
case FocusOut:
|
||||||
{
|
{
|
||||||
if (event->xany.window != xfi->window->handle)
|
XFocusChangeEvent *focusEvent = (XFocusChangeEvent *)event;
|
||||||
app = true;
|
if (focusEvent->mode == NotifyUngrab)
|
||||||
|
xf_rail_end_local_move(xfi, window);
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EnterNotify:
|
||||||
|
case LeaveNotify:
|
||||||
|
{
|
||||||
|
XCrossingEvent *crossingEvent = (XCrossingEvent *)event;
|
||||||
|
if(crossingEvent->mode == NotifyUngrab)
|
||||||
|
xf_rail_end_local_move(xfi, window);
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VisibilityNotify:
|
||||||
|
case ConfigureNotify:
|
||||||
|
case Expose:
|
||||||
|
case PropertyNotify:
|
||||||
|
// Allow these events to be processed during move to keep
|
||||||
|
// our state up to date.
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Any other event should signify the root no longer
|
||||||
|
// has the grap, so the move has finished.
|
||||||
|
xf_rail_end_local_move(xfi, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (event->type != MotionNotify)
|
if (event->type != MotionNotify)
|
||||||
DEBUG_X11("%s Event: wnd=0x%04X", X11_EVENT_STRINGS[event->type], (uint32) event->xany.window);
|
DEBUG_X11("%s Event: wnd=0x%04X", X11_EVENT_STRINGS[event->type], (uint32) event->xany.window);
|
||||||
@ -576,47 +628,47 @@ boolean xf_event_process(freerdp* instance, XEvent* event)
|
|||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case Expose:
|
case Expose:
|
||||||
status = xf_event_Expose(xfi, event, app);
|
status = xf_event_Expose(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VisibilityNotify:
|
case VisibilityNotify:
|
||||||
status = xf_event_VisibilityNotify(xfi, event, app);
|
status = xf_event_VisibilityNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
status = xf_event_MotionNotify(xfi, event, app);
|
status = xf_event_MotionNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
status = xf_event_ButtonPress(xfi, event, app);
|
status = xf_event_ButtonPress(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
status = xf_event_ButtonRelease(xfi, event, app);
|
status = xf_event_ButtonRelease(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
status = xf_event_KeyPress(xfi, event, app);
|
status = xf_event_KeyPress(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
status = xf_event_KeyRelease(xfi, event, app);
|
status = xf_event_KeyRelease(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
status = xf_event_FocusIn(xfi, event, app);
|
status = xf_event_FocusIn(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
status = xf_event_FocusOut(xfi, event, app);
|
status = xf_event_FocusOut(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
status = xf_event_EnterNotify(xfi, event, app);
|
status = xf_event_EnterNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
status = xf_event_LeaveNotify(xfi, event, app);
|
status = xf_event_LeaveNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NoExpose:
|
case NoExpose:
|
||||||
@ -626,42 +678,42 @@ boolean xf_event_process(freerdp* instance, XEvent* event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
status = xf_event_ConfigureNotify(xfi, event, app);
|
status = xf_event_ConfigureNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
status = xf_event_MapNotify(xfi, event, app);
|
status = xf_event_MapNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UnmapNotify:
|
case UnmapNotify:
|
||||||
status = xf_event_UnmapNotify(xfi, event, app);
|
status = xf_event_UnmapNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ReparentNotify:
|
case ReparentNotify:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MappingNotify:
|
case MappingNotify:
|
||||||
status = xf_event_MappingNotify(xfi, event, app);
|
status = xf_event_MappingNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
status = xf_event_ClientMessage(xfi, event, app);
|
status = xf_event_ClientMessage(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
status = xf_event_SelectionNotify(xfi, event, app);
|
status = xf_event_SelectionNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionRequest:
|
case SelectionRequest:
|
||||||
status = xf_event_SelectionRequest(xfi, event, app);
|
status = xf_event_SelectionRequest(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionClear:
|
case SelectionClear:
|
||||||
status = xf_event_SelectionClear(xfi, event, app);
|
status = xf_event_SelectionClear(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
status = xf_event_PropertyNotify(xfi, event, app);
|
status = xf_event_PropertyNotify(xfi, event, xfi->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -108,39 +108,6 @@ void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
|
|||||||
window->windowWidth, window->windowHeight);
|
window->windowWidth, window->windowHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The position of the X window can become out of sync with the RDP window
|
|
||||||
* if the X window is moved locally by the window manager. In this event
|
|
||||||
* send an update to the RDP server informing it of the new window position
|
|
||||||
* and size.
|
|
||||||
*/
|
|
||||||
void xf_rail_local_movesize(xfInfo* xfi, xfWindow* window)
|
|
||||||
{
|
|
||||||
rdpWindow* wnd = window->window;
|
|
||||||
|
|
||||||
if (window->isMapped)
|
|
||||||
{
|
|
||||||
// If current window position disagrees with RDP window position, send
|
|
||||||
// update to RDP server
|
|
||||||
if ( window->left != wnd->windowOffsetX ||
|
|
||||||
window->top != wnd->windowOffsetY ||
|
|
||||||
window->width != wnd->windowWidth ||
|
|
||||||
window->height != wnd->windowHeight)
|
|
||||||
{
|
|
||||||
xf_rail_send_windowmove(xfi, wnd->windowId,
|
|
||||||
window->left, window->top, window->right+1, window->bottom+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u"
|
|
||||||
" RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
|
|
||||||
(uint32) window->handle, window->left, window->top,
|
|
||||||
window->right, window->bottom, window->width, window->height,
|
|
||||||
wnd->windowId,
|
|
||||||
wnd->windowOffsetX, wnd->windowOffsetY,
|
|
||||||
wnd->windowWidth, wnd->windowHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xf_rail_ShowWindow(rdpRail* rail, rdpWindow* window, uint8 state)
|
void xf_rail_ShowWindow(rdpRail* rail, rdpWindow* window, uint8 state)
|
||||||
{
|
{
|
||||||
xfInfo* xfi;
|
xfInfo* xfi;
|
||||||
@ -241,22 +208,6 @@ static void xf_send_rail_client_event(rdpChannels* channels, uint16 event_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_rail_send_windowmove(xfInfo* xfi, uint32 windowId, uint32 left, uint32 top, uint32 right, uint32 bottom)
|
|
||||||
{
|
|
||||||
rdpChannels* channels;
|
|
||||||
RAIL_WINDOW_MOVE_ORDER window_move;
|
|
||||||
|
|
||||||
channels = xfi->_context->channels;
|
|
||||||
|
|
||||||
window_move.windowId = windowId;
|
|
||||||
window_move.left = left;
|
|
||||||
window_move.top = top;
|
|
||||||
window_move.right = right;
|
|
||||||
window_move.bottom = bottom;
|
|
||||||
|
|
||||||
xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move);
|
|
||||||
}
|
|
||||||
|
|
||||||
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled)
|
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled)
|
||||||
{
|
{
|
||||||
rdpRail* rail;
|
rdpRail* rail;
|
||||||
@ -291,6 +242,84 @@ void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 com
|
|||||||
xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, &syscommand);
|
xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, &syscommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of the X window can become out of sync with the RDP window
|
||||||
|
* if the X window is moved locally by the window manager. In this event
|
||||||
|
* send an update to the RDP server informing it of the new window position
|
||||||
|
* and size.
|
||||||
|
*/
|
||||||
|
void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window)
|
||||||
|
{
|
||||||
|
xfWindow* xfw;
|
||||||
|
rdpChannels* channels;
|
||||||
|
RAIL_WINDOW_MOVE_ORDER window_move;
|
||||||
|
|
||||||
|
xfw = (xfWindow*) window->extra;
|
||||||
|
channels = xfi->_context->channels;
|
||||||
|
|
||||||
|
if (! xfw->is_mapped || xfw->local_move.state != LMS_NOT_ACTIVE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u"
|
||||||
|
" RDP=0x%X rc={l=%d t=%d} w=%d h=%d lms_state=%d mapped=%d",
|
||||||
|
(uint32) xfw->handle, xfw->left, xfw->top,
|
||||||
|
xfw->right, xfw->bottom, xfw->width, xfw->height,
|
||||||
|
window->windowId,
|
||||||
|
window->windowOffsetX, window->windowOffsetY,
|
||||||
|
window->windowWidth, window->windowHeight,
|
||||||
|
xfw->local_move.state, xfw->is_mapped);
|
||||||
|
|
||||||
|
// If current window position disagrees with RDP window position, send
|
||||||
|
// update to RDP server
|
||||||
|
if ( xfw->left != window->windowOffsetX ||
|
||||||
|
xfw->top != window->windowOffsetY ||
|
||||||
|
xfw->width != window->windowWidth ||
|
||||||
|
xfw->height != window->windowHeight)
|
||||||
|
{
|
||||||
|
window_move.windowId = window->windowId;
|
||||||
|
window_move.left = xfw->left;
|
||||||
|
window_move.top = xfw->top;
|
||||||
|
window_move.right = xfw->right;
|
||||||
|
window_move.bottom = xfw->bottom;
|
||||||
|
|
||||||
|
xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window)
|
||||||
|
{
|
||||||
|
xfWindow* xfw;
|
||||||
|
rdpChannels* channels;
|
||||||
|
RAIL_WINDOW_MOVE_ORDER window_move;
|
||||||
|
int x,y;
|
||||||
|
rdpInput* input = xfi->instance->input;
|
||||||
|
|
||||||
|
xfw = (xfWindow*) window->extra;
|
||||||
|
channels = xfi->_context->channels;
|
||||||
|
|
||||||
|
// Send RDP client event to inform RDP server
|
||||||
|
|
||||||
|
window_move.windowId = window->windowId;
|
||||||
|
window_move.left = xfw->left;
|
||||||
|
window_move.top = xfw->top;
|
||||||
|
window_move.right = xfw->right + 1; // In the update to RDP the position is one past the window
|
||||||
|
window_move.bottom = xfw->bottom + 1;
|
||||||
|
|
||||||
|
DEBUG_X11_LMS("ClientWindowMove: window=0x%X rc={l=%d t=%d r=%d b=%d}",
|
||||||
|
(uint32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom);
|
||||||
|
|
||||||
|
xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move);
|
||||||
|
|
||||||
|
// Send synthetic button up event to the RDP server. This is per the RDP spec to
|
||||||
|
// indicate a local move has finished.
|
||||||
|
|
||||||
|
x = xfw->left + xfw->local_move.window_x;
|
||||||
|
y = xfw->top + xfw->local_move.window_y;
|
||||||
|
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
|
||||||
|
|
||||||
|
xfw->local_move.state = LMS_TERMINATING;
|
||||||
|
}
|
||||||
|
|
||||||
void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event)
|
void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event)
|
||||||
{
|
{
|
||||||
RAIL_SYSPARAM_ORDER* sysparam;
|
RAIL_SYSPARAM_ORDER* sysparam;
|
||||||
@ -398,14 +427,16 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channe
|
|||||||
rdpWindow* rail_window = NULL;
|
rdpWindow* rail_window = NULL;
|
||||||
RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->user_data;
|
RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->user_data;
|
||||||
int direction = 0;
|
int direction = 0;
|
||||||
|
Window child_window;
|
||||||
|
int x,y;
|
||||||
|
|
||||||
rail = ((rdpContext*) xfi->context)->rail;
|
rail = ((rdpContext*) xfi->context)->rail;
|
||||||
rail_window = window_list_get_by_id(rail->list, movesize->windowId);
|
rail_window = window_list_get_by_id(rail->list, movesize->windowId);
|
||||||
|
|
||||||
if (rail_window != NULL)
|
if (rail_window != NULL)
|
||||||
{
|
{
|
||||||
xfWindow* window = NULL;
|
xfWindow* xfw = NULL;
|
||||||
window = (xfWindow*) rail_window->extra;
|
xfw = (xfWindow*) rail_window->extra;
|
||||||
|
|
||||||
DEBUG_X11_LMS("windowId=0x%X isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d",
|
DEBUG_X11_LMS("windowId=0x%X isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d",
|
||||||
movesize->windowId, movesize->isMoveSizeStart,
|
movesize->windowId, movesize->isMoveSizeStart,
|
||||||
@ -415,44 +446,68 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channe
|
|||||||
{
|
{
|
||||||
case RAIL_WMSZ_LEFT: //0x1
|
case RAIL_WMSZ_LEFT: //0x1
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
|
direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_RIGHT: //0x2
|
case RAIL_WMSZ_RIGHT: //0x2
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
|
direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_TOP: //0x3
|
case RAIL_WMSZ_TOP: //0x3
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_TOP;
|
direction = _NET_WM_MOVERESIZE_SIZE_TOP;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_TOPLEFT: //0x4
|
case RAIL_WMSZ_TOPLEFT: //0x4
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
|
direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_TOPRIGHT: //0x5
|
case RAIL_WMSZ_TOPRIGHT: //0x5
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
|
direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_BOTTOM: //0x6
|
case RAIL_WMSZ_BOTTOM: //0x6
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
|
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_BOTTOMLEFT: //0x7
|
case RAIL_WMSZ_BOTTOMLEFT: //0x7
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
|
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_BOTTOMRIGHT: //0x8
|
case RAIL_WMSZ_BOTTOMRIGHT: //0x8
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
|
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_MOVE: //0x9
|
case RAIL_WMSZ_MOVE: //0x9
|
||||||
direction = _NET_WM_MOVERESIZE_MOVE;
|
direction = _NET_WM_MOVERESIZE_MOVE;
|
||||||
|
XTranslateCoordinates(xfi->display, xfw->handle, DefaultRootWindow(xfi->display),
|
||||||
|
movesize->posX, movesize->posY, &x, &y, &child_window);
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_KEYMOVE: //0xA
|
case RAIL_WMSZ_KEYMOVE: //0xA
|
||||||
direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
|
direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
case RAIL_WMSZ_KEYSIZE: //0xB
|
case RAIL_WMSZ_KEYSIZE: //0xB
|
||||||
direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
|
direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
|
||||||
|
x = movesize->posX;
|
||||||
|
y = movesize->posY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movesize->isMoveSizeStart)
|
if (movesize->isMoveSizeStart)
|
||||||
{
|
{
|
||||||
xf_StartLocalMoveSize(xfi, window, direction, movesize->posX, movesize->posY);
|
xf_StartLocalMoveSize(xfi, xfw, direction, x, y);
|
||||||
} else {
|
} else {
|
||||||
xf_EndLocalMoveSize(xfi, window, True);
|
xf_MoveWindow(xfi, xfw, movesize->posX, movesize->posY,
|
||||||
|
xfw->width, xfw->height);
|
||||||
|
xf_EndLocalMoveSize(xfi, xfw, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,8 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, uint32 uleft, uint32 utop, uint32
|
|||||||
void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail);
|
void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail);
|
||||||
void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 command);
|
void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 command);
|
||||||
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled);
|
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled);
|
||||||
void xf_rail_send_windowmove(xfInfo* xfi, uint32 windowId, uint32 left, uint32 top, uint32 right, uint32 bottom);
|
|
||||||
void xf_process_rail_event(xfInfo* xfi, rdpChannels* chanman, RDP_EVENT* event);
|
void xf_process_rail_event(xfInfo* xfi, rdpChannels* chanman, RDP_EVENT* event);
|
||||||
void xf_rail_local_movesize(xfInfo* xfi, xfWindow* window);
|
void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window);
|
||||||
|
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window);
|
||||||
|
|
||||||
#endif /* __XF_RAIL_H */
|
#endif /* __XF_RAIL_H */
|
||||||
|
@ -37,7 +37,29 @@
|
|||||||
|
|
||||||
/* Extended Window Manager Hints: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html */
|
/* Extended Window Manager Hints: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html */
|
||||||
|
|
||||||
|
/* bit definitions for MwmHints.flags */
|
||||||
|
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
||||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||||
|
#define MWM_HINTS_INPUT_MODE (1L << 2)
|
||||||
|
#define MWM_HINTS_STATUS (1L << 3)
|
||||||
|
|
||||||
|
/* bit definitions for MwmHints.functions */
|
||||||
|
#define MWM_FUNC_ALL (1L << 0)
|
||||||
|
#define MWM_FUNC_RESIZE (1L << 1)
|
||||||
|
#define MWM_FUNC_MOVE (1L << 2)
|
||||||
|
#define MWM_FUNC_MINIMIZE (1L << 3)
|
||||||
|
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
||||||
|
#define MWM_FUNC_CLOSE (1L << 5)
|
||||||
|
|
||||||
|
/* bit definitions for MwmHints.decorations */
|
||||||
|
#define MWM_DECOR_ALL (1L << 0)
|
||||||
|
#define MWM_DECOR_BORDER (1L << 1)
|
||||||
|
#define MWM_DECOR_RESIZEH (1L << 2)
|
||||||
|
#define MWM_DECOR_TITLE (1L << 3)
|
||||||
|
#define MWM_DECOR_MENU (1L << 4)
|
||||||
|
#define MWM_DECOR_MINIMIZE (1L << 5)
|
||||||
|
#define MWM_DECOR_MAXIMIZE (1L << 6)
|
||||||
|
|
||||||
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
|
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
|
||||||
|
|
||||||
struct _PropMotifWmHints
|
struct _PropMotifWmHints
|
||||||
@ -75,7 +97,8 @@ void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int n
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_X11("Send ClientMessage Event: wnd=0x%04X", (unsigned int) xevent.xclient.window);
|
DEBUG_X11("Send ClientMessage Event: wnd=0x%04X", (unsigned int) xevent.xclient.window);
|
||||||
XSendEvent(xfi->display, window->handle, False, NoEventMask, &xevent);
|
XSendEvent(xfi->display, DefaultRootWindow(xfi->display), False,
|
||||||
|
SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
|
||||||
XSync(xfi->display, False);
|
XSync(xfi->display, False);
|
||||||
|
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
@ -181,8 +204,9 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show)
|
|||||||
{
|
{
|
||||||
PropMotifWmHints hints;
|
PropMotifWmHints hints;
|
||||||
|
|
||||||
hints.decorations = show;
|
hints.decorations = (show) ? MWM_DECOR_ALL : 0;
|
||||||
hints.flags = MWM_HINTS_DECORATIONS;
|
hints.functions = MWM_FUNC_ALL ;
|
||||||
|
hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
|
||||||
|
|
||||||
XChangeProperty(xfi->display, window->handle, xfi->_MOTIF_WM_HINTS, xfi->_MOTIF_WM_HINTS, 32,
|
XChangeProperty(xfi->display, window->handle, xfi->_MOTIF_WM_HINTS, xfi->_MOTIF_WM_HINTS, 32,
|
||||||
PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
|
PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
|
||||||
@ -203,21 +227,27 @@ void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_st
|
|||||||
{
|
{
|
||||||
Atom window_type;
|
Atom window_type;
|
||||||
|
|
||||||
window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL;
|
if (style & WS_POPUP)
|
||||||
|
|
||||||
if ((style & WS_POPUP) || (style & WS_DLGFRAME) || (ex_style & WS_EX_DLGMODALFRAME))
|
|
||||||
{
|
{
|
||||||
window_type = xfi->_NET_WM_WINDOW_TYPE_DIALOG;
|
// WS_POPUP includes tool tips, dropdown menus, etc. These won't work
|
||||||
|
// correctly if the local window manager resizes or moves them. Set
|
||||||
|
// override redirect to prevent this from occurring.
|
||||||
|
|
||||||
|
XSetWindowAttributes attrs;
|
||||||
|
attrs.override_redirect = True;
|
||||||
|
XChangeWindowAttributes(xfi->display, window->handle, CWOverrideRedirect, &attrs);
|
||||||
|
window->is_transient = true;
|
||||||
|
|
||||||
|
window_type = xfi->_NET_WM_WINDOW_TYPE_POPUP;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (ex_style & WS_EX_TOOLWINDOW)
|
|
||||||
{
|
{
|
||||||
xf_SetWindowUnlisted(xfi, window);
|
window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
window_type = xfi->_NET_WM_WINDOW_TYPE_UTILITY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_WINDOW_TYPE,
|
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_WINDOW_TYPE,
|
||||||
XA_ATOM, 32, PropModeReplace, (uint8*) &window_type, 1);
|
XA_ATOM, 32, PropModeReplace, (uint8*) &window_type, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, boolean decorations)
|
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, boolean decorations)
|
||||||
@ -235,12 +265,14 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height,
|
|||||||
window->height = height;
|
window->height = height;
|
||||||
window->fullscreen = false;
|
window->fullscreen = false;
|
||||||
window->decorations = decorations;
|
window->decorations = decorations;
|
||||||
window->isMapped = false;
|
window->local_move.state = LMS_NOT_ACTIVE;
|
||||||
|
window->is_mapped = false;
|
||||||
|
window->is_transient = false;
|
||||||
|
|
||||||
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
|
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
|
||||||
xfi->workArea.x, xfi->workArea.y, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual,
|
xfi->workArea.x, xfi->workArea.y, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual,
|
||||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||||
CWBorderPixel, &xfi->attribs);
|
CWBorderPixel | CWWinGravity | CWBitGravity, &xfi->attribs);
|
||||||
|
|
||||||
class_hints = XAllocClassHint();
|
class_hints = XAllocClassHint();
|
||||||
|
|
||||||
@ -345,21 +377,32 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
|
|||||||
window->height = height;
|
window->height = height;
|
||||||
|
|
||||||
XGCValues gcv;
|
XGCValues gcv;
|
||||||
int input_mask;
|
|
||||||
XClassHint* class_hints;
|
XClassHint* class_hints;
|
||||||
|
int input_mask;
|
||||||
|
|
||||||
window->decorations = false;
|
window->decorations = false;
|
||||||
window->fullscreen = false;
|
window->fullscreen = false;
|
||||||
window->window = wnd;
|
window->window = wnd;
|
||||||
window->localMove.inProgress = false;
|
window->local_move.state = LMS_NOT_ACTIVE;
|
||||||
window->isMapped = false;
|
window->is_mapped = false;
|
||||||
|
window->is_transient = false;
|
||||||
|
|
||||||
|
// Proper behavior of tooltips, dropdown menus, etc, depend on the local window
|
||||||
|
// manager not modify them. Set override_redirect on these windows. RDP window
|
||||||
|
// styles don't map 1 to 1 to X window styles, but the presence of WM_POPUP
|
||||||
|
// appears to be sufficient for setting override_redirect.
|
||||||
|
|
||||||
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
|
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
|
||||||
x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
|
x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
|
||||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||||
CWBorderPixel, &xfi->attribs);
|
CWBorderPixel | CWWinGravity | CWBitGravity, &xfi->attribs);
|
||||||
|
|
||||||
|
DEBUG_X11_LMS("Create window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d rdp=0x%X",
|
||||||
|
(uint32) window->handle, window->left, window->top, window->right, window->bottom,
|
||||||
|
window->width, window->height, wnd->windowId);
|
||||||
|
|
||||||
xf_SetWindowDecorations(xfi, window, window->decorations);
|
xf_SetWindowDecorations(xfi, window, window->decorations);
|
||||||
|
xf_SetWindowStyle(xfi, window, wnd->style, wnd->extendedStyle);
|
||||||
|
|
||||||
class_hints = XAllocClassHint();
|
class_hints = XAllocClassHint();
|
||||||
|
|
||||||
@ -377,10 +420,14 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
|
|||||||
|
|
||||||
XSetWMProtocols(xfi->display, window->handle, &(xfi->WM_DELETE_WINDOW), 1);
|
XSetWMProtocols(xfi->display, window->handle, &(xfi->WM_DELETE_WINDOW), 1);
|
||||||
|
|
||||||
input_mask =
|
input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
|
||||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
|
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
|
||||||
VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
|
PointerMotionMask | Button1MotionMask | Button2MotionMask |
|
||||||
PointerMotionMask | ExposureMask | EnterWindowMask;
|
Button3MotionMask | Button4MotionMask | Button5MotionMask |
|
||||||
|
ButtonMotionMask | KeymapStateMask | ExposureMask |
|
||||||
|
VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask |
|
||||||
|
SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask |
|
||||||
|
ColormapChangeMask | OwnerGrabButtonMask;
|
||||||
|
|
||||||
XSelectInput(xfi->display, window->handle, input_mask);
|
XSelectInput(xfi->display, window->handle, input_mask);
|
||||||
XMapWindow(xfi->display, window->handle);
|
XMapWindow(xfi->display, window->handle);
|
||||||
@ -419,32 +466,31 @@ void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int windowRelativeX, int windowRelativeY)
|
void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y)
|
||||||
{
|
{
|
||||||
window->localMove.windowRelativeX = windowRelativeX;
|
rdpWindow* wnd = window->window;
|
||||||
window->localMove.windowRelativeY = windowRelativeY;
|
Window child_window;
|
||||||
|
|
||||||
DEBUG_X11_LMS("direction=%d coords=%d,%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d",
|
DEBUG_X11_LMS("direction=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d "
|
||||||
direction, windowRelativeX, windowRelativeY,
|
"RDP=0x%X rc={l=%d t=%d} w=%d h=%d mouse_x=%d mouse_y=%d",
|
||||||
(uint32) window->handle, window->left, window->top, window->right, window->bottom,
|
direction, (uint32) window->handle,
|
||||||
window->width, window->height);
|
window->left, window->top, window->right, window->bottom,
|
||||||
|
window->width, window->height,
|
||||||
|
wnd->windowId,
|
||||||
|
wnd->windowOffsetX, wnd->windowOffsetY,
|
||||||
|
wnd->windowWidth, wnd->windowHeight,
|
||||||
|
x, y);
|
||||||
|
|
||||||
// FIXME: There does not appear a way to tell when the local window manager completes
|
window->local_move.root_x = x;
|
||||||
// a window move or resize. The client will receive a number of ConfigureNotify events
|
window->local_move.root_y = y;
|
||||||
// but nothing indicates when the user has completed the move gesture (keyboard or mouse).
|
window->local_move.state = LMS_ACTIVE;
|
||||||
//
|
|
||||||
return;
|
|
||||||
|
|
||||||
// X Server _WM_MOVERESIZE coordinates are expressed relative to the root window.
|
XTranslateCoordinates(xfi->display, DefaultRootWindow(xfi->display), window->handle,
|
||||||
// RDP coordinates are expressed relative to the local window.
|
window->local_move.root_x,
|
||||||
// Translate these to root window coordinates.
|
window->local_move.root_y,
|
||||||
|
&window->local_move.window_x,
|
||||||
window->localMove.inProgress = True;
|
&window->local_move.window_y,
|
||||||
Window childWindow;
|
&child_window);
|
||||||
int x,y;
|
|
||||||
|
|
||||||
XTranslateCoordinates(xfi->display, window->handle, DefaultRootWindow(xfi->display),
|
|
||||||
windowRelativeX, windowRelativeY, &x, &y, &childWindow);
|
|
||||||
|
|
||||||
XUngrabPointer(xfi->display, CurrentTime);
|
XUngrabPointer(xfi->display, CurrentTime);
|
||||||
xf_SendClientEvent(xfi, window,
|
xf_SendClientEvent(xfi, window,
|
||||||
@ -459,40 +505,42 @@ void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int win
|
|||||||
|
|
||||||
void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window, boolean cancel)
|
void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window, boolean cancel)
|
||||||
{
|
{
|
||||||
DEBUG_X11_LMS("inProcess=%d cancel=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d",
|
rdpWindow* wnd = window->window;
|
||||||
window->localMove.inProgress, cancel,
|
|
||||||
(uint32) window->handle, window->left, window->top, window->right, window->bottom,
|
|
||||||
window->width, window->height);
|
|
||||||
|
|
||||||
if (!window->localMove.inProgress)
|
DEBUG_X11_LMS("inProcess=%d cancel=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d "
|
||||||
|
"RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
|
||||||
|
window->local_move.state, cancel,
|
||||||
|
(uint32) window->handle, window->left, window->top, window->right, window->bottom,
|
||||||
|
window->width, window->height,
|
||||||
|
wnd->windowId,
|
||||||
|
wnd->windowOffsetX, wnd->windowOffsetY,
|
||||||
|
wnd->windowWidth, wnd->windowHeight);
|
||||||
|
|
||||||
|
if (window->local_move.state == LMS_NOT_ACTIVE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cancel)
|
if (cancel)
|
||||||
{
|
{
|
||||||
// Per ICCM, the X client can ask to cancel an active move. Do this if we
|
// Per ICCM, the X client can ask to cancel an active move. Do this if we
|
||||||
// receive a local move stop from RDP while a local move is in progress
|
// receive a local move stop from RDP while a local move is in progress
|
||||||
Window childWindow;
|
|
||||||
int x,y;
|
|
||||||
|
|
||||||
XTranslateCoordinates(xfi->display, window->handle, DefaultRootWindow(xfi->display),
|
|
||||||
window->localMove.windowRelativeX, window->localMove.windowRelativeY, &x, &y, &childWindow);
|
|
||||||
|
|
||||||
xf_SendClientEvent(xfi, window,
|
xf_SendClientEvent(xfi, window,
|
||||||
xfi->_NET_WM_MOVERESIZE, // Request X window manager to initate a local move
|
xfi->_NET_WM_MOVERESIZE, // Request X window manager to abort a local move
|
||||||
5, // 5 arguments to follow
|
5, // 5 arguments to follow
|
||||||
x, // x relative to root window
|
window->local_move.root_x, // x relative to root window
|
||||||
y, // y relative to root window
|
window->local_move.root_y, // y relative to root window
|
||||||
_NET_WM_MOVERESIZE_CANCEL, // extended ICCM direction flag
|
_NET_WM_MOVERESIZE_CANCEL, // extended ICCM direction flag
|
||||||
1, // simulated mouse button 1
|
1, // simulated mouse button 1
|
||||||
1);// 1 == application request per extended ICCM
|
1);// 1 == application request per extended ICCM
|
||||||
}
|
}
|
||||||
|
|
||||||
window->localMove.inProgress = False;
|
window->local_move.state = LMS_NOT_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
|
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
boolean resize = false;
|
boolean resize = false;
|
||||||
|
rdpWindow* wnd = window->window;
|
||||||
|
|
||||||
if ((width * height) < 1)
|
if ((width * height) < 1)
|
||||||
return;
|
return;
|
||||||
@ -500,6 +548,16 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
|
|||||||
if ((window->width != width) || (window->height != height))
|
if ((window->width != width) || (window->height != height))
|
||||||
resize = true;
|
resize = true;
|
||||||
|
|
||||||
|
DEBUG_X11_LMS("window=0x%X current rc={l=%d t=%d r=%d b=%d} w=%u h=%u "
|
||||||
|
"new rc={l=%d t=%d r=%d b=%d} w=%u h=%u"
|
||||||
|
" RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
|
||||||
|
(uint32) window->handle, window->left, window->top,
|
||||||
|
window->right, window->bottom, window->width, window->height,
|
||||||
|
x, y, x + width -1, y + height -1, width, height,
|
||||||
|
wnd->windowId,
|
||||||
|
wnd->windowOffsetX, wnd->windowOffsetY,
|
||||||
|
wnd->windowWidth, wnd->windowHeight);
|
||||||
|
|
||||||
window->left = x;
|
window->left = x;
|
||||||
window->top = y;
|
window->top = y;
|
||||||
window->right = x + width - 1;
|
window->right = x + width - 1;
|
||||||
@ -507,20 +565,24 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
|
|||||||
window->width = width;
|
window->width = width;
|
||||||
window->height = height;
|
window->height = height;
|
||||||
|
|
||||||
|
if (window->is_transient)
|
||||||
|
{
|
||||||
if (resize)
|
if (resize)
|
||||||
XMoveResizeWindow(xfi->display, window->handle, x, y, width, height);
|
XMoveResizeWindow(xfi->display, window->handle, x, y, width, height);
|
||||||
else
|
else
|
||||||
XMoveWindow(xfi->display, window->handle, x, y);
|
XMoveWindow(xfi->display, window->handle, x, y);
|
||||||
|
} else {
|
||||||
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d",
|
// Sending a client event preserves
|
||||||
(uint32) window->handle, window->left, window->top, window->right, window->bottom,
|
// window gravity
|
||||||
window->width, window->height);
|
xf_SendClientEvent(xfi, window,
|
||||||
|
xfi->_NET_MOVERESIZE_WINDOW, // Request X window manager to move window
|
||||||
if (resize)
|
5, // 5 arguments to follow
|
||||||
{
|
0x1F0A, // STATIC gravity
|
||||||
xf_UpdateWindowArea(xfi, window, 0, 0, width, height);
|
x, // x relative to root window
|
||||||
|
y, // y relative to root window
|
||||||
|
width,
|
||||||
|
height);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state)
|
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state)
|
||||||
@ -630,8 +692,8 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
|
|||||||
{
|
{
|
||||||
int ax, ay;
|
int ax, ay;
|
||||||
rdpWindow* wnd;
|
rdpWindow* wnd;
|
||||||
|
|
||||||
wnd = window->window;
|
wnd = window->window;
|
||||||
|
|
||||||
ax = x + wnd->windowOffsetX;
|
ax = x + wnd->windowOffsetX;
|
||||||
ay = y + wnd->windowOffsetY;
|
ay = y + wnd->windowOffsetY;
|
||||||
|
|
||||||
|
@ -43,11 +43,20 @@ typedef struct xf_window xfWindow;
|
|||||||
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
|
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
|
||||||
#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
|
#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
|
||||||
|
|
||||||
|
enum xf_localmove_state
|
||||||
|
{
|
||||||
|
LMS_NOT_ACTIVE,
|
||||||
|
LMS_ACTIVE,
|
||||||
|
LMS_TERMINATING
|
||||||
|
};
|
||||||
|
|
||||||
struct xf_localmove
|
struct xf_localmove
|
||||||
{
|
{
|
||||||
int windowRelativeX;
|
int root_x; // relative to root
|
||||||
int windowRelativeY;
|
int root_y;
|
||||||
boolean inProgress;
|
int window_x; // relative to window
|
||||||
|
int window_y;
|
||||||
|
enum xf_localmove_state state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xf_window
|
struct xf_window
|
||||||
@ -63,8 +72,9 @@ struct xf_window
|
|||||||
boolean fullscreen;
|
boolean fullscreen;
|
||||||
boolean decorations;
|
boolean decorations;
|
||||||
rdpWindow* window;
|
rdpWindow* window;
|
||||||
boolean isMapped;
|
boolean is_mapped;
|
||||||
xfLocalMove localMove;
|
boolean is_transient;
|
||||||
|
xfLocalMove local_move;
|
||||||
};
|
};
|
||||||
|
|
||||||
void xf_ewmhints_init(xfInfo* xfi);
|
void xf_ewmhints_init(xfInfo* xfi);
|
||||||
@ -94,7 +104,7 @@ void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, int maxWidth, int max
|
|||||||
int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight);
|
int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight);
|
||||||
|
|
||||||
|
|
||||||
void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int windowRelativeX, int windowRelativeY);
|
void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y);
|
||||||
void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window, boolean cancel);
|
void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window, boolean cancel);
|
||||||
void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
||||||
|
|
||||||
|
@ -288,6 +288,8 @@ void xf_create_window(xfInfo* xfi)
|
|||||||
xfi->attribs.backing_store = xfi->primary ? NotUseful : Always;
|
xfi->attribs.backing_store = xfi->primary ? NotUseful : Always;
|
||||||
xfi->attribs.override_redirect = xfi->fullscreen;
|
xfi->attribs.override_redirect = xfi->fullscreen;
|
||||||
xfi->attribs.colormap = xfi->colormap;
|
xfi->attribs.colormap = xfi->colormap;
|
||||||
|
xfi->attribs.bit_gravity = ForgetGravity;
|
||||||
|
xfi->attribs.win_gravity = StaticGravity;
|
||||||
|
|
||||||
if (xfi->remote_app != true)
|
if (xfi->remote_app != true)
|
||||||
{
|
{
|
||||||
@ -470,24 +472,26 @@ boolean xf_pre_connect(freerdp* instance)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfi->_NET_WM_ICON = XInternAtom(xfi->display, "_NET_WM_ICON", false);
|
xfi->_NET_WM_ICON = XInternAtom(xfi->display, "_NET_WM_ICON", True);
|
||||||
xfi->_MOTIF_WM_HINTS = XInternAtom(xfi->display, "_MOTIF_WM_HINTS", false);
|
xfi->_MOTIF_WM_HINTS = XInternAtom(xfi->display, "_MOTIF_WM_HINTS", True);
|
||||||
xfi->_NET_CURRENT_DESKTOP = XInternAtom(xfi->display, "_NET_CURRENT_DESKTOP", false);
|
xfi->_NET_CURRENT_DESKTOP = XInternAtom(xfi->display, "_NET_CURRENT_DESKTOP", True);
|
||||||
xfi->_NET_WORKAREA = XInternAtom(xfi->display, "_NET_WORKAREA", false);
|
xfi->_NET_WORKAREA = XInternAtom(xfi->display, "_NET_WORKAREA", True);
|
||||||
xfi->_NET_WM_STATE = XInternAtom(xfi->display, "_NET_WM_STATE", false);
|
xfi->_NET_WM_STATE = XInternAtom(xfi->display, "_NET_WM_STATE", True);
|
||||||
xfi->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfi->display, "_NET_WM_STATE_FULLSCREEN", false);
|
xfi->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfi->display, "_NET_WM_STATE_FULLSCREEN", True);
|
||||||
xfi->_NET_WM_WINDOW_TYPE = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE", false);
|
xfi->_NET_WM_WINDOW_TYPE = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE", True);
|
||||||
|
|
||||||
xfi->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_NORMAL", false);
|
xfi->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_NORMAL", True);
|
||||||
xfi->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_DIALOG", false);
|
xfi->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_DIALOG", True);
|
||||||
xfi->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_UTILITY", false);
|
xfi->_NET_WM_WINDOW_TYPE_POPUP= XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_POPUP", True);
|
||||||
xfi->_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_TASKBAR", false);
|
xfi->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_UTILITY", True);
|
||||||
xfi->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_PAGER", false);
|
xfi->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", True);
|
||||||
|
xfi->_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_TASKBAR", True);
|
||||||
|
xfi->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_PAGER", True);
|
||||||
|
xfi->_NET_WM_MOVERESIZE = XInternAtom(xfi->display, "_NET_WM_MOVERESIZE", True);
|
||||||
|
xfi->_NET_MOVERESIZE_WINDOW = XInternAtom(xfi->display, "_NET_MOVERESIZE_WINDOW", True);
|
||||||
|
|
||||||
xfi->_NET_WM_MOVERESIZE = XInternAtom(xfi->display, "_NET_WM_MOVERESIZE", false);
|
xfi->WM_PROTOCOLS = XInternAtom(xfi->display, "WM_PROTOCOLS", True);
|
||||||
|
xfi->WM_DELETE_WINDOW = XInternAtom(xfi->display, "WM_DELETE_WINDOW", True);
|
||||||
xfi->WM_PROTOCOLS = XInternAtom(xfi->display, "WM_PROTOCOLS", false);
|
|
||||||
xfi->WM_DELETE_WINDOW = XInternAtom(xfi->display, "WM_DELETE_WINDOW", false);
|
|
||||||
|
|
||||||
xf_kbd_init(xfi);
|
xf_kbd_init(xfi);
|
||||||
|
|
||||||
|
@ -142,8 +142,11 @@ struct xf_info
|
|||||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
||||||
Atom _NET_WM_WINDOW_TYPE_UTILITY;
|
Atom _NET_WM_WINDOW_TYPE_UTILITY;
|
||||||
|
Atom _NET_WM_WINDOW_TYPE_POPUP;
|
||||||
|
Atom _NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
|
||||||
|
|
||||||
Atom _NET_WM_MOVERESIZE;
|
Atom _NET_WM_MOVERESIZE;
|
||||||
|
Atom _NET_MOVERESIZE_WINDOW;
|
||||||
|
|
||||||
Atom WM_PROTOCOLS;
|
Atom WM_PROTOCOLS;
|
||||||
Atom WM_DELETE_WINDOW;
|
Atom WM_DELETE_WINDOW;
|
||||||
|
Loading…
Reference in New Issue
Block a user