clients: fix "focus in event" issues

The input->FocusInEvent callback implementations (normal and fast-path) have
always sent the mouse position even if the pointer was outside of the freerdp
client area. In addition xfreerdp used the wrong pointer coordinates which
were relative to the root window instead of its own.
On focus-in the pointer position must only be sent if the pointer is
currently within the program's client area. However, the clients had no way
to pass that information to input->FocusInEvent which required an API change.

- removed mouse pointer x, y parameters from input interface's FocusInEvent
- clients are responsible to call input->MouseEvent on focus-in if necessary
- fixed xfreerdp and wfreerdp accordingly
This commit is contained in:
Norbert Federa 2015-01-16 18:40:57 +01:00
parent 8d32a86318
commit 344362a8a3
7 changed files with 42 additions and 53 deletions

View File

@ -137,7 +137,8 @@ static void wl_keyboard_enter(void* data, struct wl_keyboard* keyboard, uint32_t
x = input_w->last_x;
y = input_w->last_y;
input->FocusInEvent(input, 0, x, y);
input->FocusInEvent(input, 0);
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
}
static void wl_keyboard_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface)

View File

@ -157,7 +157,8 @@ void wf_event_focus_in(wfContext* wfc)
{
UINT16 syncFlags;
rdpInput* input;
UINT16 mouseX, mouseY;
POINT pt;
RECT rc;
input = wfc->instance->input;
@ -175,10 +176,15 @@ void wf_event_focus_in(wfContext* wfc)
if (GetKeyState(VK_KANA))
syncFlags |= KBD_SYNC_KANA_LOCK;
mouseX = 0;
mouseY = 0;
input->FocusInEvent(input, syncFlags);
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
/* send pointer position if the cursor is currently inside our client area */
GetCursorPos(&pt);
ScreenToClient(wfc->hwnd, &pt);
GetClientRect(wfc->hwnd, &rc);
if (pt.x >= rc.left && pt.x < rc.right && pt.y >= rc.top && pt.y < rc.bottom)
input->MouseEvent(input, PTR_FLAGS_MOVE, (UINT16)pt.x, (UINT16)pt.y);
}
static int wf_event_process_WM_MOUSEWHEEL(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)

View File

@ -314,28 +314,30 @@ UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc)
void xf_keyboard_focus_in(xfContext* xfc)
{
rdpInput* input;
UINT32 syncFlags = 0;
int dummy, mouseX = 0, mouseY = 0;
Window wdummy;
UINT32 state = 0;
UINT32 syncFlags, state;
Window w;
int d, x, y;
if (!xfc->display || !xfc->window)
return;
if (xfc->display && xfc->window)
{
input = xfc->instance->input;
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
if (!xfc->remote_app)
{
XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy,
&mouseX, &mouseY, &dummy, &dummy, &state);
}
else
{
XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
}
input->FocusInEvent(input, syncFlags);
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
/* finish with a mouse pointer position like mstsc.exe if required */
if (xfc->remote_app)
return;
if (XQueryPointer(xfc->display, xfc->window->handle, &w, &w, &d, &d, &x, &y, &state))
{
if (x >= 0 && x < xfc->window->width && y >= 0 && y < xfc->window->height)
{
xf_event_adjust_coordinates(xfc, &x, &y);
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
}
}
}

View File

@ -67,7 +67,7 @@ typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef void (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pExtendedMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pFocusInEvent)(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y);
typedef void (*pFocusInEvent)(rdpInput* input, UINT16 toggleStates);
typedef void (*pKeyboardPauseEvent)(rdpInput* input);
struct rdp_input
@ -104,7 +104,7 @@ FREERDP_API void freerdp_input_send_keyboard_pause_event(rdpInput* input);
FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
FREERDP_API void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y);
FREERDP_API void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates);
#ifdef __cplusplus
}

View File

@ -154,7 +154,7 @@ void input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UI
rdp_send_client_input_pdu(rdp, s);
}
void input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
void input_send_focus_in_event(rdpInput* input, UINT16 toggleStates)
{
/* send a tab up like mstsc.exe */
input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f);
@ -164,9 +164,6 @@ void input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, U
/* send another tab up like mstsc.exe */
input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f);
/* finish with a mouse pointer position like mstsc.exe */
input_send_mouse_event(input, PTR_FLAGS_MOVE, x, y);
}
static void input_send_keyboard_pause_event(rdpInput* input)
@ -245,7 +242,7 @@ void input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 flags, UIN
fastpath_send_input_pdu(rdp->fastpath, s);
}
void input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
void input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates)
{
wStream* s;
rdpRdp* rdp = input->context->rdp;
@ -266,12 +263,7 @@ void input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates, UI
Stream_Write_UINT8(s, eventFlags); /* Key Release event (1 byte) */
Stream_Write_UINT8(s, 0x0f); /* keyCode (1 byte) */
/* finish with a mouse pointer position like mstsc.exe */
eventFlags = 0 | FASTPATH_INPUT_EVENT_MOUSE << 5;
Stream_Write_UINT8(s, eventFlags); /* Mouse Pointer event (1 byte) */
input_write_extended_mouse_event(s, PTR_FLAGS_MOVE, x, y);
fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4);
fastpath_send_multiple_input_pdu(rdp->fastpath, s, 3);
}
static void input_send_fastpath_keyboard_pause_event(rdpInput* input)
@ -548,9 +540,9 @@ void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT
IFCALL(input->ExtendedMouseEvent, input, flags, x, y);
}
void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates)
{
IFCALL(input->FocusInEvent, input, toggleStates, x, y);
IFCALL(input->FocusInEvent, input, toggleStates);
}
void freerdp_input_send_keyboard_pause_event(rdpInput* input)

View File

@ -2265,12 +2265,10 @@ static void input_message_ExtendedMouseEvent(rdpInput* input, UINT16 flags, UINT
MakeMessageId(Input, ExtendedMouseEvent), (void*) (size_t) flags, (void*) (size_t) pos);
}
static void input_message_FocusInEvent(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
static void input_message_FocusInEvent(rdpInput* input, UINT16 toggleStates)
{
UINT32 pos = (x << 16) | y;
MessageQueue_Post(input->queue, (void*) input,
MakeMessageId(Input, FocusInEvent), (void*) (size_t) toggleStates, (void*) (size_t) pos);
MakeMessageId(Input, FocusInEvent), (void*) (size_t) toggleStates, NULL);
}
static void input_message_KeyboardPauseEvent(rdpInput* input)
@ -2360,16 +2358,7 @@ static int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg
break;
case Input_FocusInEvent:
{
UINT32 pos;
UINT16 x, y;
pos = (UINT32) (size_t) msg->lParam;
x = ((pos & 0xFFFF0000) >> 16);
y = (pos & 0x0000FFFF);
IFCALL(proxy->FocusInEvent, msg->context, (UINT16) (size_t) msg->wParam, x, y);
}
IFCALL(proxy->FocusInEvent, msg->context, (UINT16) (size_t) msg->wParam);
break;
case Input_KeyboardPauseEvent:

View File

@ -194,7 +194,6 @@ BOOL nego_connect(rdpNego* nego)
BOOL nego_disconnect(rdpNego* nego)
{
rdpSettings* settings = nego->transport->settings;
nego->state = NEGO_STATE_INITIAL;
return nego_transport_disconnect(nego);
}