Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: Fix touch input, disable window rounding #3207

Merged
merged 4 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/stable-compilation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ jobs:
apt-get update
apt-get install -yqq --no-install-recommends --no-install-suggests \
ca-certificates build-essential cmake ninja-build git \
libicu-dev libexpat1-dev libsdl2-dev libpng-dev libpixman-1-dev \
libfmt-dev libfreetype6-dev libharfbuzz-dev libmpg123-dev \
libsndfile-dev libvorbis-dev libopusfile-dev libspeexdsp-dev \
libicu-dev libexpat1-dev libinih-dev \
libsdl2-dev libpng-dev libpixman-1-dev libfmt-dev \
libfreetype6-dev libharfbuzz-dev libmpg123-dev libsndfile-dev \
libvorbis-dev libopusfile-dev libspeexdsp-dev \
libdrm-dev libgbm-dev # only needed for sdl2 on debian 11
- name: Clone Repository
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,10 @@ if(${PLAYER_TARGET_PLATFORM} STREQUAL "SDL2")
target_sources(${PROJECT_NAME} PRIVATE
src/platform/wiiu/input_buttons.cpp)
endif()

if(WIN32)
target_link_libraries(${PROJECT_NAME} "Dwmapi")
endif()
elseif(${PLAYER_TARGET_PLATFORM} STREQUAL "SDL1")
target_sources(${PROJECT_NAME} PRIVATE
src/platform/sdl/sdl_audio.cpp
Expand Down
9 changes: 9 additions & 0 deletions src/input_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,13 @@ void Input::LogSource::UpdateSystem() {
// input log does not record actions outside of logical frames.
}

void Input::TouchInput::Down(int id, int x, int y) {
this->id = id;
this->position = { x, y };
this->pressed = true;
}

void Input::TouchInput::Up() {
id = -1;
pressed = false;
}
9 changes: 6 additions & 3 deletions src/input_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,13 @@ namespace Input {
};

struct TouchInput {
bool pressed = false;
Point position;
void Down(int id, int x, int y);
void Up();

// Fields for use by InputSource. Do not modify in Ui!
// Do not alter the fields from the Ui class, use Down and Up
int id = -1;
Point position;
bool pressed = false;
bool prev_frame_pressed = false;
Game_Clock::time_point touch_begin;
Game_Clock::time_point touch_end;
Expand Down
2 changes: 1 addition & 1 deletion src/platform/sdl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static void LogCallback(LogLevel lvl, std::string const& msg, LogCallbackUserDat
extern "C" int main(int argc, char* argv[]) {
std::vector<std::string> args;

#if defined(_WIN32) && !defined(__WINRT__)
#if defined(_WIN32)
// Use widestring args
int argc_w;
LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w);
Expand Down
78 changes: 45 additions & 33 deletions src/platform/sdl/sdl2_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifdef _WIN32
# include <windows.h>
# include <SDL_syswm.h>
# include <dwmapi.h>
#elif defined(__ANDROID__)
# include <jni.h>
# include <SDL_system.h>
Expand Down Expand Up @@ -118,6 +119,19 @@ static uint32_t SelectFormat(const SDL_RendererInfo& rinfo, bool print_all) {
return current_fmt;
}

#ifdef _WIN32
HWND GetWindowHandle(SDL_Window* window) {
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version)
SDL_bool success = SDL_GetWindowWMInfo(window, &wminfo);

if (success < 0)
Output::Error("Wrong SDL version");

return wminfo.info.win.window;
}
#endif

static int FilterUntilFocus(const SDL_Event* evnt);

#if defined(USE_KEYBOARD) && defined(SUPPORT_KEYBOARD)
Expand Down Expand Up @@ -354,8 +368,8 @@ bool Sdl2Ui::RefreshDisplayMode() {
window.size_changed = true;

auto window_sg = lcf::makeScopeGuard([&]() {
SDL_DestroyWindow(sdl_window);
sdl_window = nullptr;
SDL_DestroyWindow(sdl_window);
sdl_window = nullptr;
});

SetAppIcon();
Expand Down Expand Up @@ -415,6 +429,13 @@ bool Sdl2Ui::RefreshDisplayMode() {
return false;
}

#ifdef _WIN32
HWND window = GetWindowHandle(sdl_window);
// Not using the enum names because this will fail to build when not using a recent Windows 11 SDK
int window_rounding = 1; // DWMWCP_DONOTROUND
DwmSetWindowAttribute(window, 33 /* DWMWA_WINDOW_CORNER_PREFERENCE */, &window_rounding, sizeof(window_rounding));
#endif

renderer_sg.Dismiss();
window_sg.Dismiss();
} else {
Expand Down Expand Up @@ -647,15 +668,10 @@ void Sdl2Ui::SetTitle(const std::string &title) {
}

bool Sdl2Ui::ShowCursor(bool flag) {
#ifdef __WINRT__
// Prevent cursor hide in WinRT because it is hidden everywhere while the app runs...
return flag;
#else
bool temp_flag = cursor_visible;
cursor_visible = flag;
SDL_ShowCursor(flag ? SDL_ENABLE : SDL_DISABLE);
return temp_flag;
#endif
}

void Sdl2Ui::ProcessEvent(SDL_Event &evnt) {
Expand Down Expand Up @@ -940,29 +956,33 @@ void Sdl2Ui::ProcessFingerEvent(SDL_Event& evnt) {
// We currently ignore swipe gestures
// A finger touch is detected when the fingers go up a brief delay after going down
if (evnt.type == SDL_FINGERDOWN) {
int finger = evnt.tfinger.fingerId;
if (finger < static_cast<int>(finger_input.size())) {
auto& fi = touch_input[finger];
fi.position.x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
fi.position.y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
auto fi = std::find_if(touch_input.begin(), touch_input.end(), [&](const auto& input) {
return input.id == -1;
});
if (fi == touch_input.end()) {
// already tracking 5 fingers
return;
}

#ifdef EMSCRIPTEN
double display_ratio = emscripten_get_device_pixel_ratio();
fi.position.x = (evnt.tfinger.x * display_ratio - viewport.x) * main_surface->width() / xw;
fi.position.y = (evnt.tfinger.y * display_ratio - viewport.y) * main_surface->height() / yh;
double display_ratio = emscripten_get_device_pixel_ratio();
int x = (evnt.tfinger.x * display_ratio - viewport.x) * main_surface->width() / xw;
int y = (evnt.tfinger.y * display_ratio - viewport.y) * main_surface->height() / yh;
#else
fi.position.x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
fi.position.y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
int x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
int y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
#endif

fi.pressed = true;
}
fi->Down(evnt.tfinger.fingerId, x, y);
} else if (evnt.type == SDL_FINGERUP) {
int finger = evnt.tfinger.fingerId;
if (finger < static_cast<int>(finger_input.size())) {
auto& fi = touch_input[finger];
fi.pressed = false;
auto fi = std::find_if(touch_input.begin(), touch_input.end(), [&](const auto& input) {
return input.id == evnt.tfinger.fingerId;
});
if (fi == touch_input.end()) {
// Finger is not tracked
return;
}
fi->Up();
}
#else
/* unused */
Expand All @@ -971,17 +991,9 @@ void Sdl2Ui::ProcessFingerEvent(SDL_Event& evnt) {
}

void Sdl2Ui::SetAppIcon() {
#if defined(__WINRT__) || defined(__MORPHOS__)
#if defined(__MORPHOS__)
// do nothing
#elif defined(_WIN32)
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version)
SDL_bool success = SDL_GetWindowWMInfo(sdl_window, &wminfo);

if (success < 0)
Output::Error("Wrong SDL version");

HWND window;
HINSTANCE handle = GetModuleHandle(NULL);
HICON icon = LoadIcon(handle, MAKEINTRESOURCE(23456));
HICON icon_small = (HICON) LoadImage(handle, MAKEINTRESOURCE(23456), IMAGE_ICON,
Expand All @@ -990,7 +1002,7 @@ void Sdl2Ui::SetAppIcon() {
if (icon == NULL || icon_small == NULL)
Output::Warning("Could not load window icon.");

window = wminfo.info.win.window;
HWND window = GetWindowHandle(sdl_window);
SetClassLongPtr(window, GCLP_HICON, (LONG_PTR) icon);
SetClassLongPtr(window, GCLP_HICONSM, (LONG_PTR) icon_small);
#else
Expand Down