SetCursorFocused Windows
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 6m28s

This commit is contained in:
2025-07-08 16:08:33 -04:00
parent bb776026ad
commit 87f862730b
4 changed files with 56 additions and 12 deletions

View File

@@ -86,7 +86,7 @@ protected:
float refresh_rate_prev_5 = 0.f;
float avg_refresh_rate = 0.0f;
/// Returns the most accurate and recent available mouse coordinates.
/// Returns the most accurate and recent available mouse coordinates relative to the top left corner of the renderable area (not including the title bar).
/// @note Call this version at most **once** per-frame. It polls the X-Window server and therefore is quite slow.
/// @see getCursorPos();
[[nodiscard]] std::pair<int, int> GetAccurateMouseCoordinates() const;
@@ -250,14 +250,14 @@ public:
void SetSize(const std::pair<int, int>& size);
/// Returns the position of the window's top-left corner relative to the display
std::pair<int, int> GetPos() const;
[[nodiscard]] std::pair<int, int> GetPos() const;
/// Returns the known size of the window, in {x,y} pixel measurement.
std::pair<int, int> GetSize() const;
[[nodiscard]] std::pair<int, int> GetSize() const;
/// Returns the position of the "renderable area" of the window relative to it's top left corner.
/// (used to account for the width or the border & title bar).
std::pair<int, int> GetPositionOfRenderableArea() const;
[[nodiscard]] std::pair<int, int> GetPositionOfRenderableArea() const;
/// Requests the operating system to move the window to the specified coordinates on the display.
/// @param x The horizontal screen position to place the window at.
@@ -286,15 +286,18 @@ public:
/// Tells the operating system to not allow the cursor to go off our window.
/// @note This is useful for 3D games.
// TODO recreate this behavior on Windows. On X-Windows, The cursor is focused on the next mouse movement because of an X11 timing issue.
void SetCursorFocused(bool state);
/// Hides the cursor when it's inside of our window.
/// Hides the cursor when it's inside our window.
/// @note This is useful for 3D games.
void SetCursorVisible(bool cursor_enable);
/// @returns Whether ther cursor is visible.
bool GetCursorVisible();
/// @returns Whether the cursor is focused (cannot go off of our window).
bool GetCursorFocused();
/// Returns the current time, represented as a high-resolution std::chrono alias.
static std::chrono::steady_clock::time_point GetTimestamp();
@@ -322,10 +325,11 @@ public:
public:
virtual void SwapBuffers() = 0;
/// Sets whether or not to enable vertical synchronization.
/// Sets whether vertical sync is enabled.
/// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given.
virtual void SetVsyncEnabled(bool state) = 0;
/// Sets whether or not we're using key repeat.
/// Sets whether we're using key repeat.
void SetKeyRepeatEnabled(bool state);
/// @returns If key repeat is enabled.

View File

@@ -71,8 +71,10 @@ int main() {
window->SetResizable(true);
//window->SetCursorVisible(true);
window->SetKeyRepeatEnabled(false);
//window->SetCursorCenter();
//window->DialogOK("MessageBox", "Generic message from a ReWindow MessageBox.");
window->SetCursorFocused(true);
//std::this_thread::sleep_for(std::chrono::milliseconds(500));
Logger::Debug(std::format("Window '{}' flags: IN_FOCUS={} FULLSCREEN={} RESIZEABLE={} VSYNC={} KEY_REPEAT={} QUIT={}",
window->GetTitle(), window->IsFocused(), window->IsFullscreen(),
@@ -83,8 +85,8 @@ int main() {
window->OnMouseButtonDownEvent += [&] (MouseButtonDownEvent e) { jlog::Debug(e.Button.Mnemonic + std::to_string(e.Button.ButtonIndex)); };
window->OnMouseWheelEvent += [&, window] (MouseWheelEvent e) { std::cout << window->GetMouseWheelPersistent() << std::endl; };
while (!window->IsClosing()) {
while (!window->IsClosing())
window->ManagedRefresh();
}
delete window;
}

View File

@@ -189,6 +189,10 @@ void RWindow::Refresh() {
}
}
bool RWindow::GetCursorFocused() {
return cursor_focused;
}
float RWindow::ComputeElapsedFrameTimeSeconds(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end) {
auto frame_time = end - start;
unsigned long int frame_time_us = std::chrono::duration_cast<std::chrono::microseconds>(frame_time).count();

View File

@@ -15,6 +15,20 @@ using namespace ReWindow;
// TODO get rid of this.
bool local_focused = true;
bool local_toggling_cursor_focused = false;
void RWindow::SetCursorFocused(bool state) {
local_toggling_cursor_focused = state;
if (state)
cursor_focused = true;
else if (!state && cursor_focused) {
ClipCursor(nullptr);
cursor_focused = false;
local_toggling_cursor_focused = false;
}
}
std::pair<int, int> RWindow::SetCursorCenter() {
auto current_cursor_pos = GetAccurateMouseCoordinates();
@@ -40,7 +54,6 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_CLOSE: {
window->processOnClose();
DestroyWindow(hwnd);
}
case WM_DESTROY: {
@@ -62,6 +75,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
window->processFocusIn();
local_focused = true;
if (window->GetCursorFocused())
local_toggling_cursor_focused = true;
// Cancels window flashing.
// TODO check if we're flashing before this.
static FLASHWINFO flash_inter {sizeof(FLASHWINFO), hwnd, FLASHW_STOP, 0, 0};
@@ -71,6 +87,11 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_KILLFOCUS: {
window->processFocusOut();
if (window->GetCursorFocused()) {
ClipCursor(nullptr);
local_toggling_cursor_focused = true;
}
local_focused = false;
}
@@ -159,8 +180,21 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
//This is the same as "Motion Notify" in the X Window System.
case WM_MOUSEMOVE: {
if (local_toggling_cursor_focused) {
RECT rect;
if (GetClientRect(hwnd, &rect)) {
POINT top_left = { rect.left, rect.top };
POINT bottom_right = { rect.right, rect.bottom };
MapWindowPoints(hwnd, nullptr, &top_left, 1);
MapWindowPoints(hwnd, nullptr, &bottom_right, 1);
}
RECT clip_rect = { top_left.x, top_left.y, bottom_right.x, bottom_right.y };
if (ClipCursor(&clip_rect))
local_toggling_cursor_focused = false;
}
}
}
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}