From d8a4e2227ad0555e6b158f28f6c9e20d623acd9a Mon Sep 17 00:00:00 2001 From: emmauss Date: Fri, 7 Feb 2020 09:44:38 +0000 Subject: [PATCH] fix fullscreen state, fix focus, addressed comments --- Ryujinx/Ui/GLRenderer.cs | 40 +- Ryujinx/Ui/GLScreen.cs | 375 ------------------ Ryujinx/Ui/MainWindow.cs | 28 +- Ryujinx/Ui/MainWindow.glade | 9 +- ...{ScopedGLContext.cs => ScopedGlContext.cs} | 4 +- 5 files changed, 47 insertions(+), 409 deletions(-) delete mode 100644 Ryujinx/Ui/GLScreen.cs rename Ryujinx/Ui/{ScopedGLContext.cs => ScopedGlContext.cs} (86%) diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs index 563510ce9f..4c8ce225f8 100644 --- a/Ryujinx/Ui/GLRenderer.cs +++ b/Ryujinx/Ui/GLRenderer.cs @@ -26,7 +26,7 @@ namespace Ryujinx.Ui public bool IsActive { get; set; } public bool IsStopped { get; set; } - public bool IsFocused { get; set; } = false; + public bool IsFocused { get; set; } private double _mouseX; private double _mouseY; @@ -70,11 +70,13 @@ namespace Ryujinx.Ui _primaryController = new Input.NpadController(ConfigurationState.Instance.Hid.JoystickControls); - AddEvents((int)(Gdk.EventMask.ButtonPressMask | - Gdk.EventMask.ButtonReleaseMask | - Gdk.EventMask.PointerMotionMask | - Gdk.EventMask.KeyPressMask | - Gdk.EventMask.KeyReleaseMask)); + AddEvents((int)(Gdk.EventMask.ButtonPressMask + | Gdk.EventMask.ButtonReleaseMask + | Gdk.EventMask.PointerMotionMask + | Gdk.EventMask.KeyPressMask + | Gdk.EventMask.KeyReleaseMask)); + + this.Shown += Renderer_Shown; } private void Parent_FocusOutEvent(object o, Gtk.FocusOutEventArgs args) @@ -94,11 +96,17 @@ namespace Ryujinx.Ui this.Dispose(); } + protected void Renderer_Shown(object sender, EventArgs e) + { + IsFocused = this.ParentWindow.State.HasFlag(Gdk.WindowState.Focused); + } + public void HandleScreenState(KeyboardState keyboard) { - bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11) || - ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft) || keyboard.IsKeyDown(OpenTK.Input.Key.AltRight)) - && keyboard.IsKeyDown(OpenTK.Input.Key.Enter)); + bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11) + || ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft) + || keyboard.IsKeyDown(OpenTK.Input.Key.AltRight)) + && keyboard.IsKeyDown(OpenTK.Input.Key.Enter)); if (toggleFullscreen == _toggleFullscreen) { @@ -107,9 +115,9 @@ namespace Ryujinx.Ui _toggleFullscreen = toggleFullscreen; - if (IsFocused) + Gtk.Application.Invoke(delegate { - if (this.ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen) ) + if (this.ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen)) { if (keyboard.IsKeyDown(OpenTK.Input.Key.Escape) || _toggleFullscreen) { @@ -130,7 +138,7 @@ namespace Ryujinx.Ui (this.Toplevel as MainWindow)?.ToggleExtraWidgets(false); } } - } + }); } private void GLRenderer_Initialized(object sender, EventArgs e) @@ -225,7 +233,7 @@ namespace Ryujinx.Ui IsStopped = true; IsActive = false; - using (ScopedGLContext scopedGLContext = new ScopedGLContext(WindowInfo, GraphicsContext)) + using (ScopedGlContext scopedGLContext = new ScopedGlContext(WindowInfo, GraphicsContext)) { _device.DisposeGpu(); } @@ -245,7 +253,7 @@ namespace Ryujinx.Ui public void Render() { - using (ScopedGLContext scopedGLContext = new ScopedGLContext(WindowInfo, GraphicsContext)) + using (ScopedGlContext scopedGLContext = new ScopedGlContext(WindowInfo, GraphicsContext)) { _renderer.Initialize(); @@ -259,7 +267,7 @@ namespace Ryujinx.Ui return; } - using (ScopedGLContext scopedGLContext = new ScopedGLContext(WindowInfo, GraphicsContext)) + using (ScopedGlContext scopedGLContext = new ScopedGlContext(WindowInfo, GraphicsContext)) { _ticks += _chrono.ElapsedTicks; @@ -318,6 +326,7 @@ namespace Ryujinx.Ui this.ParentWindow.Title = _newTitle; }); } + if (IsFocused) { UpdateFrame(); @@ -424,7 +433,6 @@ namespace Ryujinx.Ui screenHeight = (AllocatedWidth * TouchScreenHeight) / TouchScreenWidth; } - int startX = (AllocatedWidth - screenWidth) >> 1; int startY = (AllocatedHeight - screenHeight) >> 1; diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs deleted file mode 100644 index 5e83458aef..0000000000 --- a/Ryujinx/Ui/GLScreen.cs +++ /dev/null @@ -1,375 +0,0 @@ -using OpenTK; -using OpenTK.Graphics; -using OpenTK.Input; -using Ryujinx.Configuration; -using Ryujinx.Graphics.OpenGL; -using Ryujinx.HLE; -using Ryujinx.HLE.Input; -using System; -using System.Threading; - -using Stopwatch = System.Diagnostics.Stopwatch; - -namespace Ryujinx.Ui -{ - public class GlScreen : GameWindow - { - private const int TouchScreenWidth = 1280; - private const int TouchScreenHeight = 720; - - private const int TargetFps = 60; - - private Switch _device; - - private Renderer _renderer; - - private HotkeyButtons _prevHotkeyButtons = 0; - - private KeyboardState? _keyboard = null; - - private MouseState? _mouse = null; - - private Input.NpadController _primaryController; - - private Thread _renderThread; - - private bool _resizeEvent; - - private bool _titleEvent; - - private string _newTitle; - - public GlScreen(Switch device) - : base(1280, 720, - new GraphicsMode(), "Ryujinx", 0, - DisplayDevice.Default, 3, 3, - GraphicsContextFlags.ForwardCompatible) - { - _device = device; - - if (!(device.Gpu.Renderer is Renderer)) - { - throw new NotSupportedException($"GPU renderer must be an OpenGL renderer when using GlScreen!"); - } - - _renderer = (Renderer)device.Gpu.Renderer; - - _primaryController = new Input.NpadController(ConfigurationState.Instance.Hid.JoystickControls); - - Location = new Point( - (DisplayDevice.Default.Width / 2) - (Width / 2), - (DisplayDevice.Default.Height / 2) - (Height / 2)); - } - - private void RenderLoop() - { - MakeCurrent(); - - _renderer.Initialize(); - - Stopwatch chrono = new Stopwatch(); - - chrono.Start(); - - long ticksPerFrame = Stopwatch.Frequency / TargetFps; - - long ticks = 0; - - while (Exists && !IsExiting) - { - if (_device.WaitFifo()) - { - _device.ProcessFrame(); - } - - if (_resizeEvent) - { - _resizeEvent = false; - - _renderer.Window.SetSize(Width, Height); - } - - ticks += chrono.ElapsedTicks; - - chrono.Restart(); - - if (ticks >= ticksPerFrame) - { - RenderFrame(); - - // Queue max. 1 vsync - ticks = Math.Min(ticks - ticksPerFrame, ticksPerFrame); - } - } - - _device.DisposeGpu(); - } - - public void MainLoop() - { - VSync = VSyncMode.Off; - - Visible = true; - - Context.MakeCurrent(null); - - // OpenTK doesn't like sleeps in its thread, to avoid this a renderer thread is created - _renderThread = new Thread(RenderLoop) - { - Name = "GUI.RenderThread" - }; - - _renderThread.Start(); - - while (Exists && !IsExiting) - { - ProcessEvents(); - - if (!IsExiting) - { - UpdateFrame(); - - if (_titleEvent) - { - _titleEvent = false; - - Title = _newTitle; - } - } - - // Polling becomes expensive if it's not slept - Thread.Sleep(1); - } - } - - private new void UpdateFrame() - { - HotkeyButtons currentHotkeyButtons = 0; - ControllerButtons currentButton = 0; - JoystickPosition leftJoystick; - JoystickPosition rightJoystick; - HLE.Input.Keyboard? hidKeyboard = null; - - int leftJoystickDx = 0; - int leftJoystickDy = 0; - int rightJoystickDx = 0; - int rightJoystickDy = 0; - - // Keyboard Input - if (_keyboard.HasValue) - { - KeyboardState keyboard = _keyboard.Value; - - // Normal Input - currentHotkeyButtons = KeyboardControls.GetHotkeyButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard); - currentButton = KeyboardControls.GetButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard); - - if (ConfigurationState.Instance.Hid.EnableKeyboard) - { - hidKeyboard = KeyboardControls.GetKeysDown(ConfigurationState.Instance.Hid.KeyboardControls, keyboard); - } - - (leftJoystickDx, leftJoystickDy) = KeyboardControls.GetLeftStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard); - (rightJoystickDx, rightJoystickDy) = KeyboardControls.GetRightStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard); - } - - if (!hidKeyboard.HasValue) - { - hidKeyboard = new HLE.Input.Keyboard - { - Modifier = 0, - Keys = new int[0x8] - }; - } - - currentButton |= _primaryController.GetButtons(); - - // Keyboard has priority stick-wise - if (leftJoystickDx == 0 && leftJoystickDy == 0) - { - (leftJoystickDx, leftJoystickDy) = _primaryController.GetLeftStick(); - } - - if (rightJoystickDx == 0 && rightJoystickDy == 0) - { - (rightJoystickDx, rightJoystickDy) = _primaryController.GetRightStick(); - } - - leftJoystick = new JoystickPosition - { - Dx = leftJoystickDx, - Dy = leftJoystickDy - }; - - rightJoystick = new JoystickPosition - { - Dx = rightJoystickDx, - Dy = rightJoystickDy - }; - - currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick); - - bool hasTouch = false; - - // Get screen touch position from left mouse click - // OpenTK always captures mouse events, even if out of focus, so check if window is focused. - if (Focused && _mouse?.LeftButton == ButtonState.Pressed) - { - MouseState mouse = _mouse.Value; - - int scrnWidth = Width; - int scrnHeight = Height; - - if (Width > (Height * TouchScreenWidth) / TouchScreenHeight) - { - scrnWidth = (Height * TouchScreenWidth) / TouchScreenHeight; - } - else - { - scrnHeight = (Width * TouchScreenHeight) / TouchScreenWidth; - } - - int startX = (Width - scrnWidth) >> 1; - int startY = (Height - scrnHeight) >> 1; - - int endX = startX + scrnWidth; - int endY = startY + scrnHeight; - - if (mouse.X >= startX && - mouse.Y >= startY && - mouse.X < endX && - mouse.Y < endY) - { - int scrnMouseX = mouse.X - startX; - int scrnMouseY = mouse.Y - startY; - - int mX = (scrnMouseX * TouchScreenWidth) / scrnWidth; - int mY = (scrnMouseY * TouchScreenHeight) / scrnHeight; - - TouchPoint currentPoint = new TouchPoint - { - X = mX, - Y = mY, - - // Placeholder values till more data is acquired - DiameterX = 10, - DiameterY = 10, - Angle = 90 - }; - - hasTouch = true; - - _device.Hid.SetTouchPoints(currentPoint); - } - } - - if (!hasTouch) - { - _device.Hid.SetTouchPoints(); - } - - if (ConfigurationState.Instance.Hid.EnableKeyboard && hidKeyboard.HasValue) - { - _device.Hid.WriteKeyboard(hidKeyboard.Value); - } - - BaseController controller = _device.Hid.PrimaryController; - - controller.SendInput(currentButton, leftJoystick, rightJoystick); - - // Toggle vsync - if (currentHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync) && - !_prevHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync)) - { - _device.EnableDeviceVsync = !_device.EnableDeviceVsync; - } - - _prevHotkeyButtons = currentHotkeyButtons; - } - - private new void RenderFrame() - { - _device.PresentFrame(SwapBuffers); - - _device.Statistics.RecordSystemFrameTime(); - - double hostFps = _device.Statistics.GetSystemFrameRate(); - double gameFps = _device.Statistics.GetGameFrameRate(); - - string titleNameSection = string.IsNullOrWhiteSpace(_device.System.TitleName) ? string.Empty - : " | " + _device.System.TitleName; - - string titleIdSection = string.IsNullOrWhiteSpace(_device.System.TitleIdText) ? string.Empty - : " | " + _device.System.TitleIdText.ToUpper(); - - _newTitle = $"Ryujinx{titleNameSection}{titleIdSection} | Host FPS: {hostFps:0.0} | Game FPS: {gameFps:0.0} | " + - $"Game Vsync: {(_device.EnableDeviceVsync ? "On" : "Off")}"; - - _titleEvent = true; - - _device.System.SignalVsync(); - - _device.VsyncEvent.Set(); - } - - protected override void OnUnload(EventArgs e) - { - _renderThread.Join(); - - base.OnUnload(e); - } - - protected override void OnResize(EventArgs e) - { - _resizeEvent = true; - } - - protected override void OnKeyDown(KeyboardKeyEventArgs e) - { - bool toggleFullscreen = e.Key == Key.F11 || - (e.Modifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Enter); - - if (WindowState == WindowState.Fullscreen) - { - if (e.Key == Key.Escape || toggleFullscreen) - { - WindowState = WindowState.Normal; - } - } - else - { - if (e.Key == Key.Escape) - { - Exit(); - } - - if (toggleFullscreen) - { - WindowState = WindowState.Fullscreen; - } - } - - _keyboard = e.Keyboard; - } - - protected override void OnKeyUp(KeyboardKeyEventArgs e) - { - _keyboard = e.Keyboard; - } - - protected override void OnMouseDown(MouseButtonEventArgs e) - { - _mouse = e.Mouse; - } - - protected override void OnMouseUp(MouseButtonEventArgs e) - { - _mouse = e.Mouse; - } - - protected override void OnMouseMove(MouseMoveEventArgs e) - { - _mouse = e.Mouse; - } - } -} diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index fe8cf04c08..39596b20cf 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -29,7 +29,6 @@ namespace Ryujinx.Ui private static HLE.Switch _emulationContext; - // private static GlScreen _screen; private static GLRenderer _gLWigdet; private static AutoResetEvent _screenExitStatus = new AutoResetEvent(false); @@ -51,12 +50,12 @@ namespace Ryujinx.Ui [GUI] Window _mainWin; [GUI] MenuBar _menuBar; [GUI] Box _footerBox; - [GUI] CheckMenuItem _fullScreen; + [GUI] MenuItem _fullScreen; [GUI] MenuItem _stopEmulation; [GUI] CheckMenuItem _favToggle; [GUI] MenuItem _firmwareInstallFile; [GUI] MenuItem _firmwareInstallDirectory; - [GUI] MenuItem _openDebugger; + [GUI] MenuItem _openDebugger; [GUI] CheckMenuItem _iconToggle; [GUI] CheckMenuItem _appToggle; [GUI] CheckMenuItem _developerToggle; @@ -74,7 +73,7 @@ namespace Ryujinx.Ui [GUI] LevelBar _progressBar; [GUI] Box _viewBox; [GUI] Box _listStatusBox; - + #pragma warning restore CS0649 #pragma warning restore IDE0044 @@ -160,6 +159,8 @@ namespace Ryujinx.Ui UpdateGameTable(); Task.Run(RefreshFirmwareLabel); + + _fullScreen.Activated += FullScreen_Toggled; } #if USE_DEBUGGING @@ -411,7 +412,7 @@ namespace Ryujinx.Ui Application.Invoke(delegate { _viewBox.Remove(_gLWigdet); - _gLWigdet.Dispose(); + _gLWigdet.Exit(); if(_gLWigdet.Window != this.Window && _gLWigdet.Window != null) { @@ -445,7 +446,6 @@ namespace Ryujinx.Ui _stopEmulation.Sensitive = false; _firmwareInstallFile.Sensitive = true; _firmwareInstallDirectory.Sensitive = true; - }); _screenExitStatus.Set(); @@ -453,7 +453,7 @@ namespace Ryujinx.Ui public void ToggleExtraWidgets(bool show) { - Gtk.Application.Invoke(delegate + if (_gLWigdet != null) { if (show) { @@ -465,7 +465,11 @@ namespace Ryujinx.Ui _menuBar.Hide(); _footerBox.Hide(); } - }); + } + + bool fullScreenToggled = this.Window.State.HasFlag(Gdk.WindowState.Fullscreen); + + _fullScreen.Label = !fullScreenToggled ? "Exit Fullscreen" : "Enter Fullscreen"; } private static void UpdateGameMetadata(string titleId) @@ -864,16 +868,22 @@ namespace Ryujinx.Ui private void FullScreen_Toggled(object o, EventArgs args) { - if (_fullScreen.Active) + bool fullScreenToggled = this.Window.State.HasFlag(Gdk.WindowState.Fullscreen); + + if (!fullScreenToggled) { Fullscreen(); + _fullScreen.Label = "Exit Fullscreen"; + ToggleExtraWidgets(false); } else { Unfullscreen(); + _fullScreen.Label = "Enter Fullscreen"; + ToggleExtraWidgets(true); } } diff --git a/Ryujinx/Ui/MainWindow.glade b/Ryujinx/Ui/MainWindow.glade index ec05004192..8477f392a4 100644 --- a/Ryujinx/Ui/MainWindow.glade +++ b/Ryujinx/Ui/MainWindow.glade @@ -97,13 +97,11 @@ True False - + True False - Fullscreens the window - Fullscreen + Enter Fullscreen True - @@ -405,9 +403,6 @@ True False - - - True diff --git a/Ryujinx/Ui/ScopedGLContext.cs b/Ryujinx/Ui/ScopedGlContext.cs similarity index 86% rename from Ryujinx/Ui/ScopedGLContext.cs rename to Ryujinx/Ui/ScopedGlContext.cs index 49d33a0961..8dc9246ef0 100644 --- a/Ryujinx/Ui/ScopedGLContext.cs +++ b/Ryujinx/Ui/ScopedGlContext.cs @@ -5,13 +5,13 @@ using System.Threading; namespace Ryujinx.Ui { - class ScopedGLContext : IDisposable + class ScopedGlContext : IDisposable { private IGraphicsContext _graphicsContext; private static readonly object _lock = new object(); - public ScopedGLContext(IWindowInfo windowInfo, IGraphicsContext graphicsContext) + public ScopedGlContext(IWindowInfo windowInfo, IGraphicsContext graphicsContext) { _graphicsContext = graphicsContext;