Fixed following mouse cursor when keyboard is shown

This commit is contained in:
Sergii Pylypenko
2014-12-26 23:24:22 +02:00
parent 934f3981a9
commit 50a6d7e253
7 changed files with 128 additions and 78 deletions

View File

@@ -353,23 +353,21 @@ public class MainActivity extends Activity
DimSystemStatusBar.get().dim(_videoLayout); DimSystemStatusBar.get().dim(_videoLayout);
DimSystemStatusBar.get().dim(mGLView); DimSystemStatusBar.get().dim(mGLView);
if( Globals.ScreenFollowsMouse ) Rect r = new Rect();
_videoLayout.getWindowVisibleDisplayFrame(r);
mGLView.nativeScreenVisibleRect(r.left, r.top, r.right, r.bottom);
_videoLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{ {
Rect r = new Rect(); public void onGlobalLayout()
_videoLayout.getWindowVisibleDisplayFrame(r);
mGLView.nativeScreenVisibleRect(r.left, r.top, r.right, r.bottom);
_videoLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{ {
public void onGlobalLayout() Rect r = new Rect();
{ _videoLayout.getWindowVisibleDisplayFrame(r);
Rect r = new Rect(); int heightDiff = _videoLayout.getRootView().getHeight() - _videoLayout.getHeight(); // Take system bar into consideration
_videoLayout.getWindowVisibleDisplayFrame(r); int widthDiff = _videoLayout.getRootView().getWidth() - _videoLayout.getWidth(); // Nexus 5 has system bar at the right side
int heightDiff = _videoLayout.getRootView().getHeight() - _videoLayout.getHeight(); // Take system bar into consideration mGLView.nativeScreenVisibleRect(r.left + widthDiff, r.top + heightDiff, r.width(), r.height());
mGLView.nativeScreenVisibleRect(r.left, r.top + heightDiff, r.width(), r.height()); Log.v("SDL", "Main window visible region changed: " + r.left + ":" + r.top + ":" + r.width() + ":" + r.height() );
Log.v("SDL", "Main window visible region changed: " + r.left + ":" + r.top + ":" + r.width() + ":" + r.height() ); }
} });
});
}
} }
@Override @Override

View File

@@ -527,7 +527,8 @@ class Settings
Globals.RightMouseButtonLongPress ? 1 : 0, Globals.RightMouseButtonLongPress ? 1 : 0,
Globals.MoveMouseWithGyroscope ? 1 : 0, Globals.MoveMouseWithGyroscope ? 1 : 0,
Globals.MoveMouseWithGyroscopeSpeed, Globals.MoveMouseWithGyroscopeSpeed,
Globals.CompatibilityHacksForceScreenUpdateMouseClick ? 1 : 0 ); Globals.CompatibilityHacksForceScreenUpdateMouseClick ? 1 : 0,
Globals.ScreenFollowsMouse ? 1 : 0 );
} }
static void Apply(MainActivity p) static void Apply(MainActivity p)
@@ -863,7 +864,7 @@ class Settings
int relativeMovementAccel, int showMouseCursor, int relativeMovementAccel, int showMouseCursor,
int HoverJitterFilter, int RightMouseButtonLongPress, int HoverJitterFilter, int RightMouseButtonLongPress,
int MoveMouseWithGyroscope, int MoveMouseWithGyroscopeSpeed, int MoveMouseWithGyroscope, int MoveMouseWithGyroscopeSpeed,
int ForceScreenUpdateMouseClick); int ForceScreenUpdateMouseClick, int ScreenFollowsMouse);
private static native void nativeSetJoystickUsed(int amount); private static native void nativeSetJoystickUsed(int amount);
private static native void nativeSetAccelerometerUsed(); private static native void nativeSetAccelerometerUsed();
private static native void nativeSetMultitouchUsed(); private static native void nativeSetMultitouchUsed();

View File

@@ -35,6 +35,7 @@ If you compile this code with SDL 1.3 or newer, or use in some other way, the li
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include "SDL.h"
#include "SDL_config.h" #include "SDL_config.h"
#include "SDL_version.h" #include "SDL_version.h"
@@ -130,6 +131,8 @@ static unsigned int relativeMovementTime = 0;
int SDL_ANDROID_currentMouseX = 0; int SDL_ANDROID_currentMouseX = 0;
int SDL_ANDROID_currentMouseY = 0; int SDL_ANDROID_currentMouseY = 0;
int SDL_ANDROID_currentMouseButtons = 0; int SDL_ANDROID_currentMouseButtons = 0;
int screenFollowsMouse = 0;
int SDL_ANDROID_SystemBarAndKeyboardShown;
static int hardwareMouseDetected = 0; static int hardwareMouseDetected = 0;
enum { MOUSE_HW_BUTTON_LEFT = 1, MOUSE_HW_BUTTON_RIGHT = 2, MOUSE_HW_BUTTON_MIDDLE = 4, MOUSE_HW_BUTTON_BACK = 8, MOUSE_HW_BUTTON_FORWARD = 16, MOUSE_HW_BUTTON_MAX = MOUSE_HW_BUTTON_FORWARD }; enum { MOUSE_HW_BUTTON_LEFT = 1, MOUSE_HW_BUTTON_RIGHT = 2, MOUSE_HW_BUTTON_MIDDLE = 4, MOUSE_HW_BUTTON_BACK = 8, MOUSE_HW_BUTTON_FORWARD = 16, MOUSE_HW_BUTTON_MAX = MOUSE_HW_BUTTON_FORWARD };
@@ -1094,7 +1097,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel, jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel,
jint ShowMouseCursor, jint HoverJitterFilter, jint RightMouseButtonLongPress, jint ShowMouseCursor, jint HoverJitterFilter, jint RightMouseButtonLongPress,
jint MoveMouseWithGyroscope, jint MoveMouseWithGyroscopeSpeed, jint MoveMouseWithGyroscope, jint MoveMouseWithGyroscopeSpeed,
jint ForceScreenUpdateMouseClick) jint ForceScreenUpdateMouseClick, jint ScreenFollowsMouse)
{ {
SDL_ANDROID_isMouseUsed = 1; SDL_ANDROID_isMouseUsed = 1;
rightClickMethod = RightClickMethod; rightClickMethod = RightClickMethod;
@@ -1120,6 +1123,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
moveMouseWithGyroscopeSpeed = 0.0625f * MoveMouseWithGyroscopeSpeed * MoveMouseWithGyroscopeSpeed + 0.125f * MoveMouseWithGyroscopeSpeed + 0.5f; // Scale value from 0.5 to 2, with 1 at the middle moveMouseWithGyroscopeSpeed = 0.0625f * MoveMouseWithGyroscopeSpeed * MoveMouseWithGyroscopeSpeed + 0.125f * MoveMouseWithGyroscopeSpeed + 0.5f; // Scale value from 0.5 to 2, with 1 at the middle
moveMouseWithGyroscopeSpeed *= 5.0f; moveMouseWithGyroscopeSpeed *= 5.0f;
forceScreenUpdateMouseClick = ForceScreenUpdateMouseClick; forceScreenUpdateMouseClick = ForceScreenUpdateMouseClick;
screenFollowsMouse = ScreenFollowsMouse;
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "moveMouseWithGyroscopeSpeed %d = %f", MoveMouseWithGyroscopeSpeed, moveMouseWithGyroscopeSpeed); //__android_log_print(ANDROID_LOG_INFO, "libSDL", "moveMouseWithGyroscopeSpeed %d = %f", MoveMouseWithGyroscopeSpeed, moveMouseWithGyroscopeSpeed);
if( !mouseClickTimeoutInitialized && ( if( !mouseClickTimeoutInitialized && (
leftClickMethod == LEFT_CLICK_WITH_TAP || leftClickMethod == LEFT_CLICK_WITH_TAP ||
@@ -1137,49 +1141,78 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
} }
} }
JNIEXPORT void JNICALL typedef struct
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected)
{ {
if( !SDL_ANDROID_isMouseUsed )
return;
static struct {
int leftClickMethod; int leftClickMethod;
int ShowScreenUnderFinger; int ShowScreenUnderFinger;
int leftClickTimeout; int leftClickTimeout;
int relativeMovement; int relativeMovement;
int ShowMouseCursor; int ShowMouseCursor;
} cfg = { 0 }; } MouseSettings_t;
if( hardwareMouseDetected != detected ) static void saveMouseSettings(MouseSettings_t *cfg)
{
cfg->leftClickMethod = leftClickMethod;
cfg->ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger;
cfg->leftClickTimeout = leftClickTimeout;
cfg->relativeMovement = relativeMovement;
cfg->ShowMouseCursor = SDL_ANDROID_ShowMouseCursor;
}
static void restoreMouseSettings(MouseSettings_t *cfg)
{
leftClickMethod = cfg->leftClickMethod;
SDL_ANDROID_ShowScreenUnderFinger = cfg->ShowScreenUnderFinger;
leftClickTimeout = cfg->leftClickTimeout;
relativeMovement = cfg->relativeMovement;
SDL_ANDROID_ShowMouseCursor = cfg->ShowMouseCursor;
}
static void processHardwareMouseDetected (int detected, int ScreenSizeCallback)
{
static MouseSettings_t cfg;
static int initialized = 0;
if( !SDL_ANDROID_isMouseUsed )
return;
if( !initialized )
{ {
hardwareMouseDetected = detected; initialized = 1;
if(detected) saveMouseSettings(&cfg);
}
if( hardwareMouseDetected != detected || ScreenSizeCallback )
{
if( !ScreenSizeCallback )
{ {
cfg.leftClickMethod = leftClickMethod; hardwareMouseDetected = detected;
cfg.ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger; if( SDL_ANDROID_SystemBarAndKeyboardShown )
cfg.leftClickTimeout = leftClickTimeout; return; // Do not enable hardware mouse mode when the keyboard is shown
cfg.relativeMovement = relativeMovement; }
cfg.ShowMouseCursor = SDL_ANDROID_ShowMouseCursor;
if( detected )
{
saveMouseSettings(&cfg);
leftClickMethod = LEFT_CLICK_NORMAL; leftClickMethod = LEFT_CLICK_NORMAL;
SDL_ANDROID_ShowScreenUnderFinger = 0; SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE;
leftClickTimeout = 0; leftClickTimeout = 0;
relativeMovement = 0; relativeMovement = 0;
SDL_ANDROID_ShowMouseCursor = 0; SDL_ANDROID_ShowMouseCursor = 0;
} }
else else
{ restoreMouseSettings(&cfg);
leftClickMethod = cfg.leftClickMethod;
SDL_ANDROID_ShowScreenUnderFinger = cfg.ShowScreenUnderFinger;
leftClickTimeout = cfg.leftClickTimeout;
relativeMovement = cfg.relativeMovement;
SDL_ANDROID_ShowMouseCursor = cfg.ShowMouseCursor;
}
} }
SDL_ANDROID_SetHoverDeadzone(); SDL_ANDROID_SetHoverDeadzone();
} }
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected)
{
processHardwareMouseDetected(detected, 0);
}
void SDL_ANDROID_SetHoverDeadzone() void SDL_ANDROID_SetHoverDeadzone()
{ {
hoverDeadzone = (hardwareMouseDetected == MOUSE_HW_INPUT_STYLUS) ? hoverDeadzone = (hardwareMouseDetected == MOUSE_HW_INPUT_STYLUS) ?
@@ -1551,7 +1584,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenCalibration) (JNIEnv* env, jobject
SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1; SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1;
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz ) JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz )
{ {
SDL_android_init_keymap(SDL_android_keymap); SDL_android_init_keymap(SDL_android_keymap);
@@ -1607,3 +1640,48 @@ void *mouseClickTimeoutThread (void * unused)
} }
return NULL; return NULL;
} }
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeScreenVisibleRect) (JNIEnv* env, jobject thiz, jint x, jint y, jint w, jint h )
{
SDL_ANDROID_ScreenVisibleRect.x = x;
SDL_ANDROID_ScreenVisibleRect.y = y;
SDL_ANDROID_ScreenVisibleRect.w = w;
SDL_ANDROID_ScreenVisibleRect.h = h;
if( SDL_WasInit(SDL_INIT_VIDEO) )
{
// Move mouse by 1 pixel to force screen update
SDL_GetMouseState( &x, &y );
SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y);
}
else
return;
if( screenFollowsMouse )
{
static MouseSettings_t cfg;
//int systemBarActive = SDL_ANDROID_ScreenVisibleRect.h < SDL_ANDROID_sRealWindowHeight;
int keyboardActive = SDL_ANDROID_ScreenVisibleRect.h < SDL_ANDROID_sRealWindowHeight * 9 / 10;
if( keyboardActive && !SDL_ANDROID_SystemBarAndKeyboardShown )
{
SDL_ANDROID_SystemBarAndKeyboardShown = 1;
processHardwareMouseDetected(0, 1); // Disable direct mouse input mode, set relative mouse mode
saveMouseSettings(&cfg);
leftClickMethod = LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE;
leftClickTimeout = getClickTimeout(3);
relativeMovement = 1;
}
else if( !keyboardActive && SDL_ANDROID_SystemBarAndKeyboardShown )
{
SDL_ANDROID_SystemBarAndKeyboardShown = 0;
restoreMouseSettings(&cfg);
if( hardwareMouseDetected ) // Restore direct mouse input mode if needed
processHardwareMouseDetected(1, 1);
}
}
}

View File

@@ -269,5 +269,6 @@ extern int SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY;
extern int SDL_ANDROID_moveMouseWithKbSpeedX, SDL_ANDROID_moveMouseWithKbSpeedY; extern int SDL_ANDROID_moveMouseWithKbSpeedX, SDL_ANDROID_moveMouseWithKbSpeedY;
extern int SDL_ANDROID_moveMouseWithKbAccelX, SDL_ANDROID_moveMouseWithKbAccelY; extern int SDL_ANDROID_moveMouseWithKbAccelX, SDL_ANDROID_moveMouseWithKbAccelY;
extern int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded; extern int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded;
extern int SDL_ANDROID_SystemBarAndKeyboardShown;
#endif #endif

View File

@@ -978,7 +978,7 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects)
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_FlipHWSurface()"); //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_FlipHWSurface()");
if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels && ! ( SDL_CurrentVideoSurface->flags & SDL_HWSURFACE ) ) if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels && ! ( SDL_CurrentVideoSurface->flags & SDL_HWSURFACE ) )
{ {
SDL_Rect rect, dstrect; SDL_Rect rect;
rect.x = 0; rect.x = 0;
rect.y = 0; rect.y = 0;
rect.w = SDL_CurrentVideoSurface->w; rect.w = SDL_CurrentVideoSurface->w;
@@ -998,12 +998,13 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects)
} }
} }
if( SDL_ANDROID_ScreenVisibleRect.h <= 0 ) if( !SDL_ANDROID_SystemBarAndKeyboardShown )
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &rect);
else else
{ {
int x, y; int x, y;
SDL_GetMouseState(&x, &y); SDL_Rect dstrect;
SDL_GetMouseState(&x, &y); // Follow mouse pointer location
rect.w = SDL_ANDROID_ScreenVisibleRect.w * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_sRealWindowWidth; rect.w = SDL_ANDROID_ScreenVisibleRect.w * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_sRealWindowWidth;
rect.h = SDL_ANDROID_ScreenVisibleRect.h * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_sRealWindowHeight; rect.h = SDL_ANDROID_ScreenVisibleRect.h * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_sRealWindowHeight;
rect.x = x - rect.w / 2; rect.x = x - rect.w / 2;
@@ -1024,21 +1025,12 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects)
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect);
} }
if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER && SDL_ANDROID_ShowScreenUnderFingerRect.w > 0 ) if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER )
{ {
SDL_Rect dstrect = SDL_ANDROID_ShowScreenUnderFingerRect;
rect = SDL_ANDROID_ShowScreenUnderFingerRectSrc; rect = SDL_ANDROID_ShowScreenUnderFingerRectSrc;
dstrect = SDL_ANDROID_ShowScreenUnderFingerRect;
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect); SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect);
int buttons = SDL_GetMouseState(NULL, NULL); int buttons = SDL_GetMouseState(NULL, NULL);
// For some reason this code fails - it just outputs nothing to screen
/*
SDL_SetRenderDrawColor(0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(&SDL_ANDROID_ShowScreenUnderFingerRect);
SDL_SetRenderDrawColor(255, 255, 255, SDL_ALPHA_OPAQUE);
SDL_RenderDrawRect(&SDL_ANDROID_ShowScreenUnderFingerRectSrc);
SDL_SetRenderDrawColor(0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderDrawRect(&frame);
*/
// Do it old-fashioned way with direct GL calls // Do it old-fashioned way with direct GL calls
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
@@ -1053,7 +1045,6 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects)
glDrawArrays(GL_LINE_LOOP, 0, 4); glDrawArrays(GL_LINE_LOOP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix(); glPopMatrix();
//glFlush();
} }
#ifdef VIDEO_DEBUG #ifdef VIDEO_DEBUG
if( SDL_ANDROID_VideoDebugRect.w > 0 ) if( SDL_ANDROID_VideoDebugRect.w > 0 )

View File

@@ -38,7 +38,6 @@ If you compile this code with SDL 1.3 or newer, or use in some other way, the li
#include "SDL_config.h" #include "SDL_config.h"
#include "SDL_version.h" #include "SDL_version.h"
#include "SDL.h"
#include "SDL_video.h" #include "SDL_video.h"
#include "SDL_mouse.h" #include "SDL_mouse.h"
#include "SDL_mutex.h" #include "SDL_mutex.h"
@@ -437,22 +436,6 @@ void SDLCALL SDL_ANDROID_GetClipboardText(char * buf, int len)
(*JavaEnv)->PopLocalFrame( JavaEnv, NULL ); (*JavaEnv)->PopLocalFrame( JavaEnv, NULL );
} }
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeScreenVisibleRect) (JNIEnv* env, jobject thiz, jint x, jint y, jint w, jint h )
{
SDL_ANDROID_ScreenVisibleRect.x = x;
SDL_ANDROID_ScreenVisibleRect.y = y;
SDL_ANDROID_ScreenVisibleRect.w = w;
SDL_ANDROID_ScreenVisibleRect.h = h;
if( SDL_WasInit(SDL_INIT_VIDEO) )
{
// Move mouse by 1 pixel to force screen update
SDL_GetMouseState( &x, &y );
SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y);
}
}
int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position) int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position)
{ {
jint arr[5]; jint arr[5];

View File

@@ -31,8 +31,6 @@ TODO, which will get actually done
- XSDL: support Android intent x11://localhost:6000 - http://www.openintents.org/node/905 - XSDL: support Android intent x11://localhost:6000 - http://www.openintents.org/node/905
- XSDL: screen follows mouse when on-screen keyboard is shown.
- XSDL: copy text from Android clipboard when it changes. - XSDL: copy text from Android clipboard when it changes.
- USB Keyboard: configurable mouse speed, show keyboard LEDs, redefine unknown keys, fix Lollipop SELinux bug. - USB Keyboard: configurable mouse speed, show keyboard LEDs, redefine unknown keys, fix Lollipop SELinux bug.