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(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();
_videoLayout.getWindowVisibleDisplayFrame(r);
mGLView.nativeScreenVisibleRect(r.left, r.top, r.right, r.bottom);
_videoLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
public void onGlobalLayout()
{
public void onGlobalLayout()
{
Rect r = new Rect();
_videoLayout.getWindowVisibleDisplayFrame(r);
int heightDiff = _videoLayout.getRootView().getHeight() - _videoLayout.getHeight(); // Take system bar into consideration
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() );
}
});
}
Rect r = new Rect();
_videoLayout.getWindowVisibleDisplayFrame(r);
int heightDiff = _videoLayout.getRootView().getHeight() - _videoLayout.getHeight(); // Take system bar into consideration
int widthDiff = _videoLayout.getRootView().getWidth() - _videoLayout.getWidth(); // Nexus 5 has system bar at the right side
mGLView.nativeScreenVisibleRect(r.left + widthDiff, r.top + heightDiff, r.width(), r.height());
Log.v("SDL", "Main window visible region changed: " + r.left + ":" + r.top + ":" + r.width() + ":" + r.height() );
}
});
}
@Override

View File

@@ -527,7 +527,8 @@ class Settings
Globals.RightMouseButtonLongPress ? 1 : 0,
Globals.MoveMouseWithGyroscope ? 1 : 0,
Globals.MoveMouseWithGyroscopeSpeed,
Globals.CompatibilityHacksForceScreenUpdateMouseClick ? 1 : 0 );
Globals.CompatibilityHacksForceScreenUpdateMouseClick ? 1 : 0,
Globals.ScreenFollowsMouse ? 1 : 0 );
}
static void Apply(MainActivity p)
@@ -863,7 +864,7 @@ class Settings
int relativeMovementAccel, int showMouseCursor,
int HoverJitterFilter, int RightMouseButtonLongPress,
int MoveMouseWithGyroscope, int MoveMouseWithGyroscopeSpeed,
int ForceScreenUpdateMouseClick);
int ForceScreenUpdateMouseClick, int ScreenFollowsMouse);
private static native void nativeSetJoystickUsed(int amount);
private static native void nativeSetAccelerometerUsed();
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 <semaphore.h>
#include "SDL.h"
#include "SDL_config.h"
#include "SDL_version.h"
@@ -130,6 +131,8 @@ static unsigned int relativeMovementTime = 0;
int SDL_ANDROID_currentMouseX = 0;
int SDL_ANDROID_currentMouseY = 0;
int SDL_ANDROID_currentMouseButtons = 0;
int screenFollowsMouse = 0;
int SDL_ANDROID_SystemBarAndKeyboardShown;
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 };
@@ -1094,7 +1097,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel,
jint ShowMouseCursor, jint HoverJitterFilter, jint RightMouseButtonLongPress,
jint MoveMouseWithGyroscope, jint MoveMouseWithGyroscopeSpeed,
jint ForceScreenUpdateMouseClick)
jint ForceScreenUpdateMouseClick, jint ScreenFollowsMouse)
{
SDL_ANDROID_isMouseUsed = 1;
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 *= 5.0f;
forceScreenUpdateMouseClick = ForceScreenUpdateMouseClick;
screenFollowsMouse = ScreenFollowsMouse;
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "moveMouseWithGyroscopeSpeed %d = %f", MoveMouseWithGyroscopeSpeed, moveMouseWithGyroscopeSpeed);
if( !mouseClickTimeoutInitialized && (
leftClickMethod == LEFT_CLICK_WITH_TAP ||
@@ -1137,49 +1141,78 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
}
}
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected)
typedef struct
{
if( !SDL_ANDROID_isMouseUsed )
return;
static struct {
int leftClickMethod;
int ShowScreenUnderFinger;
int leftClickTimeout;
int relativeMovement;
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;
if(detected)
initialized = 1;
saveMouseSettings(&cfg);
}
if( hardwareMouseDetected != detected || ScreenSizeCallback )
{
if( !ScreenSizeCallback )
{
cfg.leftClickMethod = leftClickMethod;
cfg.ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger;
cfg.leftClickTimeout = leftClickTimeout;
cfg.relativeMovement = relativeMovement;
cfg.ShowMouseCursor = SDL_ANDROID_ShowMouseCursor;
hardwareMouseDetected = detected;
if( SDL_ANDROID_SystemBarAndKeyboardShown )
return; // Do not enable hardware mouse mode when the keyboard is shown
}
if( detected )
{
saveMouseSettings(&cfg);
leftClickMethod = LEFT_CLICK_NORMAL;
SDL_ANDROID_ShowScreenUnderFinger = 0;
SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE;
leftClickTimeout = 0;
relativeMovement = 0;
SDL_ANDROID_ShowMouseCursor = 0;
}
else
{
leftClickMethod = cfg.leftClickMethod;
SDL_ANDROID_ShowScreenUnderFinger = cfg.ShowScreenUnderFinger;
leftClickTimeout = cfg.leftClickTimeout;
relativeMovement = cfg.relativeMovement;
SDL_ANDROID_ShowMouseCursor = cfg.ShowMouseCursor;
}
restoreMouseSettings(&cfg);
}
SDL_ANDROID_SetHoverDeadzone();
}
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected)
{
processHardwareMouseDetected(detected, 0);
}
void SDL_ANDROID_SetHoverDeadzone()
{
hoverDeadzone = (hardwareMouseDetected == MOUSE_HW_INPUT_STYLUS) ?
@@ -1551,7 +1584,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenCalibration) (JNIEnv* env, jobject
SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1;
}
JNIEXPORT void JNICALL
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz )
{
SDL_android_init_keymap(SDL_android_keymap);
@@ -1607,3 +1640,48 @@ void *mouseClickTimeoutThread (void * unused)
}
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_moveMouseWithKbAccelX, SDL_ANDROID_moveMouseWithKbAccelY;
extern int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded;
extern int SDL_ANDROID_SystemBarAndKeyboardShown;
#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()");
if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels && ! ( SDL_CurrentVideoSurface->flags & SDL_HWSURFACE ) )
{
SDL_Rect rect, dstrect;
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = SDL_CurrentVideoSurface->w;
@@ -998,12 +998,13 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects)
}
}
if( SDL_ANDROID_ScreenVisibleRect.h <= 0 )
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect);
if( !SDL_ANDROID_SystemBarAndKeyboardShown )
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &rect);
else
{
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.h = SDL_ANDROID_ScreenVisibleRect.h * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_sRealWindowHeight;
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);
}
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;
dstrect = SDL_ANDROID_ShowScreenUnderFingerRect;
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &dstrect);
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
glPushMatrix();
glLoadIdentity();
@@ -1053,7 +1045,6 @@ static void ANDROID_FlipHWSurfaceInternal(int numrects, SDL_Rect *rects)
glDrawArrays(GL_LINE_LOOP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
//glFlush();
}
#ifdef VIDEO_DEBUG
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_version.h"
#include "SDL.h"
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "SDL_mutex.h"
@@ -437,22 +436,6 @@ void SDLCALL SDL_ANDROID_GetClipboardText(char * buf, int len)
(*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)
{
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: screen follows mouse when on-screen keyboard is shown.
- XSDL: copy text from Android clipboard when it changes.
- USB Keyboard: configurable mouse speed, show keyboard LEDs, redefine unknown keys, fix Lollipop SELinux bug.