diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 73516d408..53dbddf5c 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -554,71 +554,99 @@ boolean xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, boolean app) return true; } -boolean xf_event_process(freerdp* instance, XEvent* event) +boolean xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*event) { - boolean status = true; - xfInfo* xfi = ((xfContext*) instance->context)->xfi; + if (! xfi->remote_app) + return false; - if (xfi->window && xfi->window->local_move.state == LMS_ACTIVE) + switch (xfi->window->local_move.state) { - 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 LMS_NOT_ACTIVE: + // No local move in progress, nothing to do + break; + case LMS_STARTING: + // Local move initiated by RDP server, but we + // have not yet seen any updates from the X server + switch(event->type) { + case ConfigureNotify: + // Starting to see move events + // from the X server. Local + // move is now in progress. + xfi->window->local_move.state = LMS_ACTIVE; + + // Allow these events to be processed during move to keep + // our state up to date. + break; 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); - } - break; - - case FocusIn: - case FocusOut: - { - XFocusChangeEvent *focusEvent = (XFocusChangeEvent *)event; - 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. + // 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_rail_end_local_move(xfi, window); + break; + case VisibilityNotify: + case PropertyNotify: + // Allow these events to pass + return false; + default: + // Eat any other events + return true; } + break; + case LMS_ACTIVE: + // Local move is in progress + switch(event->type) + { + case ConfigureNotify: + case VisibilityNotify: + case PropertyNotify: + // Keep us up to date on position + break; + case Expose: + return true; + default: + // Any other event terminates move + xf_rail_end_local_move(xfi, window); + break; + } + break; + + case LMS_TERMINATING: + // Already sent RDP end move to sever + // Allow events to pass. + break; + } + + return false; +} + + +boolean xf_event_process(freerdp* instance, XEvent* event) +{ + boolean status = true; + xfInfo* xfi = ((xfContext*) instance->context)->xfi; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + rdpWindow* window; + + if (xfi->remote_app) + { + window = window_list_get_by_extra_id( + rail->list, (void*) event->xexpose.window); + if (window) + { + // Update "current" window for cursor change orders + xfi->window = (xfWindow *) window->extra; + + if (xf_event_suppress_events(xfi, window, event)) + return true; } } @@ -715,10 +743,6 @@ boolean xf_event_process(freerdp* instance, XEvent* event) case PropertyNotify: status = xf_event_PropertyNotify(xfi, event, xfi->remote_app); break; - - default: - DEBUG_X11("xf_event_process unknown event %d", event->type); - break; } return status; diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 496cd5cce..90d314ff1 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -263,13 +263,12 @@ void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window) 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", + " RDP=0x%X rc={l=%d t=%d} w=%d h=%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); + window->windowWidth, window->windowHeight); // If current window position disagrees with RDP window position, send // update to RDP server diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 74e130a92..b213e5794 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -85,7 +85,7 @@ void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int n xevent.xclient.type = ClientMessage; xevent.xclient.serial = 0; - xevent.xclient.send_event = True; + xevent.xclient.send_event = False; xevent.xclient.display = xfi->display; xevent.xclient.window = window->handle; xevent.xclient.message_type = atom; @@ -483,7 +483,7 @@ void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, window->local_move.root_x = x; window->local_move.root_y = y; - window->local_move.state = LMS_ACTIVE; + window->local_move.state = LMS_STARTING; XTranslateCoordinates(xfi->display, DefaultRootWindow(xfi->display), window->handle, window->local_move.root_x, @@ -507,7 +507,7 @@ void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window, boolean cancel) { rdpWindow* wnd = window->window; - DEBUG_X11_LMS("inProcess=%d cancel=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d " + DEBUG_X11_LMS("state=%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, @@ -565,24 +565,10 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h window->width = width; window->height = height; - if (window->is_transient) - { - if (resize) - XMoveResizeWindow(xfi->display, window->handle, x, y, width, height); - else - XMoveWindow(xfi->display, window->handle, x, y); - } else { - // Sending a client event preserves - // window gravity - xf_SendClientEvent(xfi, window, - xfi->_NET_MOVERESIZE_WINDOW, // Request X window manager to move window - 5, // 5 arguments to follow - 0x1F0A, // STATIC gravity - x, // x relative to root window - y, // y relative to root window - width, - height); - } + if (resize) + XMoveResizeWindow(xfi->display, window->handle, x, y, width, height); + else + XMoveWindow(xfi->display, window->handle, x, y); } void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state) diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index d9667b4ef..b59cf4dce 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -46,6 +46,7 @@ typedef struct xf_window xfWindow; enum xf_localmove_state { LMS_NOT_ACTIVE, + LMS_STARTING, LMS_ACTIVE, LMS_TERMINATING };