diff --git a/Backends/RmlUi_Backend_SDL_GL2.cpp b/Backends/RmlUi_Backend_SDL_GL2.cpp index bc1b4c65a..65e1be63c 100644 --- a/Backends/RmlUi_Backend_SDL_GL2.cpp +++ b/Backends/RmlUi_Backend_SDL_GL2.cpp @@ -158,14 +158,16 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al #if SDL_MAJOR_VERSION >= 3 auto CreateWindow = [&]() { + const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale)); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale)); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true); SDL_Window* window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); return window; @@ -249,6 +251,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call #define RMLSDL_WINDOW_EVENTS_BEGIN #define RMLSDL_WINDOW_EVENTS_END auto GetKey = [](const SDL_Event& event) { return event.key.key; }; + auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); }; constexpr auto event_quit = SDL_EVENT_QUIT; constexpr auto event_key_down = SDL_EVENT_KEY_DOWN; constexpr auto event_window_size_changed = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED; @@ -264,6 +267,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } \ break; auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; }; + auto GetDisplayScale = []() { return 1.f; }; constexpr auto event_quit = SDL_QUIT; constexpr auto event_key_down = SDL_KEYDOWN; constexpr auto event_window_size_changed = SDL_WINDOWEVENT_SIZE_CHANGED; @@ -295,13 +299,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call propagate_event = false; const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev)); const int key_modifier = RmlSDL::GetKeyModifierState(); - const float native_dp_ratio = 1.f; + const float native_dp_ratio = GetDisplayScale(); // See if we have any global shortcuts that take priority over the context. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true)) break; // Otherwise, hand the event over to the context by calling the input handler as normal. - if (!RmlSDL::InputEventHandler(context, ev)) + if (!RmlSDL::InputEventHandler(context, data->window, ev)) break; // The key was not consumed by the context either, try keyboard shortcuts of lower priority. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false)) @@ -324,7 +328,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } if (propagate_event) - RmlSDL::InputEventHandler(context, ev); + RmlSDL::InputEventHandler(context, data->window, ev); has_event = SDL_PollEvent(&ev); } diff --git a/Backends/RmlUi_Backend_SDL_GL3.cpp b/Backends/RmlUi_Backend_SDL_GL3.cpp index 924200467..2d5b1225c 100644 --- a/Backends/RmlUi_Backend_SDL_GL3.cpp +++ b/Backends/RmlUi_Backend_SDL_GL3.cpp @@ -170,14 +170,16 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #if SDL_MAJOR_VERSION >= 3 + const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale)); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale)); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true); SDL_Window* window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); #else @@ -272,6 +274,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call #define RMLSDL_WINDOW_EVENTS_BEGIN #define RMLSDL_WINDOW_EVENTS_END auto GetKey = [](const SDL_Event& event) { return event.key.key; }; + auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); }; constexpr auto event_quit = SDL_EVENT_QUIT; constexpr auto event_key_down = SDL_EVENT_KEY_DOWN; constexpr auto event_window_size_changed = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED; @@ -287,6 +290,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } \ break; auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; }; + auto GetDisplayScale = []() { return 1.f; }; constexpr auto event_quit = SDL_QUIT; constexpr auto event_key_down = SDL_KEYDOWN; constexpr auto event_window_size_changed = SDL_WINDOWEVENT_SIZE_CHANGED; @@ -318,13 +322,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call propagate_event = false; const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev)); const int key_modifier = RmlSDL::GetKeyModifierState(); - const float native_dp_ratio = 1.f; + const float native_dp_ratio = GetDisplayScale(); // See if we have any global shortcuts that take priority over the context. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true)) break; // Otherwise, hand the event over to the context by calling the input handler as normal. - if (!RmlSDL::InputEventHandler(context, ev)) + if (!RmlSDL::InputEventHandler(context, data->window, ev)) break; // The key was not consumed by the context either, try keyboard shortcuts of lower priority. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false)) @@ -347,7 +351,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } if (propagate_event) - RmlSDL::InputEventHandler(context, ev); + RmlSDL::InputEventHandler(context, data->window, ev); has_event = SDL_PollEvent(&ev); } diff --git a/Backends/RmlUi_Backend_SDL_SDLrenderer.cpp b/Backends/RmlUi_Backend_SDL_SDLrenderer.cpp index a589424e7..d78e875a8 100644 --- a/Backends/RmlUi_Backend_SDL_SDLrenderer.cpp +++ b/Backends/RmlUi_Backend_SDL_SDLrenderer.cpp @@ -67,13 +67,15 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); #if SDL_MAJOR_VERSION >= 3 + const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale)); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale)); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true); SDL_Window* window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); #else @@ -167,11 +169,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call #if SDL_MAJOR_VERSION >= 3 auto GetKey = [](const SDL_Event& event) { return event.key.key; }; + auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); }; constexpr auto event_quit = SDL_EVENT_QUIT; constexpr auto event_key_down = SDL_EVENT_KEY_DOWN; bool has_event = false; #else auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; }; + auto GetDisplayScale = []() { return 1.f; }; constexpr auto event_quit = SDL_QUIT; constexpr auto event_key_down = SDL_KEYDOWN; int has_event = 0; @@ -202,13 +206,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call propagate_event = false; const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev)); const int key_modifier = RmlSDL::GetKeyModifierState(); - const float native_dp_ratio = 1.f; + const float native_dp_ratio = GetDisplayScale(); // See if we have any global shortcuts that take priority over the context. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true)) break; // Otherwise, hand the event over to the context by calling the input handler as normal. - if (!RmlSDL::InputEventHandler(context, ev)) + if (!RmlSDL::InputEventHandler(context, data->window, ev)) break; // The key was not consumed by the context either, try keyboard shortcuts of lower priority. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false)) @@ -219,7 +223,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } if (propagate_event) - RmlSDL::InputEventHandler(context, ev); + RmlSDL::InputEventHandler(context, data->window, ev); has_event = SDL_PollEvent(&ev); } diff --git a/Backends/RmlUi_Backend_SDL_VK.cpp b/Backends/RmlUi_Backend_SDL_VK.cpp index fbad69242..d50cade13 100644 --- a/Backends/RmlUi_Backend_SDL_VK.cpp +++ b/Backends/RmlUi_Backend_SDL_VK.cpp @@ -75,14 +75,16 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); #if SDL_MAJOR_VERSION >= 3 + const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale)); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale)); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN, true); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true); SDL_Window* window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); auto CreateSurface = [](VkInstance instance, VkSurfaceKHR* out_surface) { @@ -217,6 +219,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call #define RMLSDL_WINDOW_EVENTS_BEGIN #define RMLSDL_WINDOW_EVENTS_END auto GetKey = [](const SDL_Event& event) { return event.key.key; }; + auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); }; constexpr auto event_quit = SDL_EVENT_QUIT; constexpr auto event_key_down = SDL_EVENT_KEY_DOWN; constexpr auto event_window_size_changed = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED; @@ -232,6 +235,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } \ break; auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; }; + auto GetDisplayScale = []() { return 1.f; }; constexpr auto event_quit = SDL_QUIT; constexpr auto event_key_down = SDL_KEYDOWN; constexpr auto event_window_size_changed = SDL_WINDOWEVENT_SIZE_CHANGED; @@ -263,13 +267,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call propagate_event = false; const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev)); const int key_modifier = RmlSDL::GetKeyModifierState(); - const float native_dp_ratio = 1.f; + const float native_dp_ratio = GetDisplayScale(); // See if we have any global shortcuts that take priority over the context. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true)) break; // Otherwise, hand the event over to the context by calling the input handler as normal. - if (!RmlSDL::InputEventHandler(context, ev)) + if (!RmlSDL::InputEventHandler(context, data->window, ev)) break; // The key was not consumed by the context either, try keyboard shortcuts of lower priority. if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false)) @@ -292,7 +296,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call } if (propagate_event) - RmlSDL::InputEventHandler(context, ev); + RmlSDL::InputEventHandler(context, data->window, ev); has_event = SDL_PollEvent(&ev); } diff --git a/Backends/RmlUi_Platform_SDL.cpp b/Backends/RmlUi_Platform_SDL.cpp index d6d374928..0c553c0c4 100644 --- a/Backends/RmlUi_Platform_SDL.cpp +++ b/Backends/RmlUi_Platform_SDL.cpp @@ -147,7 +147,7 @@ void SystemInterface_SDL::DeactivateKeyboard() } } -bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev) +bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Window* window, SDL_Event& ev) { #if SDL_MAJOR_VERSION >= 3 #define RMLSDL_WINDOW_EVENTS_BEGIN @@ -165,6 +165,7 @@ bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev) constexpr auto rmlsdl_true = true; constexpr auto rmlsdl_false = false; #else + (void)window; #define RMLSDL_WINDOW_EVENTS_BEGIN \ case SDL_WINDOWEVENT: \ { \ @@ -246,6 +247,15 @@ bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev) } break; +#if SDL_MAJOR_VERSION >= 3 + case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: + { + const float display_scale = SDL_GetWindowDisplayScale(window); + context->SetDensityIndependentPixelRatio(display_scale); + } + break; +#endif + RMLSDL_WINDOW_EVENTS_END default: break; diff --git a/Backends/RmlUi_Platform_SDL.h b/Backends/RmlUi_Platform_SDL.h index 1fe809324..becc4d0f8 100644 --- a/Backends/RmlUi_Platform_SDL.h +++ b/Backends/RmlUi_Platform_SDL.h @@ -77,7 +77,7 @@ namespace RmlSDL { // Applies input on the context based on the given SDL event. // @return True if the event is still propagating, false if it was handled by the context. -bool InputEventHandler(Rml::Context* context, SDL_Event& ev); +bool InputEventHandler(Rml::Context* context, SDL_Window* window, SDL_Event& ev); // Converts the SDL key to RmlUi key. Rml::Input::KeyIdentifier ConvertKey(int sdl_key); diff --git a/changelog.md b/changelog.md index 7c9d2206c..1a8e8665b 100644 --- a/changelog.md +++ b/changelog.md @@ -107,6 +107,22 @@ The font face will be inherited from the element it is being applied to. However - Fix incorrect clipping when using multiple contexts of different dimensions. #677 #680 (thanks @s1sw) +### Backends + +- Update SFML backend to support SFML 3, in addition to the existing SFML 2 support. + - By default, SFML 3 is preferred before SFML 2 during CMake configuration. To override the automatic selection, set the CMake variable `RMLUI_SFML_VERSION_MAJOR` to the desired version (2 or 3). +- Update SDL backends to support SDL 3, in addition to the existing SDL 2 support. + - By default, SDL 3 is preferred before SDL 2 during CMake configuration. To override the automatic selection, set the CMake variable `RMLUI_SDL_VERSION_MAJOR` to the desired version (2 or 3). +- SDL 3-specific improvements: + - Enable high DPI support. + - Enable positioning of the input method editor (IME) to the text cursor. +- Improvements to both SDL 2 and SDL 3: + - Keyboard is activated and deactivated when focusing text input fields. + - Text input events are only submitted when text input fields are focused. +- `SDL_GL2`-specific improvements: + - GLEW is no longer required, and no longer linked to. + - Use OpenGL directly instead of the SDL renderer, just like the `SDL_GL3` renderer. + ### Plugins - Log warnings when SVG or Lottie files cannot be rendered. #687 @@ -142,7 +158,7 @@ The font face will be inherited from the element it is being applied to. However - They now take the new `RenderBox` class as input. The `Element::GetRenderBox` method can be used to construct it. - Changed `ComputedValues::border_radius` to return an array instead of `Vector4f`. - `Rml::ReleaseMemoryPools` is no longer exposed publicly. This function is automatically called during shutdown and should not be used manually. - +- SDL backends: The SDL platform's `InputEventHandler` function now takes an additional parameter `window`. ## RmlUi 6.0 diff --git a/readme.md b/readme.md index 21920d0d3..7558b8ecc 100644 --- a/readme.md +++ b/readme.md @@ -155,13 +155,13 @@ The provided backends on the other hand are not intended to be used directly by ### Platforms -| Platform support | Basic windowing | Clipboard | High DPI | Comments | -|------------------|:---------------:|:---------:|:----------:|---------------------------------------------------| -| Win32 | ✔️ | ✔️ | ✔️ | High DPI only supported on Windows 10 and newer. | -| X11 | ✔️ | ✔️ | ❌ | | -| SFML | ✔️ | ⚠️ | ❌ | Some issues with Unicode characters in clipboard. | -| GLFW | ✔️ | ✔️ | ✔️ | | -| SDL | ✔️ | ✔️ | ❌ | | +| Platform support | Basic windowing | Clipboard | High DPI | Comments | +|------------------|:---------------:|:---------:|:--------:|-----------| +| Win32 | ✔️ | ✔️ | ✔️ | High DPI only supported on Windows 10 and newer. | +| X11 | ✔️ | ✔️ | ❌ | | +| SFML | ✔️ | ⚠️ | ❌ | Supports SFML 2 and SFML 3. Some issues with Unicode characters in clipboard. | +| GLFW | ✔️ | ✔️ | ✔️ | | +| SDL | ✔️ | ✔️ | ✔️ | Supports SDL 2 and SDL 3. High DPI supported only on SDL 3. | **Basic windowing**: Open windows, react to resize events, submit inputs to the RmlUi context.\ **Clipboard**: Read from and write to the system clipboard.\ @@ -169,13 +169,13 @@ The provided backends on the other hand are not intended to be used directly by ### Backends -| Platform \ Renderer | OpengGL 2 | OpengGL 3 | Vulkan | SDLrenderer | -|---------------------|:---------:|:---------:|:---------:|:-----------:| -| Win32 | ✔️ | | ✔️ | | -| X11 | ✔️ | | | | -| SFML | ✔️ | | | | -| GLFW | ✔️ | ✔️ | ✔️ | | -| SDL¹ | ✔️ | ✔️² | ✔️ | ✔️ | +| Platform \ Renderer | OpenGL 2 (GL2) | OpenGL 3 (GL3) | Vulkan (VK) | SDLrenderer | +|---------------------|:--------------:|:--------------:|:-----------:|:-----------:| +| Win32 | ✔️ | | ✔️ | | +| X11 | ✔️ | | | | +| SFML | ✔️ | | | | +| GLFW | ✔️ | ✔️ | ✔️ | | +| SDL¹ | ✔️ | ✔️² | ✔️ | ✔️ | ¹ SDL backends extend their respective renderers to provide image support based on SDL_image.\ ² Supports Emscripten compilation target.