Forest Logo
search
package_2

guicompatibility

By @coffilhg

Roblox

Mirrored from Wally

GUICompatibility

Useful for detecting GUI Insets

Available Here!

  • This repository ~ src/init.luau

  • Wally

    GUICompatibility = "coffilhg/guicompatibility@1.0.0"
    
  • Rotriever

    GUICompatibility = "github.com/Coffilhg/Useful-Modules@GUICompatibility/1.0.0"
    

To-Do

  • Add A Proper README

Basic example:

Client-sided script

[image: 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.]

--!strict
const Players = game:GetService(`Players`)
const UIS = game:GetService(`UserInputService`)

const GUICompatibility = require(`./Packages/GUICompatibility`)

const Player = Players.LocalPlayer :: Player
const PG = Player.PlayerGui
const UI = Instance.new(`ScreenGui`)
UI.ResetOnSpawn = false
UI.IgnoreGuiInset = false
UI.ClipToDeviceSafeArea = false
UI.Parent = PG
const GuiInsetSize = GUICompatibility:GetGuiInsetSize()

const pointer = Instance.new("Frame")
pointer.Size = UDim2.fromOffset(12, 12)
pointer.AnchorPoint = Vector2.new(.5, .5)
pointer.BorderSizePixel = 0
pointer.BackgroundColor3 = Color3.fromRGB(255, 60, 255)
pointer.Parent = UI
Instance.new("UICorner", pointer).CornerRadius = UDim.new(1, 0)

const safeArea = Instance.new("Frame")
safeArea.Size = UDim2.fromOffset(0, 0)
safeArea.AnchorPoint = Vector2.new(.5, 1)
safeArea.Position = UDim2.fromScale(.5, 1)
safeArea.Size = UDim2.fromScale(1, 0.1)
safeArea.BorderSizePixel = 0
safeArea.BackgroundColor3 = Color3.fromRGB(160, 60, 255)
safeArea.ZIndex = -1
safeArea.Parent = UI

const fullAreaX = Instance.new("Frame")
fullAreaX.Size = UDim2.fromOffset(0, 0)
fullAreaX.AnchorPoint = Vector2.new(.5, 1)
fullAreaX.Position = UDim2.fromScale(.5, 1)
fullAreaX.BorderSizePixel = 0
fullAreaX.BackgroundColor3 = Color3.fromRGB(255, 229, 60)
fullAreaX.ZIndex = -2
fullAreaX.Parent = UI

const safeAreaYBottomLabel = Instance.new("TextLabel")
safeAreaYBottomLabel.Size = UDim2.fromOffset(0.1, 0)
safeAreaYBottomLabel.AnchorPoint = Vector2.new(.5, 0)
safeAreaYBottomLabel.Position = UDim2.fromScale(.5, 1)
safeAreaYBottomLabel.BorderSizePixel = 0
safeAreaYBottomLabel.BackgroundColor3 = Color3.fromRGB(21, 21, 21)
safeAreaYBottomLabel.TextScaled = true
safeAreaYBottomLabel.TextWrapped = true
safeAreaYBottomLabel.TextColor3 = Color3.fromRGB(245, 245, 245)
safeAreaYBottomLabel.ZIndex = -1
safeAreaYBottomLabel.Parent = UI

const safeAreaYTopLabel = Instance.new("TextLabel")
safeAreaYTopLabel.Size = UDim2.fromOffset(0.1, 0)
safeAreaYTopLabel.AnchorPoint = Vector2.new(.5, UI.IgnoreGuiInset and 0 or 1)
safeAreaYTopLabel.Position = UDim2.fromScale(.5, 0)
safeAreaYTopLabel.BorderSizePixel = 0
safeAreaYTopLabel.BackgroundColor3 = Color3.fromRGB(21, 21, 21)
safeAreaYTopLabel.TextScaled = true
safeAreaYTopLabel.TextWrapped = true
safeAreaYTopLabel.TextColor3 = Color3.fromRGB(245, 245, 245)
safeAreaYTopLabel.ZIndex = -1
safeAreaYTopLabel.Parent = UI

--UIS.InputBegan:Connect(function(input: InputObject, isProcessed: boolean)
--	if isProcessed then
--		return
--	end
	
--	if input.KeyCode == Enum.KeyCode.E then
--		const pixel = Instance.new("Frame")
--		pixel.Size = UDim2.fromOffset(3, 3)
--		pixel.AnchorPoint = Vector2.new(.5, .5)
--		pixel.BorderSizePixel = 0
--		pixel.BackgroundColor3 = Color3.fromRGB(255, 60, 255)
--		const accuratePosition = UIS:GetMouseLocation() - Vector2.new(0, GuiInsetSize.Value)
--		pixel.Position = UDim2.fromOffset(accuratePosition.X, accuratePosition.Y)
--		pixel.Parent = UI
-- correct with IgnoreGuiInset = false
--		print(pixel)
--	end
--end)

UIS.InputChanged:Connect(function(input: InputObject, isProcessed: boolean)
	
	if UI.IgnoreGuiInset then
		-- correct with IgnoreGuiInset = true
		pointer.Position = UDim2.fromOffset(input.Position.X, input.Position.Y + GuiInsetSize.Value)
	else
		-- correct with IgnoreGuiInset = false
		pointer.Position = UDim2.fromOffset(input.Position.X, input.Position.Y)
	end
	
	print(GuiInsetSize.Value, GUICompatibility:GetSafeInsetsSize())
	
	const safeInsetsSize = GUICompatibility:GetSafeInsetsSize()
	fullAreaX.Size = UDim2.new(1, safeInsetsSize.X, 0.1, 0)
	
	safeAreaYBottomLabel.Size = UDim2.new(0.1, 0, 0, safeInsetsSize.Y)
	safeAreaYBottomLabel.Text = `{safeInsetsSize.Y} px`
	
	safeAreaYTopLabel.Size = UDim2.new(0.1, 0, 0, GuiInsetSize.Value)
	safeAreaYTopLabel.Text = `{GuiInsetSize.Value} px`
end)

License & Attribution

This module is licensed under the Mozilla Public License 2.0 (MPL-2.0).

What this means for Roblox Developers:

  • Use & Modify: You can freely use this module in any public, private, or commercial Roblox game.
  • 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.
  • 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.

See the full terms in the LICENSE file.

Attribution to all dependencies is included in Notice

Copyright © 2026 @Coffilhg (Roblox UserId 517222346)

Package Details

Install command (Click to copy)


Version

1.0.0

License

MPL-2.0

warning

Usable with conditions

infoFile-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.

Automated license review — not legal advice.