瀏覽代碼

Allow to set window resizability from a console parameter and fix resizability handling in XCB. (#18721)

* Add r_resizable parameter

Signed-off-by: Kacper Dąbrowski <[email protected]>

* Fix resizable flag handling in XcbNativeWindow

Signed-off-by: Kacper Dąbrowski <[email protected]>

* Replace C-style casts with static_cast

Signed-off-by: Kacper Dąbrowski <[email protected]>

---------

Signed-off-by: Kacper Dąbrowski <[email protected]>
Kacper Dąbrowski 5 月之前
父節點
當前提交
e8034ed506

+ 56 - 2
Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.cpp

@@ -59,8 +59,8 @@ namespace AzFramework
         m_xcbWindow = xcb_generate_id(m_xcbConnection);
 
         uint16_t borderWidth = 0;
-        const uint32_t mask = styleMasks.m_platformAgnosticStyleMask;
-        if ((mask & WindowStyleMasks::WINDOW_STYLE_BORDERED) || (mask & WindowStyleMasks::WINDOW_STYLE_RESIZEABLE))
+        m_styleMask = styleMasks.m_platformAgnosticStyleMask;
+        if ((m_styleMask & WindowStyleMasks::WINDOW_STYLE_BORDERED) || (m_styleMask & WindowStyleMasks::WINDOW_STYLE_RESIZEABLE))
         {
             borderWidth = s_DefaultXcbWindowBorderWidth;
         }
@@ -87,6 +87,8 @@ namespace AzFramework
         m_width = geometry.m_width;
         m_height = geometry.m_height;
 
+        SetWindowSizeHints();
+
         InitializeAtoms();
 
         xcb_client_message_event_t event;
@@ -112,6 +114,58 @@ namespace AzFramework
         xcb_flush(m_xcbConnection);
     }
 
+    void XcbNativeWindow::SetWindowSizeHints()
+    {
+        struct XcbSizeHints
+        {
+            uint32_t flags;
+            int32_t  x, y;
+            int32_t  width, height;
+            int32_t  minWidth, minHeight;
+            int32_t  maxWidth, maxHeight;
+            int32_t  widthInc, heightInc;
+            int32_t  minAspectNum, minAspectDen;
+            int32_t  maxAspectNum, maxAspectDen;
+            int32_t  baseWidth, baseHeight;
+            uint32_t winGravity;
+        };
+
+        enum XcbSizeHintsFlags
+        {
+            USPosition  = 1U << 0,
+            USSize      = 1U << 1,
+            PPosition   = 1U << 2,
+            PSize       = 1U << 3,
+            PMinSize    = 1U << 4,
+            PMaxSize    = 1U << 5,
+            PResizeInc  = 1U << 6,
+            PAspect     = 1U << 7,
+            PWinGravity = 1U << 9
+        };
+
+        XcbSizeHints hints{};
+
+        if ((m_styleMask & WindowStyleMasks::WINDOW_STYLE_RESIZEABLE) == 0)
+        {
+            hints.flags      |= XcbSizeHintsFlags::PMaxSize | XcbSizeHintsFlags::PMinSize,
+            hints.minWidth   = static_cast<int32_t>(m_width);
+            hints.minHeight  = static_cast<int32_t>(m_height);
+            hints.maxWidth   = static_cast<int32_t>(m_width);
+            hints.maxHeight  = static_cast<int32_t>(m_height);
+        }
+
+        xcb_void_cookie_t xcbCheckResult;
+        xcbCheckResult = xcb_change_property(m_xcbConnection,
+                                             XCB_PROP_MODE_REPLACE,
+                                             m_xcbWindow,
+                                             XCB_ATOM_WM_NORMAL_HINTS,
+                                             XCB_ATOM_WM_SIZE_HINTS,
+                                             32,
+                                             18,
+                                             &hints);
+        AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set window size hints.");
+    }
+
     xcb_atom_t XcbNativeWindow::GetAtom(const char* atomName)
     {
         xcb_intern_atom_cookie_t intern_atom_cookie = xcb_intern_atom(m_xcbConnection, 0, strlen(atomName), atomName);

+ 2 - 0
Code/Framework/AzFramework/Platform/Common/Xcb/AzFramework/XcbNativeWindow.h

@@ -46,6 +46,7 @@ namespace AzFramework
     private:
         bool ValidateXcbResult(xcb_void_cookie_t cookie);
         void WindowSizeChanged(const uint32_t width, const uint32_t height);
+        void SetWindowSizeHints();
         int SetAtom(xcb_window_t window, xcb_atom_t atom, xcb_atom_t type, size_t len, void* data);
 
         // Initialize one atom.
@@ -58,6 +59,7 @@ namespace AzFramework
         xcb_connection_t* m_xcbConnection = nullptr;
         xcb_screen_t* m_xcbRootScreen = nullptr;
         xcb_window_t m_xcbWindow = 0;
+        uint32_t m_styleMask;
         int32_t m_posX;
         int32_t m_posY;
         bool m_fullscreenState = false;

+ 22 - 1
Gems/Atom/Bootstrap/Code/Source/BootstrapSystemComponent.cpp

@@ -134,6 +134,7 @@ AZ_CVAR(AZ::CVarFixedString, r_default_openxr_right_pipeline_name, "passes/XRRig
 AZ_CVAR(uint32_t, r_width, 1920, cvar_r_resolution_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "Starting window width in pixels.");
 AZ_CVAR(uint32_t, r_height, 1080, cvar_r_resolution_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "Starting window height in pixels.");
 AZ_CVAR(uint32_t, r_fullscreen, false, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Starting fullscreen state.");
+AZ_CVAR(uint32_t, r_resizable, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Whether the window should be resizable.");
 AZ_CVAR(uint32_t, r_resolutionMode, 0, cvar_r_resolution_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "0: render resolution same as window client area size, 1: render resolution use the values specified by r_width and r_height");
 AZ_CVAR(float, r_renderScale, 1.0f, cvar_r_renderScale_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "Scale to apply to the window resolution.");
 AZ_CVAR(AZ::CVarFixedString, r_antiAliasing, "", cvar_r_antiAliasing_Changed, AZ::ConsoleFunctorFlags::DontReplicate, "The anti-aliasing to be used for the current render pipeline. Available options: MSAA, TAA, SMAA");
@@ -227,6 +228,20 @@ namespace AZ
                     }
                 }
 
+                const AZStd::string resizableCvarName("r_resizable");
+                if (pCmdLine->HasSwitch(resizableCvarName))
+                {
+                    auto numValues = pCmdLine->GetNumSwitchValues(resizableCvarName);
+                    if (numValues > 0)
+                    {
+                        auto valueStr = pCmdLine->GetSwitchValue(resizableCvarName);
+                        if (AZ::StringFunc::LooksLikeBool(valueStr.c_str()))
+                        {
+                            r_resizable = AZ::StringFunc::ToBool(valueStr.c_str());
+                        }
+                    }
+                }
+
                 const AZStd::string widthCvarName("r_width");
                 if (pCmdLine->HasSwitch(widthCvarName))
                 {
@@ -351,8 +366,14 @@ namespace AZ
                     // command line arguments into cvars.
                     UpdateCVarsFromCommandLine();
 
+                    AzFramework::WindowStyleMasks masks{};
+                    if (r_resizable)
+                    {
+                        masks.m_platformAgnosticStyleMask |= AzFramework::WindowStyleMasks::WINDOW_STYLE_RESIZEABLE;
+                    }
+
                     m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>(
-                        projectTitle.c_str(), AzFramework::WindowGeometry(0, 0, r_width, r_height));
+                        projectTitle.c_str(), AzFramework::WindowGeometry(0, 0, r_width, r_height), masks);
                     AZ_Assert(m_nativeWindow, "Failed to create the game window\n");
 
                     m_nativeWindow->Activate();