Răsfoiți Sursa

Handle the mouse leaving the window on all the backends, see #220.

Michael Ragazzon 3 ani în urmă
părinte
comite
f1d5b31ddc

+ 2 - 0
Backends/RmlUi_Backend_GLFW_GL2.cpp

@@ -221,6 +221,8 @@ static void SetupCallbacks(GLFWwindow* window)
 
 	glfwSetCharCallback(window, [](GLFWwindow* /*window*/, unsigned int codepoint) { RmlGLFW::ProcessCharCallback(data->context, codepoint); });
 
+	glfwSetCursorEnterCallback(window, [](GLFWwindow* /*window*/, int entered) { RmlGLFW::ProcessCursorEnterCallback(data->context, entered); });
+
 	// Mouse input
 	glfwSetCursorPosCallback(window, [](GLFWwindow* /*window*/, double xpos, double ypos) {
 		RmlGLFW::ProcessCursorPosCallback(data->context, xpos, ypos, data->glfw_active_modifiers);

+ 2 - 0
Backends/RmlUi_Backend_GLFW_GL3.cpp

@@ -233,6 +233,8 @@ static void SetupCallbacks(GLFWwindow* window)
 
 	glfwSetCharCallback(window, [](GLFWwindow* /*window*/, unsigned int codepoint) { RmlGLFW::ProcessCharCallback(data->context, codepoint); });
 
+	glfwSetCursorEnterCallback(window, [](GLFWwindow* /*window*/, int entered) { RmlGLFW::ProcessCursorEnterCallback(data->context, entered); });
+
 	// Mouse input
 	glfwSetCursorPosCallback(window, [](GLFWwindow* /*window*/, double xpos, double ypos) {
 		RmlGLFW::ProcessCursorPosCallback(data->context, xpos, ypos, data->glfw_active_modifiers);

+ 1 - 1
Backends/RmlUi_Backend_SDL_GL2.cpp

@@ -287,11 +287,11 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
 			case SDL_WINDOWEVENT_SIZE_CHANGED:
 			{
 				Rml::Vector2i dimensions(ev.window.data1, ev.window.data2);
-				context->SetDimensions(dimensions);
 				data->render_interface.SetViewport(dimensions.x, dimensions.y);
 			}
 			break;
 			}
+			RmlSDL::InputEventHandler(context, ev);
 		}
 		break;
 		default:

+ 1 - 1
Backends/RmlUi_Backend_SDL_GL3.cpp

@@ -272,11 +272,11 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
 			case SDL_WINDOWEVENT_SIZE_CHANGED:
 			{
 				Rml::Vector2i dimensions(ev.window.data1, ev.window.data2);
-				context->SetDimensions(dimensions);
 				data->render_interface.SetViewport(dimensions.x, dimensions.y);
 			}
 			break;
 			}
+			RmlSDL::InputEventHandler(context, ev);
 		}
 		break;
 		default:

+ 0 - 10
Backends/RmlUi_Backend_SDL_SDLrenderer.cpp

@@ -153,16 +153,6 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
 				break;
 		}
 		break;
-		case SDL_WINDOWEVENT:
-		{
-			switch (ev.window.event)
-			{
-			case SDL_WINDOWEVENT_SIZE_CHANGED:
-				context->SetDimensions(Rml::Vector2i(ev.window.data1, ev.window.data2));
-				break;
-			}
-		}
-		break;
 		default:
 		{
 			RmlSDL::InputEventHandler(context, ev);

+ 2 - 1
Backends/RmlUi_Backend_X11_GL2.cpp

@@ -131,7 +131,8 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
 	XSetWMProtocols(display, window, &delete_atom, 1);
 
 	// Capture the events we're interested in.
-	XSelectInput(display, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
+	XSelectInput(display, window,
+		KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | LeaveWindowMask | PointerMotionMask | StructureNotifyMask);
 
 	if (!allow_resize)
 	{

+ 11 - 0
Backends/RmlUi_Platform_GLFW.cpp

@@ -123,6 +123,17 @@ bool RmlGLFW::ProcessCharCallback(Rml::Context* context, unsigned int codepoint)
 	return result;
 }
 
+bool RmlGLFW::ProcessCursorEnterCallback(Rml::Context* context, int entered)
+{
+	if (!context)
+		return true;
+
+	bool result = true;
+	if (!entered)
+		result = context->ProcessMouseLeave();
+	return result;
+}
+
 bool RmlGLFW::ProcessCursorPosCallback(Rml::Context* context, double xpos, double ypos, int mods)
 {
 	if (!context)

+ 1 - 0
Backends/RmlUi_Platform_GLFW.h

@@ -69,6 +69,7 @@ namespace RmlGLFW {
 // propagating, i.e. was not handled by the context.
 bool ProcessKeyCallback(Rml::Context* context, int key, int action, int mods);
 bool ProcessCharCallback(Rml::Context* context, unsigned int codepoint);
+bool ProcessCursorEnterCallback(Rml::Context* context, int entered);
 bool ProcessCursorPosCallback(Rml::Context* context, double xpos, double ypos, int mods);
 bool ProcessMouseButtonCallback(Rml::Context* context, int button, int action, int mods);
 bool ProcessScrollCallback(Rml::Context* context, double yoffset, int mods);

+ 16 - 0
Backends/RmlUi_Platform_SDL.cpp

@@ -130,6 +130,22 @@ bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev)
 	case SDL_TEXTINPUT:
 		result = context->ProcessTextInput(Rml::String(&ev.text.text[0]));
 		break;
+	case SDL_WINDOWEVENT:
+	{
+		switch (ev.window.event)
+		{
+		case SDL_WINDOWEVENT_SIZE_CHANGED:
+		{
+			Rml::Vector2i dimensions(ev.window.data1, ev.window.data2);
+			context->SetDimensions(dimensions);
+		}
+		break;
+		case SDL_WINDOWEVENT_LEAVE:
+			context->ProcessMouseLeave();
+			break;
+		}
+	}
+	break;
 	default:
 		break;
 	}

+ 3 - 0
Backends/RmlUi_Platform_SFML.cpp

@@ -109,6 +109,9 @@ bool RmlSFML::InputHandler(Rml::Context* context, sf::Event& ev)
 	case sf::Event::MouseWheelMoved:
 		result = context->ProcessMouseWheel(float(-ev.mouseWheel.delta), RmlSFML::GetKeyModifierState());
 		break;
+	case sf::Event::MouseLeft:
+		result = context->ProcessMouseLeave();
+		break;
 	case sf::Event::TextEntered:
 	{
 		Rml::Character character = Rml::Character(ev.text.unicode);

+ 15 - 0
Backends/RmlUi_Platform_Win32.cpp

@@ -188,6 +188,8 @@ bool RmlWin32::WindowProcedure(Rml::Context* context, HWND window_handle, UINT m
 	if (!context)
 		return true;
 
+	static bool tracking_mouse_leave = false;
+
 	bool result = true;
 
 	switch (message)
@@ -215,11 +217,24 @@ bool RmlWin32::WindowProcedure(Rml::Context* context, HWND window_handle, UINT m
 	case WM_MOUSEMOVE:
 		result = context->ProcessMouseMove(static_cast<int>((short)LOWORD(l_param)), static_cast<int>((short)HIWORD(l_param)),
 			RmlWin32::GetKeyModifierState());
+
+		if (!tracking_mouse_leave)
+		{
+			TRACKMOUSEEVENT tme = {};
+			tme.cbSize = sizeof(TRACKMOUSEEVENT);
+			tme.dwFlags = TME_LEAVE;
+			tme.hwndTrack = window_handle;
+			tracking_mouse_leave = TrackMouseEvent(&tme);
+		}
 		break;
 	case WM_MOUSEWHEEL:
 		result = context->ProcessMouseWheel(static_cast<float>((short)HIWORD(w_param)) / static_cast<float>(-WHEEL_DELTA),
 			RmlWin32::GetKeyModifierState());
 		break;
+	case WM_MOUSELEAVE:
+		result = context->ProcessMouseLeave();
+		tracking_mouse_leave = false;
+		break;
 	case WM_KEYDOWN:
 		result = context->ProcessKeyDown(RmlWin32::ConvertKey((int)w_param), RmlWin32::GetKeyModifierState());
 		break;

+ 5 - 0
Backends/RmlUi_Platform_X11.cpp

@@ -270,6 +270,11 @@ bool RmlX11::HandleInputEvent(Rml::Context* context, Display* display, const XEv
 		return context->ProcessMouseMove(ev.xmotion.x, ev.xmotion.y, RmlX11::GetKeyModifierState(ev.xmotion.state));
 	}
 	break;
+	case LeaveNotify:
+	{
+		return context->ProcessMouseLeave();
+	}
+	break;
 	case KeyPress:
 	{
 		Rml::Input::KeyIdentifier key_identifier = RmlX11::ConvertKey(display, ev.xkey.keycode);