Make mouse capture handle window moving/resizing/focus change, cleanup presentation panel resize handling

This commit is contained in:
CasualPokePlayer 2025-02-24 16:07:20 -08:00
parent a2daa48cf4
commit 0311bb5d39
3 changed files with 55 additions and 53 deletions

View File

@ -886,12 +886,7 @@ namespace BizHawk.Client.EmuHawk
RewireSound();
}
old = Config.VSyncThrottle;
Config.VSyncThrottle = false;
if (old)
{
_presentationPanel.Resized = true;
}
}
ThrottleMessage();
@ -904,12 +899,7 @@ namespace BizHawk.Client.EmuHawk
if (Config.SoundThrottle)
{
Config.ClockThrottle = false;
var old = Config.VSyncThrottle;
Config.VSyncThrottle = false;
if (old)
{
_presentationPanel.Resized = true;
}
}
ThrottleMessage();
@ -918,7 +908,6 @@ namespace BizHawk.Client.EmuHawk
private void VsyncThrottleMenuItem_Click(object sender, EventArgs e)
{
Config.VSyncThrottle = !Config.VSyncThrottle;
_presentationPanel.Resized = true;
if (Config.VSyncThrottle)
{
Config.ClockThrottle = false;
@ -942,11 +931,6 @@ namespace BizHawk.Client.EmuHawk
private void VsyncEnabledMenuItem_Click(object sender, EventArgs e)
{
Config.VSync = !Config.VSync;
if (!Config.VSyncThrottle) // when vsync throttle is on, vsync is forced to on, so no change to make here
{
_presentationPanel.Resized = true;
}
VsyncMessage();
}
@ -1577,7 +1561,12 @@ namespace BizHawk.Client.EmuHawk
private void MainForm_Resize(object sender, EventArgs e)
{
_presentationPanel.Resized = true;
if (Config.CaptureMouse)
{
CaptureMouse(false);
CaptureMouse(true);
}
if (_framebufferResizedPending && WindowState is FormWindowState.Normal)
{
_framebufferResizedPending = false;

View File

@ -538,6 +538,7 @@ namespace BizHawk.Client.EmuHawk
ResizeBegin += (o, e) =>
{
_inResizeLoop = true;
if (!OSTailoredCode.IsUnixHost)
{
Sound?.StopSound();
@ -551,17 +552,30 @@ namespace BizHawk.Client.EmuHawk
_inResizeLoop = false;
UpdateWindowTitle();
if (_presentationPanel != null)
{
_presentationPanel.Resized = true;
}
if (!OSTailoredCode.IsUnixHost)
{
Sound?.StartSound();
}
};
_presentationPanel.Control.Move += (_, _) =>
{
if (Config.CaptureMouse)
{
CaptureMouse(false);
CaptureMouse(true);
}
};
_presentationPanel.Control.Resize += (_, _) =>
{
if (Config.CaptureMouse)
{
CaptureMouse(false);
CaptureMouse(true);
}
};
if (!Config.GCAdapterSupportEnabled)
{
// annoyingly this isn't an SDL hint in SDL2, only in SDL3, have to use an environment variables to signal this
@ -961,6 +975,7 @@ namespace BizHawk.Client.EmuHawk
if (disposing)
{
components?.Dispose();
_presentationPanel?.Dispose();
SingleInstanceDispose();
}
@ -1185,11 +1200,23 @@ namespace BizHawk.Client.EmuHawk
{
base.OnActivated(e);
Input.Instance.ControlInputFocus(this, HostInputType.Mouse, true);
if (Config.CaptureMouse)
{
CaptureMouse(false);
CaptureMouse(true);
}
}
protected override void OnDeactivate(EventArgs e)
{
Input.Instance.ControlInputFocus(this, HostInputType.Mouse, false);
if (Config.CaptureMouse)
{
CaptureMouse(false);
}
base.OnDeactivate(e);
}
@ -1492,7 +1519,6 @@ namespace BizHawk.Client.EmuHawk
// Change size
Size = new Size(lastComputedSize.Width + borderWidth, lastComputedSize.Height + borderHeight);
PerformLayout();
_presentationPanel.Resized = true;
// Is window off the screen at this size?
if (!area.Contains(Bounds))
@ -1511,6 +1537,7 @@ namespace BizHawk.Client.EmuHawk
}
}
}
DoPresentationPanelResize();
DoPresentationPanelResize();
}
@ -1588,8 +1615,6 @@ namespace BizHawk.Client.EmuHawk
SynchChrome();
WindowState = FormWindowState.Maximized; // be sure to do this after setting the chrome, otherwise it wont work fully
ResumeLayout();
_presentationPanel.Resized = true;
}
else
{
@ -4859,6 +4884,7 @@ namespace BizHawk.Client.EmuHawk
Cursor.Hide();
_presentationPanel.Control.Cursor = Properties.Resources.BlankCursor;
_cursorHidden = true;
BringToFront();
}
else
{
@ -4904,6 +4930,15 @@ namespace BizHawk.Client.EmuHawk
if (_hasXFixes)
{
for (var i = 0; i < 4; i++)
{
if (_pointerBarriers[i] != IntPtr.Zero)
{
XfixesImports.XFixesDestroyPointerBarrier(_x11Display, _pointerBarriers[i]);
_pointerBarriers[i] = IntPtr.Zero;
}
}
if (wantCapture)
{
var fbLocation = Point.Subtract(Bounds.Location, new(PointToClient(Location)));
@ -4939,17 +4974,6 @@ namespace BizHawk.Client.EmuHawk
XlibImports.GrabMode.Async, XlibImports.GrabMode.Async, _presentationPanel.Control.Handle, IntPtr.Zero, XlibImports.CurrentTime);
_ = XlibImports.XUngrabPointer(_x11Display, XlibImports.CurrentTime);
}
else
{
for (var i = 0; i < 4; i++)
{
if (_pointerBarriers[i] != IntPtr.Zero)
{
XfixesImports.XFixesDestroyPointerBarrier(_x11Display, _pointerBarriers[i]);
_pointerBarriers[i] = IntPtr.Zero;
}
}
}
_ = XlibImports.XFlush(_x11Display);
}
@ -4961,25 +4985,16 @@ namespace BizHawk.Client.EmuHawk
_x11Display = XlibImports.XOpenDisplay(null);
}
// always returns 1
_ = XlibImports.XUngrabPointer(_x11Display, XlibImports.CurrentTime);
if (wantCapture)
{
const XlibImports.EventMask eventMask = XlibImports.EventMask.ButtonPressMask | XlibImports.EventMask.ButtonMotionMask
| XlibImports.EventMask.ButtonReleaseMask | XlibImports.EventMask.PointerMotionMask | XlibImports.EventMask.PointerMotionHintMask
| XlibImports.EventMask.EnterWindowMask | XlibImports.EventMask.LeaveWindowMask | XlibImports.EventMask.FocusChangeMask;
var grabResult = XlibImports.XGrabPointer(_x11Display, Handle, false, eventMask,
XlibImports.GrabMode.Async, XlibImports.GrabMode.Async, _presentationPanel.Control.Handle, IntPtr.Zero, XlibImports.CurrentTime);
if (grabResult == XlibImports.GrabResult.AlreadyGrabbed)
{
// try to grab again after releasing whatever current active grab
_ = XlibImports.XUngrabPointer(_x11Display, XlibImports.CurrentTime);
_ = XlibImports.XGrabPointer(_x11Display, Handle, false, eventMask,
XlibImports.GrabMode.Async, XlibImports.GrabMode.Async, _presentationPanel.Control.Handle, IntPtr.Zero, XlibImports.CurrentTime);
}
}
else
{
// always returns 1
_ = XlibImports.XUngrabPointer(_x11Display, XlibImports.CurrentTime);
_ = XlibImports.XGrabPointer(_x11Display, Handle, false, eventMask, XlibImports.GrabMode.Async,
XlibImports.GrabMode.Async, _presentationPanel.Control.Handle, IntPtr.Zero, XlibImports.CurrentTime);
}
_ = XlibImports.XFlush(_x11Display);

View File

@ -10,7 +10,7 @@ namespace BizHawk.Client.EmuHawk
/// <summary>
/// Thinly wraps a GraphicsControl for EmuHawk's needs
/// </summary>
public class PresentationPanel
public class PresentationPanel : IDisposable
{
private readonly Config _config;
@ -72,8 +72,6 @@ namespace BizHawk.Client.EmuHawk
}
}
public bool Resized { get; set; }
public Size NativeSize => GraphicsControl.ClientSize;
}
}