summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/windows/os_windows.cpp41
-rw-r--r--platform/windows/os_windows.h1
-rw-r--r--platform/x11/os_x11.cpp59
-rw-r--r--platform/x11/os_x11.h2
4 files changed, 72 insertions, 31 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index d1d769adf7..b230dda9cb 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -254,6 +254,25 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) // Check For Windows Messages
{
+ case WM_SETFOCUS:
+ {
+ window_has_focus = true;
+ // Re-capture cursor if we're in one of the capture modes
+ if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED) {
+ SetCapture(hWnd);
+ }
+ break;
+ }
+ case WM_KILLFOCUS:
+ {
+ window_has_focus = false;
+
+ // Release capture if we're in one of the capture modes
+ if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED) {
+ ReleaseCapture();
+ }
+ break;
+ }
case WM_ACTIVATE: // Watch For Window Activate Message
{
minimized = HIWORD(wParam) != 0;
@@ -266,19 +285,17 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
alt_mem=false;
control_mem=false;
shift_mem=false;
- if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED) {
RECT clipRect;
GetClientRect(hWnd, &clipRect);
ClientToScreen(hWnd, (POINT*) &clipRect.left);
ClientToScreen(hWnd, (POINT*) &clipRect.right);
ClipCursor(&clipRect);
SetCapture(hWnd);
-
}
} else {
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
alt_mem=false;
-
};
return 0; // Return To The Message Loop
@@ -345,6 +362,9 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
}
+ // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
+ if (!window_has_focus && mouse_mode==MOUSE_MODE_CAPTURED)
+ break;
/*
LPARAM extra = GetMessageExtraInfo();
if (IsPenEvent(extra)) {
@@ -376,7 +396,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
mm.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
mm.x=GET_X_LPARAM(lParam);
mm.y=GET_Y_LPARAM(lParam);
-
+
if (mouse_mode==MOUSE_MODE_CAPTURED) {
Point2i c(video_mode.width/2,video_mode.height/2);
@@ -410,7 +430,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
mm.relative_y=mm.y-old_y;
old_x=mm.x;
old_y=mm.y;
- if (main_loop)
+ if (window_has_focus && main_loop)
input->parse_input_event(event);
@@ -714,9 +734,8 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
joypad->probe_joypads();
} break;
case WM_SETCURSOR: {
-
if(LOWORD(lParam) == HTCLIENT) {
- if(mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED) {
+ if(window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED)) {
//Hide the cursor
if(hCursor == NULL)
hCursor = SetCursor(NULL);
@@ -948,7 +967,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
main_loop=NULL;
outside=true;
-
+ window_has_focus=true;
WNDCLASSEXW wc;
video_mode=p_desired;
@@ -1326,17 +1345,17 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) {
if (mouse_mode==p_mode)
return;
mouse_mode=p_mode;
- if (p_mode==MOUSE_MODE_CAPTURED) {
+ if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED) {
RECT clipRect;
GetClientRect(hWnd, &clipRect);
ClientToScreen(hWnd, (POINT*) &clipRect.left);
ClientToScreen(hWnd, (POINT*) &clipRect.right);
ClipCursor(&clipRect);
- SetCapture(hWnd);
center=Point2i(video_mode.width/2,video_mode.height/2);
POINT pos = { (int) center.x, (int) center.y };
ClientToScreen(hWnd, &pos);
- SetCursorPos(pos.x, pos.y);
+ if (mouse_mode==MOUSE_MODE_CAPTURED)
+ SetCursorPos(pos.x, pos.y);
} else {
ReleaseCapture();
ClipCursor(NULL);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index a5c8ecbe1b..2c8fa64f8e 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -118,6 +118,7 @@ class OS_Windows : public OS {
bool control_mem;
bool meta_mem;
bool force_quit;
+ bool window_has_focus;
uint32_t last_button_state;
CursorShape cursor_shape;
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 8baeb8bc90..38f7233c78 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -450,6 +450,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
physics_2d_server->init();
input = memnew( InputDefault );
+
+ window_has_focus = true; // Set focus to true at init
#ifdef JOYDEV_ENABLED
joypad = memnew( JoypadLinux(input));
#endif
@@ -518,17 +520,21 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
if (p_mode==mouse_mode)
return;
- if (mouse_mode==MOUSE_MODE_CAPTURED)
+ if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED)
XUngrabPointer(x11_display, CurrentTime);
- if (mouse_mode!=MOUSE_MODE_VISIBLE && p_mode==MOUSE_MODE_VISIBLE)
- XUndefineCursor(x11_display,x11_window);
- if (p_mode!=MOUSE_MODE_VISIBLE && mouse_mode==MOUSE_MODE_VISIBLE) {
- XDefineCursor(x11_display,x11_window,null_cursor);
+
+ // The only modes that show a cursor are VISIBLE and CONFINED
+ bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
+
+ if (showCursor) {
+ XUndefineCursor(x11_display,x11_window); // show cursor
+ } else {
+ XDefineCursor(x11_display,x11_window,null_cursor); // hide cursor
}
mouse_mode=p_mode;
- if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
while(true) {
//flush pending motion events
@@ -1254,6 +1260,10 @@ void OS_X11::process_xevents() {
do_mouse_warp=false;
+
+ // Is the current mouse mode one where it needs to be grabbed.
+ bool mouse_mode_grab = mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED;
+
while (XPending(x11_display) > 0) {
XEvent event;
XNextEvent(x11_display, &event);
@@ -1272,35 +1282,45 @@ void OS_X11::process_xevents() {
minimized = (visibility->state == VisibilityFullyObscured);
} break;
case LeaveNotify: {
-
- if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED)
+ if (main_loop && !mouse_mode_grab)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
if (input)
input->set_mouse_in_window(false);
} break;
case EnterNotify: {
-
- if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED)
+ if (main_loop && !mouse_mode_grab)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
if (input)
input->set_mouse_in_window(true);
} break;
case FocusIn:
minimized = false;
+ window_has_focus = true;
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
- if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ if (mouse_mode_grab) {
+ // Show and update the cursor if confined and the window regained focus.
+ if (mouse_mode==MOUSE_MODE_CONFINED)
+ XUndefineCursor(x11_display, x11_window);
+ else if (mouse_mode==MOUSE_MODE_CAPTURED) // or re-hide it in captured mode
+ XDefineCursor(x11_display, x11_window, null_cursor);
+
XGrabPointer(
- x11_display, x11_window, True,
+ x11_display, x11_window, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime);
}
break;
case FocusOut:
+ window_has_focus = false;
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
- if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ if (mouse_mode_grab) {
//dear X11, I try, I really try, but you never work, you do whathever you want.
+ if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ // Show the cursor if we're in captured mode so it doesn't look weird.
+ XUndefineCursor(x11_display, x11_window);
+ }
XUngrabPointer(x11_display, CurrentTime);
}
break;
@@ -1320,7 +1340,7 @@ void OS_X11::process_xevents() {
/* exit in case of a mouse button press */
last_timestamp=event.xbutton.time;
- if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
event.xbutton.x=last_mouse_pos.x;
event.xbutton.y=last_mouse_pos.y;
}
@@ -1343,7 +1363,6 @@ void OS_X11::process_xevents() {
mouse_event.mouse_button.pressed=(event.type==ButtonPress);
-
if (event.type==ButtonPress && event.xbutton.button==1) {
uint64_t diff = get_ticks_usec()/1000 - last_click_ms;
@@ -1377,7 +1396,6 @@ void OS_X11::process_xevents() {
// PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL
// MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG.
-
while(true) {
if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) {
//this is likely the warp event since it was warped here
@@ -1419,7 +1437,7 @@ void OS_X11::process_xevents() {
Point2i new_center = pos;
pos = last_mouse_pos + ( pos - center );
center=new_center;
- do_mouse_warp=true;
+ do_mouse_warp=window_has_focus; // warp the cursor if we're focused in
#else
//Dear X11, thanks for making my life miserable
@@ -1462,8 +1480,11 @@ void OS_X11::process_xevents() {
last_mouse_pos=pos;
// printf("rel: %d,%d\n", rel.x, rel.y );
-
- input->parse_input_event( motion_event);
+ // Don't propagate the motion event unless we have focus
+ // this is so that the relative motion doesn't get messed up
+ // after we regain focus.
+ if (window_has_focus || !mouse_mode_grab)
+ input->parse_input_event( motion_event);
} break;
case KeyPress:
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 3245df32c6..3ec358f103 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -134,7 +134,7 @@ class OS_X11 : public OS_Unix {
bool force_quit;
bool minimized;
-
+ bool window_has_focus;
bool do_mouse_warp;
const char *cursor_theme;