diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 5d2ec6970..e32e99111 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -141,6 +141,20 @@ bool EmulatorWindow::Initialize() { e->set_handled(handled); }); + window_->on_mouse_move.AddListener([this](MouseEvent* e) { + if (window_->is_fullscreen() && (e->dx() > 2 || e->dy() > 2)) { + if (!window_->is_cursor_visible()) { + window_->set_cursor_visible(true); + } + + cursor_hide_time_ = Clock::QueryHostSystemTime() + 30000000; + } + + e->set_handled(false); + }); + + window_->on_paint.AddListener([this](UIEvent* e) { CheckHideCursor(); }); + // Main menu. // FIXME: This code is really messy. auto main_menu = MenuItem::Create(MenuItem::Type::kNormal); @@ -277,6 +291,17 @@ void EmulatorWindow::FileOpen() { } } +void EmulatorWindow::CheckHideCursor() { + if (!window_->is_fullscreen()) { + // Only hide when fullscreen. + return; + } + + if (Clock::QueryHostSystemTime() > cursor_hide_time_) { + window_->set_cursor_visible(false); + } +} + void EmulatorWindow::CpuTimeScalarReset() { Clock::set_guest_time_scalar(1.0); UpdateTitle(); @@ -320,6 +345,12 @@ void EmulatorWindow::GpuClearCaches() { void EmulatorWindow::ToggleFullscreen() { window_->ToggleFullscreen(!window_->is_fullscreen()); + + // Hide the cursor after a second if we're going fullscreen + cursor_hide_time_ = Clock::QueryHostSystemTime() + 30000000; + if (!window_->is_fullscreen()) { + window_->set_cursor_visible(true); + } } void EmulatorWindow::ShowHelpWebsite() { LaunchBrowser("http://xenia.jp"); } diff --git a/src/xenia/app/emulator_window.h b/src/xenia/app/emulator_window.h index c493ef414..6a3b5e2e3 100644 --- a/src/xenia/app/emulator_window.h +++ b/src/xenia/app/emulator_window.h @@ -43,6 +43,7 @@ class EmulatorWindow { bool Initialize(); void FileOpen(); + void CheckHideCursor(); void CpuTimeScalarReset(); void CpuTimeScalarSetHalf(); void CpuTimeScalarSetDouble(); @@ -56,6 +57,7 @@ class EmulatorWindow { std::unique_ptr loop_; std::unique_ptr window_; std::wstring base_title_; + uint64_t cursor_hide_time_ = 0; }; } // namespace app diff --git a/src/xenia/ui/window_win.cc b/src/xenia/ui/window_win.cc index a02becc75..c81ac5e18 100644 --- a/src/xenia/ui/window_win.cc +++ b/src/xenia/ui/window_win.cc @@ -57,7 +57,7 @@ bool Win32Window::OnCreate() { wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, L"MAINICON"); wcex.hIconSm = LoadIcon(hInstance, L"MAINICON"); - wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); + wcex.hCursor = nullptr; wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = nullptr; wcex.lpszClassName = L"XeniaWindowClass"; @@ -105,6 +105,8 @@ bool Win32Window::OnCreate() { ShowWindow(hwnd_, SW_SHOWNORMAL); UpdateWindow(hwnd_); + arrow_cursor_ = LoadCursor(nullptr, IDC_ARROW); + // Initial state. if (!is_cursor_visible_) { ShowCursor(FALSE); @@ -254,9 +256,10 @@ void Win32Window::set_cursor_visible(bool value) { if (is_cursor_visible_ == value) { return; } + is_cursor_visible_ = value; + if (value) { ShowCursor(TRUE); - SetCursor(nullptr); } else { ShowCursor(FALSE); } @@ -483,8 +486,8 @@ bool Win32Window::HandleMouse(UINT message, WPARAM wParam, LPARAM lParam) { } MouseEvent::Button button = MouseEvent::Button::kNone; - int32_t dx = 0; - int32_t dy = 0; + int32_t dx = x - last_mouse_pos_.x; + int32_t dy = y - last_mouse_pos_.y; switch (message) { case WM_LBUTTONDOWN: case WM_LBUTTONUP: @@ -524,6 +527,8 @@ bool Win32Window::HandleMouse(UINT message, WPARAM wParam, LPARAM lParam) { return true; } + last_mouse_pos_ = {x, y}; + auto e = MouseEvent(this, button, x, y, dx, dy); switch (message) { case WM_LBUTTONDOWN: diff --git a/src/xenia/ui/window_win.h b/src/xenia/ui/window_win.h index 3240650c6..eae68b2ce 100644 --- a/src/xenia/ui/window_win.h +++ b/src/xenia/ui/window_win.h @@ -73,8 +73,10 @@ class Win32Window : public Window { HICON icon_ = nullptr; bool closing_ = false; bool fullscreen_ = false; + HCURSOR arrow_cursor_ = nullptr; WINDOWPLACEMENT windowed_pos_ = {0}; + POINT last_mouse_pos_ = {0}; }; class Win32MenuItem : public MenuItem {