diff options
Diffstat (limited to 'platform/linuxbsd')
| -rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 48 | ||||
| -rw-r--r-- | platform/linuxbsd/display_server_x11.h | 10 | 
2 files changed, 44 insertions, 14 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 94c2e989f1..827d0361b9 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2339,6 +2339,30 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev  void DisplayServerX11::process_events() {  	_THREAD_SAFE_METHOD_ +	if (app_focused) { +		//verify that one of the windows has focus, else send focus out notification +		bool focus_found = false; +		for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { +			if (E->get().focused) { +				focus_found = true; +			} +		} + +		if (!focus_found) { +			uint64_t delta = OS::get_singleton()->get_ticks_msec() - time_since_no_focus; + +			if (delta > 250) { +				//X11 can go between windows and have no focus for a while, when creating them or something else. Use this as safety to avoid unnecesary focus in/outs. +				if (OS::get_singleton()->get_main_loop()) { +					OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); +				} +				app_focused = false; +			} +		} else { +			time_since_no_focus = OS::get_singleton()->get_ticks_msec(); +		} +	} +  	do_mouse_warp = false;  	// Is the current mouse mode one where it needs to be grabbed. @@ -2533,12 +2557,12 @@ void DisplayServerX11::process_events() {  				break;  			case NoExpose: -				minimized = true; +				windows[window_id].minimized = true;  				break;  			case VisibilityNotify: {  				XVisibilityEvent *visibility = (XVisibilityEvent *)&event; -				minimized = (visibility->state == VisibilityFullyObscured); +				windows[window_id].minimized = (visibility->state == VisibilityFullyObscured);  			} break;  			case LeaveNotify: {  				if (!mouse_mode_grab) { @@ -2552,10 +2576,8 @@ void DisplayServerX11::process_events() {  				}  			} break;  			case FocusIn: -				minimized = false; -				window_has_focus = true; +				windows[window_id].focused = true;  				_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN); -				window_focused = true;  				if (mouse_mode_grab) {  					// Show and update the cursor if confined and the window regained focus. @@ -2582,13 +2604,19 @@ void DisplayServerX11::process_events() {  				if (windows[window_id].xic) {  					XSetICFocus(windows[window_id].xic);  				} + +				if (!app_focused) { +					if (OS::get_singleton()->get_main_loop()) { +						OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); +					} +					app_focused = true; +				}  				break;  			case FocusOut: -				window_has_focus = false; +				windows[window_id].focused = false;  				Input::get_singleton()->release_pressed_events();  				_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT); -				window_focused = false;  				if (mouse_mode_grab) {  					for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { @@ -2727,7 +2755,7 @@ void DisplayServerX11::process_events() {  					Point2i new_center = pos;  					pos = last_mouse_pos + xi.relative_motion;  					center = new_center; -					do_mouse_warp = window_has_focus; // warp the cursor if we're focused in +					do_mouse_warp = windows[window_id].focused; // warp the cursor if we're focused in  				}  				if (!last_mouse_pos_valid) { @@ -2787,7 +2815,7 @@ void DisplayServerX11::process_events() {  				// 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) { +				if (windows[window_id].focused || !mouse_mode_grab) {  					Input::get_singleton()->accumulate_input_event(mm);  				} @@ -3764,8 +3792,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode  	requested = None; -	window_has_focus = true; // Set focus to true at init -  	/*if (p_desired.layered) {  		set_window_per_pixel_transparency_enabled(true);  	}*/ diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 3b2ff0e08d..b5d2ea1c63 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -139,6 +139,8 @@ class DisplayServerX11 : public DisplayServer {  		bool borderless = false;  		bool resize_disabled = false;  		Vector2i last_position_before_fs; +		bool focused = false; +		bool minimized = false;  	};  	Map<WindowID, WindowData> windows; @@ -164,6 +166,8 @@ class DisplayServerX11 : public DisplayServer {  	uint64_t last_click_ms;  	int last_click_button_index;  	uint32_t last_button_state; +	bool app_focused = false; +	uint64_t time_since_no_focus = 0;  	struct {  		int opcode; @@ -195,8 +199,8 @@ class DisplayServerX11 : public DisplayServer {  	void _handle_key_event(WindowID p_window, XKeyEvent *p_event, bool p_echo = false); -	bool minimized; -	bool window_has_focus; +	//bool minimized; +	//bool window_has_focus;  	bool do_mouse_warp;  	const char *cursor_theme; @@ -210,7 +214,7 @@ class DisplayServerX11 : public DisplayServer {  	bool layered_window;  	String rendering_driver; -	bool window_focused; +	//bool window_focused;  	//void set_wm_border(bool p_enabled);  	void set_wm_fullscreen(bool p_enabled);  	void set_wm_above(bool p_enabled);  |