{"id":"coffilhg/guicompatibility","name":"guicompatibility","scope":"coffilhg","platform":"roblox","description":"Useful for detecting GUI Insets","version":"1.0.0","latest":"1.0.0","versions":["1.0.0"],"license":"MPL-2.0","licenseRating":"caution","licenseCaveats":["File-level copyleft: if you modify this package's own source files, those modified files must be made available under MPL-2.0. Using it unmodified in a closed-source game is fine."],"licenseVerified":true,"dependencies":{"coffilhg/coffeeobjects":{"version":"^2.4.0","alias":"CoffeeObjects"}},"integrity":"3dd594f7f06a5f76e7b2b49e18f08ea7a013a77cc9d586a784df0bb2be4516ac","likes":0,"downloads":0,"install":"forest install coffilhg/guicompatibility","url":"https://forest.dev/p/roblox/coffilhg/guicompatibility","files":"https://api.forest.dev/ai/package/roblox/coffilhg/guicompatibility/files","readme":"# GUICompatibility\r\n\r\nUseful for detecting GUI Insets\r\n\r\n\r\n\r\n## Available Here!\r\n- **[This repository](src/init.luau) ~ [src/init.luau](src/init.luau)**\r\n- **[Wally](<https://wally.run/package/coffilhg/guicompatibility>)**\r\n\r\n    ```toml\r\n    GUICompatibility = \"coffilhg/guicompatibility@1.0.0\"\r\n    ```\r\n- **[Rotriever](<https://github.com/Coffilhg/Useful-Modules/releases/tag/vGUICompatibility/1.0.0>)**\r\n\r\n    ```toml\r\n    GUICompatibility = \"github.com/Coffilhg/Useful-Modules@GUICompatibility/1.0.0\"\r\n    ```\r\n\r\n<!-- **[Creator Store](<https://create.roblox.com/store/category/gameplay?creatorName=coffilhg>)** ~ **[GUICompatibility](<https://create.roblox.com/store/asset/123456789/GUICompatibility>)**-->\r\n\r\n---\r\n\r\n# To-Do\r\n- [ ] Add A Proper README\r\n\r\n---\r\n\r\n## Basic example:\r\n> **Client-sided script**\r\n\r\n![Example image showcases how the UI generated by the example script below would look like on an iPhone 16. The UI elements are scaled exactly to the size of safe screen areas calculated by this module. A black text label at the top center displays \"58 px\". A horizontal purple bar spans the bottom safe area of the screen, with yellow rectangles on its far left and right ends marking the unsafe side margins. Below the purple bar, another black text label displays \"21 px\". A small pink circular pointer is also visible near the center-right of the screen, demonstrating accurate input position tracking.](./images/example.png \"Example Code Preview\")\r\n\r\n```lua\r\n--!strict\r\nconst Players = game:GetService(`Players`)\r\nconst UIS = game:GetService(`UserInputService`)\r\n\r\nconst GUICompatibility = require(`./Packages/GUICompatibility`)\r\n\r\nconst Player = Players.LocalPlayer :: Player\r\nconst PG = Player.PlayerGui\r\nconst UI = Instance.new(`ScreenGui`)\r\nUI.ResetOnSpawn = false\r\nUI.IgnoreGuiInset = false\r\nUI.ClipToDeviceSafeArea = false\r\nUI.Parent = PG\r\nconst GuiInsetSize = GUICompatibility:GetGuiInsetSize()\r\n\r\nconst pointer = Instance.new(\"Frame\")\r\npointer.Size = UDim2.fromOffset(12, 12)\r\npointer.AnchorPoint = Vector2.new(.5, .5)\r\npointer.BorderSizePixel = 0\r\npointer.BackgroundColor3 = Color3.fromRGB(255, 60, 255)\r\npointer.Parent = UI\r\nInstance.new(\"UICorner\", pointer).CornerRadius = UDim.new(1, 0)\r\n\r\nconst safeArea = Instance.new(\"Frame\")\r\nsafeArea.Size = UDim2.fromOffset(0, 0)\r\nsafeArea.AnchorPoint = Vector2.new(.5, 1)\r\nsafeArea.Position = UDim2.fromScale(.5, 1)\r\nsafeArea.Size = UDim2.fromScale(1, 0.1)\r\nsafeArea.BorderSizePixel = 0\r\nsafeArea.BackgroundColor3 = Color3.fromRGB(160, 60, 255)\r\nsafeArea.ZIndex = -1\r\nsafeArea.Parent = UI\r\n\r\nconst fullAreaX = Instance.new(\"Frame\")\r\nfullAreaX.Size = UDim2.fromOffset(0, 0)\r\nfullAreaX.AnchorPoint = Vector2.new(.5, 1)\r\nfullAreaX.Position = UDim2.fromScale(.5, 1)\r\nfullAreaX.BorderSizePixel = 0\r\nfullAreaX.BackgroundColor3 = Color3.fromRGB(255, 229, 60)\r\nfullAreaX.ZIndex = -2\r\nfullAreaX.Parent = UI\r\n\r\nconst safeAreaYBottomLabel = Instance.new(\"TextLabel\")\r\nsafeAreaYBottomLabel.Size = UDim2.fromOffset(0.1, 0)\r\nsafeAreaYBottomLabel.AnchorPoint = Vector2.new(.5, 0)\r\nsafeAreaYBottomLabel.Position = UDim2.fromScale(.5, 1)\r\nsafeAreaYBottomLabel.BorderSizePixel = 0\r\nsafeAreaYBottomLabel.BackgroundColor3 = Color3.fromRGB(21, 21, 21)\r\nsafeAreaYBottomLabel.TextScaled = true\r\nsafeAreaYBottomLabel.TextWrapped = true\r\nsafeAreaYBottomLabel.TextColor3 = Color3.fromRGB(245, 245, 245)\r\nsafeAreaYBottomLabel.ZIndex = -1\r\nsafeAreaYBottomLabel.Parent = UI\r\n\r\nconst safeAreaYTopLabel = Instance.new(\"TextLabel\")\r\nsafeAreaYTopLabel.Size = UDim2.fromOffset(0.1, 0)\r\nsafeAreaYTopLabel.AnchorPoint = Vector2.new(.5, UI.IgnoreGuiInset and 0 or 1)\r\nsafeAreaYTopLabel.Position = UDim2.fromScale(.5, 0)\r\nsafeAreaYTopLabel.BorderSizePixel = 0\r\nsafeAreaYTopLabel.BackgroundColor3 = Color3.fromRGB(21, 21, 21)\r\nsafeAreaYTopLabel.TextScaled = true\r\nsafeAreaYTopLabel.TextWrapped = true\r\nsafeAreaYTopLabel.TextColor3 = Color3.fromRGB(245, 245, 245)\r\nsafeAreaYTopLabel.ZIndex = -1\r\nsafeAreaYTopLabel.Parent = UI\r\n\r\n--UIS.InputBegan:Connect(function(input: InputObject, isProcessed: boolean)\r\n--\tif isProcessed then\r\n--\t\treturn\r\n--\tend\r\n\t\r\n--\tif input.KeyCode == Enum.KeyCode.E then\r\n--\t\tconst pixel = Instance.new(\"Frame\")\r\n--\t\tpixel.Size = UDim2.fromOffset(3, 3)\r\n--\t\tpixel.AnchorPoint = Vector2.new(.5, .5)\r\n--\t\tpixel.BorderSizePixel = 0\r\n--\t\tpixel.BackgroundColor3 = Color3.fromRGB(255, 60, 255)\r\n--\t\tconst accuratePosition = UIS:GetMouseLocation() - Vector2.new(0, GuiInsetSize.Value)\r\n--\t\tpixel.Position = UDim2.fromOffset(accuratePosition.X, accuratePosition.Y)\r\n--\t\tpixel.Parent = UI\r\n-- correct with IgnoreGuiInset = false\r\n--\t\tprint(pixel)\r\n--\tend\r\n--end)\r\n\r\nUIS.InputChanged:Connect(function(input: InputObject, isProcessed: boolean)\r\n\t\r\n\tif UI.IgnoreGuiInset then\r\n\t\t-- correct with IgnoreGuiInset = true\r\n\t\tpointer.Position = UDim2.fromOffset(input.Position.X, input.Position.Y + GuiInsetSize.Value)\r\n\telse\r\n\t\t-- correct with IgnoreGuiInset = false\r\n\t\tpointer.Position = UDim2.fromOffset(input.Position.X, input.Position.Y)\r\n\tend\r\n\t\r\n\tprint(GuiInsetSize.Value, GUICompatibility:GetSafeInsetsSize())\r\n\t\r\n\tconst safeInsetsSize = GUICompatibility:GetSafeInsetsSize()\r\n\tfullAreaX.Size = UDim2.new(1, safeInsetsSize.X, 0.1, 0)\r\n\t\r\n\tsafeAreaYBottomLabel.Size = UDim2.new(0.1, 0, 0, safeInsetsSize.Y)\r\n\tsafeAreaYBottomLabel.Text = `{safeInsetsSize.Y} px`\r\n\t\r\n\tsafeAreaYTopLabel.Size = UDim2.new(0.1, 0, 0, GuiInsetSize.Value)\r\n\tsafeAreaYTopLabel.Text = `{GuiInsetSize.Value} px`\r\nend)\r\n```\r\n\r\n---\r\n\r\n## License & Attribution\r\n\r\nThis module is licensed under the **Mozilla Public License 2.0 (MPL-2.0)**.\r\n\r\n#### What this means for Roblox Developers:\r\n* **Use & Modify:** You can freely use this module in any public, private, or commercial Roblox game.\r\n* **File-Level Copyleft:** If you modify the source code of this module itself, you must make your modified version of the module publicly available under the MPL 2.0.\r\n* **No Viral Code Leakage:** Including this module in your game does **not** force you to open-source your other game scripts, UI layouts, or proprietary codebase. \r\n\r\nSee the full terms in the [LICENSE](LICENSE) file.\r\n\r\nAttribution to all dependencies is included in [Notice](NOTICE)\r\n\r\nCopyright © 2026 @Coffilhg (Roblox UserId 517222346)","readmeTruncated":false}