mirror of https://github.com/encounter/SDL.git
Implemented mouse relative mode for iOS 14.1 and newer
This commit is contained in:
parent
3433f3c4cc
commit
46f19c311d
|
@ -31,6 +31,7 @@ extern void SDL_QuitGCKeyboard(void);
|
||||||
|
|
||||||
extern void SDL_InitGCMouse(void);
|
extern void SDL_InitGCMouse(void);
|
||||||
extern SDL_bool SDL_HasGCMouse(void);
|
extern SDL_bool SDL_HasGCMouse(void);
|
||||||
|
extern SDL_bool SDL_GCMouseRelativeMode(void);
|
||||||
extern void SDL_QuitGCMouse(void);
|
extern void SDL_QuitGCMouse(void);
|
||||||
|
|
||||||
#endif /* SDL_uikitevents_h_ */
|
#endif /* SDL_uikitevents_h_ */
|
||||||
|
|
|
@ -91,9 +91,9 @@ static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0
|
||||||
SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
|
SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL );
|
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL );
|
||||||
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
|
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
|
||||||
keyboard.handlerQueue = queue;
|
keyboard.handlerQueue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
||||||
|
@ -182,10 +182,22 @@ void SDL_QuitGCKeyboard(void)
|
||||||
static int mice_connected = 0;
|
static int mice_connected = 0;
|
||||||
static id mouse_connect_observer = nil;
|
static id mouse_connect_observer = nil;
|
||||||
static id mouse_disconnect_observer = nil;
|
static id mouse_disconnect_observer = nil;
|
||||||
|
static bool mouse_relative_mode = SDL_FALSE;
|
||||||
|
|
||||||
|
static void UpdateMouseGrab()
|
||||||
|
{
|
||||||
|
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||||
|
SDL_Window *window;
|
||||||
|
|
||||||
|
for (window = _this->windows; window != NULL; window = window->next) {
|
||||||
|
SDL_UpdateWindowGrab(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int SetGCMouseRelativeMode(SDL_bool enabled)
|
static int SetGCMouseRelativeMode(SDL_bool enabled)
|
||||||
{
|
{
|
||||||
/* We'll always send relative motion and we can't warp, so nothing to do here */
|
mouse_relative_mode = enabled;
|
||||||
|
UpdateMouseGrab();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,14 +234,16 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
|
||||||
|
|
||||||
mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouse, float deltaX, float deltaY)
|
mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouse, float deltaX, float deltaY)
|
||||||
{
|
{
|
||||||
SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY);
|
SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY);
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL );
|
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL );
|
||||||
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
|
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
|
||||||
mouse.handlerQueue = queue;
|
mouse.handlerQueue = queue;
|
||||||
|
|
||||||
++mice_connected;
|
++mice_connected;
|
||||||
|
|
||||||
|
UpdateMouseGrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
||||||
|
@ -245,12 +259,14 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios
|
||||||
for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) {
|
for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) {
|
||||||
button.pressedChangedHandler = nil;
|
button.pressedChangedHandler = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateMouseGrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_InitGCMouse(void)
|
void SDL_InitGCMouse(void)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
/* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */
|
/* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */
|
||||||
if (@available(iOS 14.1, tvOS 14.1, *)) {
|
if (@available(iOS 14.1, tvOS 14.1, *)) {
|
||||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||||
|
|
||||||
|
@ -284,6 +300,11 @@ SDL_bool SDL_HasGCMouse(void)
|
||||||
return (mice_connected > 0);
|
return (mice_connected > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_GCMouseRelativeMode(void)
|
||||||
|
{
|
||||||
|
return mouse_relative_mode;
|
||||||
|
}
|
||||||
|
|
||||||
void SDL_QuitGCMouse(void)
|
void SDL_QuitGCMouse(void)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
@ -320,6 +341,11 @@ SDL_bool SDL_HasGCMouse(void)
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_GCMouseRelativeMode(void)
|
||||||
|
{
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void SDL_QuitGCMouse(void)
|
void SDL_QuitGCMouse(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ UIKit_CreateDevice(int devindex)
|
||||||
device->RaiseWindow = UIKit_RaiseWindow;
|
device->RaiseWindow = UIKit_RaiseWindow;
|
||||||
device->SetWindowBordered = UIKit_SetWindowBordered;
|
device->SetWindowBordered = UIKit_SetWindowBordered;
|
||||||
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
||||||
|
device->SetWindowMouseGrab = UIKit_SetWindowMouseGrab;
|
||||||
device->DestroyWindow = UIKit_DestroyWindow;
|
device->DestroyWindow = UIKit_DestroyWindow;
|
||||||
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
||||||
device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
|
device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
|
||||||
|
@ -159,8 +160,8 @@ UIKit_VideoInit(_THIS)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_InitGCKeyboard();
|
SDL_InitGCKeyboard();
|
||||||
SDL_InitGCMouse();
|
SDL_InitGCMouse();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -168,8 +169,8 @@ UIKit_VideoInit(_THIS)
|
||||||
void
|
void
|
||||||
UIKit_VideoQuit(_THIS)
|
UIKit_VideoQuit(_THIS)
|
||||||
{
|
{
|
||||||
SDL_QuitGCKeyboard();
|
SDL_QuitGCKeyboard();
|
||||||
SDL_QuitGCMouse();
|
SDL_QuitGCMouse();
|
||||||
|
|
||||||
UIKit_QuitModes(_this);
|
UIKit_QuitModes(_this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,9 @@
|
||||||
#include "../SDL_sysvideo.h"
|
#include "../SDL_sysvideo.h"
|
||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
|
|
||||||
#import "SDL_uikitviewcontroller.h"
|
#include "SDL_uikitviewcontroller.h"
|
||||||
#import "SDL_uikitmessagebox.h"
|
#include "SDL_uikitmessagebox.h"
|
||||||
|
#include "SDL_uikitevents.h"
|
||||||
#include "SDL_uikitvideo.h"
|
#include "SDL_uikitvideo.h"
|
||||||
#include "SDL_uikitmodes.h"
|
#include "SDL_uikitmodes.h"
|
||||||
#include "SDL_uikitwindow.h"
|
#include "SDL_uikitwindow.h"
|
||||||
|
@ -246,7 +247,20 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
|
||||||
return UIRectEdgeNone;
|
return UIRectEdgeNone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
- (BOOL)prefersPointerLocked
|
||||||
|
{
|
||||||
|
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||||
|
|
||||||
|
if (SDL_HasGCMouse() &&
|
||||||
|
(SDL_GCMouseRelativeMode() || _this->grabbed_window == window)) {
|
||||||
|
return YES;
|
||||||
|
} else {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !TARGET_OS_TV */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---- Keyboard related functionality below this line ----
|
---- Keyboard related functionality below this line ----
|
||||||
|
|
|
@ -33,6 +33,7 @@ extern void UIKit_HideWindow(_THIS, SDL_Window * window);
|
||||||
extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
|
extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
|
||||||
extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
|
extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
|
||||||
extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||||
|
extern void UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||||
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
|
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
|
||||||
extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
|
extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
|
||||||
struct SDL_SysWMinfo * info);
|
struct SDL_SysWMinfo * info);
|
||||||
|
|
|
@ -161,14 +161,14 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||||
SDL_Window *other;
|
SDL_Window *other;
|
||||||
|
|
||||||
/* We currently only handle a single window per display on iOS */
|
/* We currently only handle a single window per display on iOS */
|
||||||
for (other = _this->windows; other; other = other->next) {
|
for (other = _this->windows; other; other = other->next) {
|
||||||
if (other != window && SDL_GetDisplayForWindow(other) == display) {
|
if (other != window && SDL_GetDisplayForWindow(other) == display) {
|
||||||
return SDL_SetError("Only one window allowed per display.");
|
return SDL_SetError("Only one window allowed per display.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
|
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
|
||||||
* user, so it's in standby), try to force the display to a resolution
|
* user, so it's in standby), try to force the display to a resolution
|
||||||
|
@ -320,6 +320,20 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||||
|
{
|
||||||
|
#if !TARGET_OS_TV
|
||||||
|
@autoreleasepool {
|
||||||
|
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||||
|
SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
|
||||||
|
if (@available(iOS 14.0, *)) {
|
||||||
|
[viewcontroller setNeedsUpdateOfPrefersPointerLocked];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !TARGET_OS_TV */
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UIKit_DestroyWindow(_THIS, SDL_Window * window)
|
UIKit_DestroyWindow(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue