osu-framework
                                
                                 osu-framework copied to clipboard
                                
                                    osu-framework copied to clipboard
                            
                            
                            
                        Add ability to manage output area of tablet handler
Partially does #6150 .
Exposes area position / size bindables, implements their application.
Manually tested this in different scaling modes with different window sizes/positions on display, seems to work as expected.
Ad-hoc diff for osu!:
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index c244708385..e82abc233e 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -68,6 +68,7 @@
 using osu.Game.Updater;
 using osu.Game.Users;
 using osu.Game.Utils;
+using osuTK;
 using osuTK.Graphics;
 using Sentry;
 
@@ -1134,10 +1135,46 @@ protected override void LoadComplete()
                 if (mode.NewValue != OverlayActivation.All) CloseAllOverlays();
             };
 
+            {
+                var tablet = Host.AvailableInputHandlers.OfType<ITabletHandler>().FirstOrDefault();
+
+                if (tablet != null)
+                {
+                    scalingMode = LocalConfig.GetBindable<ScalingMode>(OsuSetting.Scaling);
+                    scalingSizeX = LocalConfig.GetBindable<float>(OsuSetting.ScalingSizeX);
+                    scalingSizeY = LocalConfig.GetBindable<float>(OsuSetting.ScalingSizeY);
+                    scalingPositionX = LocalConfig.GetBindable<float>(OsuSetting.ScalingPositionX);
+                    scalingPositionY = LocalConfig.GetBindable<float>(OsuSetting.ScalingPositionY);
+
+                    void updateAreaSize(ValueChangedEvent<float> _)
+                    {
+                        if (scalingMode.Value == ScalingMode.Everything)
+                            tablet.OutputAreaSize.Value = new Vector2(scalingSizeX.Value, scalingSizeY.Value);
+                        else
+                            tablet.OutputAreaSize.Value = new Vector2(1, 1);
+                    }
+
+                    scalingMode.ValueChanged += _ => updateAreaSize(null!);
+                    scalingSizeX.ValueChanged += updateAreaSize;
+                    scalingSizeY.ValueChanged += updateAreaSize;
+                    scalingPositionX.ValueChanged += _ => tablet.OutputAreaPosition.Value = new Vector2(scalingPositionX.Value, scalingPositionY.Value);
+                    scalingPositionY.ValueChanged += _ => tablet.OutputAreaPosition.Value = new Vector2(scalingPositionX.Value, scalingPositionY.Value);
+
+                    updateAreaSize(null!);
+                    tablet.OutputAreaPosition.Value = new Vector2(scalingPositionX.Value, scalingPositionY.Value);
+                }
+            }
+
             // Importantly, this should be run after binding PostNotification to the import handlers so they can present the import after game startup.
             handleStartupImport();
         }
 
+        private Bindable<ScalingMode> scalingMode = null!;
+        private Bindable<float> scalingPositionX = null!;
+        private Bindable<float> scalingPositionY = null!;
+        private Bindable<float> scalingSizeX = null!;
+        private Bindable<float> scalingSizeY = null!;
+
         private void handleStartupImport()
         {
             if (args?.Length > 0)