Skip to content

Commit b313163

Browse files
authored
Merge pull request #3207 from Ghabry/fix-touch-input
Windows: Fix touch input, disable window rounding
2 parents 9c29b62 + 13d7e27 commit b313163

File tree

6 files changed

+69
-40
lines changed

6 files changed

+69
-40
lines changed

.github/workflows/stable-compilation.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ jobs:
4242
apt-get update
4343
apt-get install -yqq --no-install-recommends --no-install-suggests \
4444
ca-certificates build-essential cmake ninja-build git \
45-
libicu-dev libexpat1-dev libsdl2-dev libpng-dev libpixman-1-dev \
46-
libfmt-dev libfreetype6-dev libharfbuzz-dev libmpg123-dev \
47-
libsndfile-dev libvorbis-dev libopusfile-dev libspeexdsp-dev \
45+
libicu-dev libexpat1-dev libinih-dev \
46+
libsdl2-dev libpng-dev libpixman-1-dev libfmt-dev \
47+
libfreetype6-dev libharfbuzz-dev libmpg123-dev libsndfile-dev \
48+
libvorbis-dev libopusfile-dev libspeexdsp-dev \
4849
libdrm-dev libgbm-dev # only needed for sdl2 on debian 11
4950
5051
- name: Clone Repository

CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,10 @@ if(${PLAYER_TARGET_PLATFORM} STREQUAL "SDL2")
578578
target_sources(${PROJECT_NAME} PRIVATE
579579
src/platform/wiiu/input_buttons.cpp)
580580
endif()
581+
582+
if(WIN32)
583+
target_link_libraries(${PROJECT_NAME} "Dwmapi")
584+
endif()
581585
elseif(${PLAYER_TARGET_PLATFORM} STREQUAL "SDL1")
582586
target_sources(${PROJECT_NAME} PRIVATE
583587
src/platform/sdl/sdl_audio.cpp

src/input_source.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,13 @@ void Input::LogSource::UpdateSystem() {
334334
// input log does not record actions outside of logical frames.
335335
}
336336

337+
void Input::TouchInput::Down(int id, int x, int y) {
338+
this->id = id;
339+
this->position = { x, y };
340+
this->pressed = true;
341+
}
337342

343+
void Input::TouchInput::Up() {
344+
id = -1;
345+
pressed = false;
346+
}

src/input_source.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,13 @@ namespace Input {
5959
};
6060

6161
struct TouchInput {
62-
bool pressed = false;
63-
Point position;
62+
void Down(int id, int x, int y);
63+
void Up();
6464

65-
// Fields for use by InputSource. Do not modify in Ui!
65+
// Do not alter the fields from the Ui class, use Down and Up
66+
int id = -1;
67+
Point position;
68+
bool pressed = false;
6669
bool prev_frame_pressed = false;
6770
Game_Clock::time_point touch_begin;
6871
Game_Clock::time_point touch_end;

src/platform/sdl/main.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ static void LogCallback(LogLevel lvl, std::string const& msg, LogCallbackUserDat
6464
extern "C" int main(int argc, char* argv[]) {
6565
std::vector<std::string> args;
6666

67-
#if defined(_WIN32) && !defined(__WINRT__)
67+
#if defined(_WIN32)
6868
// Use widestring args
6969
int argc_w;
7070
LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w);

src/platform/sdl/sdl2_ui.cpp

+45-33
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#ifdef _WIN32
2626
# include <windows.h>
2727
# include <SDL_syswm.h>
28+
# include <dwmapi.h>
2829
#elif defined(__ANDROID__)
2930
# include <jni.h>
3031
# include <SDL_system.h>
@@ -118,6 +119,19 @@ static uint32_t SelectFormat(const SDL_RendererInfo& rinfo, bool print_all) {
118119
return current_fmt;
119120
}
120121

122+
#ifdef _WIN32
123+
HWND GetWindowHandle(SDL_Window* window) {
124+
SDL_SysWMinfo wminfo;
125+
SDL_VERSION(&wminfo.version)
126+
SDL_bool success = SDL_GetWindowWMInfo(window, &wminfo);
127+
128+
if (success < 0)
129+
Output::Error("Wrong SDL version");
130+
131+
return wminfo.info.win.window;
132+
}
133+
#endif
134+
121135
static int FilterUntilFocus(const SDL_Event* evnt);
122136

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

356370
auto window_sg = lcf::makeScopeGuard([&]() {
357-
SDL_DestroyWindow(sdl_window);
358-
sdl_window = nullptr;
371+
SDL_DestroyWindow(sdl_window);
372+
sdl_window = nullptr;
359373
});
360374

361375
SetAppIcon();
@@ -415,6 +429,13 @@ bool Sdl2Ui::RefreshDisplayMode() {
415429
return false;
416430
}
417431

432+
#ifdef _WIN32
433+
HWND window = GetWindowHandle(sdl_window);
434+
// Not using the enum names because this will fail to build when not using a recent Windows 11 SDK
435+
int window_rounding = 1; // DWMWCP_DONOTROUND
436+
DwmSetWindowAttribute(window, 33 /* DWMWA_WINDOW_CORNER_PREFERENCE */, &window_rounding, sizeof(window_rounding));
437+
#endif
438+
418439
renderer_sg.Dismiss();
419440
window_sg.Dismiss();
420441
} else {
@@ -647,15 +668,10 @@ void Sdl2Ui::SetTitle(const std::string &title) {
647668
}
648669

649670
bool Sdl2Ui::ShowCursor(bool flag) {
650-
#ifdef __WINRT__
651-
// Prevent cursor hide in WinRT because it is hidden everywhere while the app runs...
652-
return flag;
653-
#else
654671
bool temp_flag = cursor_visible;
655672
cursor_visible = flag;
656673
SDL_ShowCursor(flag ? SDL_ENABLE : SDL_DISABLE);
657674
return temp_flag;
658-
#endif
659675
}
660676

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

949967
#ifdef EMSCRIPTEN
950-
double display_ratio = emscripten_get_device_pixel_ratio();
951-
fi.position.x = (evnt.tfinger.x * display_ratio - viewport.x) * main_surface->width() / xw;
952-
fi.position.y = (evnt.tfinger.y * display_ratio - viewport.y) * main_surface->height() / yh;
968+
double display_ratio = emscripten_get_device_pixel_ratio();
969+
int x = (evnt.tfinger.x * display_ratio - viewport.x) * main_surface->width() / xw;
970+
int y = (evnt.tfinger.y * display_ratio - viewport.y) * main_surface->height() / yh;
953971
#else
954-
fi.position.x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
955-
fi.position.y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
972+
int x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
973+
int y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
956974
#endif
957975

958-
fi.pressed = true;
959-
}
976+
fi->Down(evnt.tfinger.fingerId, x, y);
960977
} else if (evnt.type == SDL_FINGERUP) {
961-
int finger = evnt.tfinger.fingerId;
962-
if (finger < static_cast<int>(finger_input.size())) {
963-
auto& fi = touch_input[finger];
964-
fi.pressed = false;
978+
auto fi = std::find_if(touch_input.begin(), touch_input.end(), [&](const auto& input) {
979+
return input.id == evnt.tfinger.fingerId;
980+
});
981+
if (fi == touch_input.end()) {
982+
// Finger is not tracked
983+
return;
965984
}
985+
fi->Up();
966986
}
967987
#else
968988
/* unused */
@@ -971,17 +991,9 @@ void Sdl2Ui::ProcessFingerEvent(SDL_Event& evnt) {
971991
}
972992

973993
void Sdl2Ui::SetAppIcon() {
974-
#if defined(__WINRT__) || defined(__MORPHOS__)
994+
#if defined(__MORPHOS__)
975995
// do nothing
976996
#elif defined(_WIN32)
977-
SDL_SysWMinfo wminfo;
978-
SDL_VERSION(&wminfo.version)
979-
SDL_bool success = SDL_GetWindowWMInfo(sdl_window, &wminfo);
980-
981-
if (success < 0)
982-
Output::Error("Wrong SDL version");
983-
984-
HWND window;
985997
HINSTANCE handle = GetModuleHandle(NULL);
986998
HICON icon = LoadIcon(handle, MAKEINTRESOURCE(23456));
987999
HICON icon_small = (HICON) LoadImage(handle, MAKEINTRESOURCE(23456), IMAGE_ICON,
@@ -990,7 +1002,7 @@ void Sdl2Ui::SetAppIcon() {
9901002
if (icon == NULL || icon_small == NULL)
9911003
Output::Warning("Could not load window icon.");
9921004

993-
window = wminfo.info.win.window;
1005+
HWND window = GetWindowHandle(sdl_window);
9941006
SetClassLongPtr(window, GCLP_HICON, (LONG_PTR) icon);
9951007
SetClassLongPtr(window, GCLP_HICONSM, (LONG_PTR) icon_small);
9961008
#else

0 commit comments

Comments
 (0)