Skip to content

Commit

Permalink
Merge pull request HumbleUI#253 from HumbleUI/lock-cursor
Browse files Browse the repository at this point in the history
macOS: lock mouse cursor, and add ⌘U to test in dashboard
  • Loading branch information
tonsky authored Dec 11, 2022
2 parents dac3d9a + be597ae commit e38b3c4
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 7 deletions.
1 change: 1 addition & 0 deletions examples/dashboard/java/PanelLegend.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public PanelLegend(Window window) {
shortcuts.put("F", "Fullscreen");
shortcuts.put("X", "Clipboard formats");
shortcuts.put("Y", "Hide mouse cursor");
shortcuts.put("U", "Lock mouse cursor");
shortcuts.put("Z", "Toggle Z-order");
shortcuts.put("B", "Toggle Progress Bar");
shortcuts.put("O", "Opacity");
Expand Down
7 changes: 6 additions & 1 deletion examples/dashboard/java/PanelMouseCursors.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
import io.github.humbleui.types.*;

public class PanelMouseCursors extends Panel {
public EventMouseMove lastMove = new EventMouseMove(0, 0, 0, 0);
public EventMouseMove lastMove = new EventMouseMove(0, 0, 0, 0, 0, 0);
public Map<IRect, MouseCursor> rects = new HashMap<>();
public boolean lastInside = false;
public boolean keepCursor = false;
public boolean cursorHidden = false;
public boolean cursorLocked = false;

public PanelMouseCursors(Window window) {
super(window);
Expand All @@ -28,6 +29,10 @@ public void accept(Event e) {
window.hideMouseCursorUntilMoved(!cursorHidden);
cursorHidden = !cursorHidden;
}
case U -> {
window.lockMouseCursor(!cursorLocked);
cursorLocked = !cursorLocked;
}
}
}
} else if (e instanceof EventMouseMove ee) {
Expand Down
3 changes: 3 additions & 0 deletions linux/cc/WindowManagerX11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,14 @@ void WindowManagerX11::_processXEvent(XEvent& ev) {
XQueryPointer(display, myWindow->_x11Window, &unused1, &unused1, &unused2, &unused2, &unused2, &unused2, &mask);
lastMousePosX = deviceEvent->event_x;
lastMousePosY = deviceEvent->event_y;
int movementX = 0, movementY = 0; // TODO: impl me!
jwm::JNILocal<jobject> eventMove(
app.getJniEnv(),
EventMouseMove::make(app.getJniEnv(),
deviceEvent->event_x,
deviceEvent->event_y,
movementX,
movementY,
jwm::MouseButtonX11::fromNativeMask(mask),
jwm::KeyX11::getModifiers()
)
Expand Down
6 changes: 6 additions & 0 deletions linux/java/WindowX11.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ public Window hideMouseCursorUntilMoved(boolean value) {
return this;
}

@Override
public Window lockMouseCursor(boolean value) {
// TODO impl me!
return this;
}

@Override
public Window setOpacity(float opacity) {
// TODO: impl me!
Expand Down
2 changes: 2 additions & 0 deletions macos/cc/JWMMainView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ void onMouseMoved(jwm::WindowMac* window, NSEvent* event, CGPoint* lastPos) {
window->fEnv,
(jint) lastPos->x,
(jint) lastPos->y,
(jint)[event deltaX],
(jint)[event deltaY],
[NSEvent pressedMouseButtons],
jwm::modifierMask([event modifierFlags])));
window->dispatch(eventObj.get());
Expand Down
12 changes: 12 additions & 0 deletions macos/cc/WindowMac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,18 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
[NSCursor setHiddenUntilMouseMoves:value];
}

extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowMac__1nLockMouseCursor
(JNIEnv* env, jobject obj, jboolean value) {
jwm::WindowMac* instance = reinterpret_cast<jwm::WindowMac*>(jwm::classes::Native::fromJava(env, obj));
if (value) {
CGAssociateMouseAndMouseCursorPosition(NO);
[NSCursor hide];
} else {
CGAssociateMouseAndMouseCursorPosition(YES);
[NSCursor unhide];
}
}

extern "C" JNIEXPORT jobject JNICALL Java_io_github_humbleui_jwm_WindowMac__1nGetScreen
(JNIEnv* env, jobject obj) {
jwm::WindowMac* instance = reinterpret_cast<jwm::WindowMac*>(jwm::classes::Native::fromJava(env, obj));
Expand Down
8 changes: 8 additions & 0 deletions macos/java/WindowMac.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ public Window hideMouseCursorUntilMoved(boolean value) {
return this;
}

@Override
public Window lockMouseCursor(boolean value) {
assert _onUIThread();
_nLockMouseCursor(value);
return this;
}

@Override
public Window setVisible(boolean value) {
assert _onUIThread();
Expand Down Expand Up @@ -291,6 +298,7 @@ public void close() {
@ApiStatus.Internal public native void _nSetTrafficLightPosition(int left, int top);
@ApiStatus.Internal public native void _nSetTrafficLightsVisible(boolean value);
@ApiStatus.Internal public native void _nHideMouseCursorUntilMoved(boolean value);
@ApiStatus.Internal public native void _nLockMouseCursor(boolean value);
@ApiStatus.Internal public native void _nSetVisible(boolean value);
@ApiStatus.Internal public native Screen _nGetScreen();
@ApiStatus.Internal public native void _nRequestFrame();
Expand Down
6 changes: 3 additions & 3 deletions shared/cc/impl/Library.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,12 @@ namespace jwm {
JNILocal<jclass> cls(env, env->FindClass("io/github/humbleui/jwm/EventMouseMove"));
Throwable::exceptionThrown(env);
kCls = static_cast<jclass>(env->NewGlobalRef(cls.get()));
kCtor = env->GetMethodID(kCls, "<init>", "(IIII)V");
kCtor = env->GetMethodID(kCls, "<init>", "(IIIIII)V");
Throwable::exceptionThrown(env);
}

jobject make(JNIEnv* env, jint x, jint y, jint buttons, jint modifiers) {
jobject res = env->NewObject(kCls, kCtor, x, y, buttons, modifiers);
jobject make(JNIEnv* env, jint x, jint y, jint movementX, jint movementY, jint buttons, jint modifiers) {
jobject res = env->NewObject(kCls, kCtor, x, y, movementX, movementY, buttons, modifiers);
return Throwable::exceptionThrown(env) ? nullptr : res;
}
}
Expand Down
2 changes: 1 addition & 1 deletion shared/cc/impl/Library.hh
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ namespace jwm {
namespace EventMouseMove {
extern jclass kCls;
extern jmethodID kCtor;
jobject make(JNIEnv* env, jint x, jint y, jint buttons = 0, jint modifiers = 0);
jobject make(JNIEnv* env, jint x, jint y, jint movementX, jint movementY, jint buttons = 0, jint modifiers = 0);
}

namespace EventMouseScroll {
Expand Down
4 changes: 3 additions & 1 deletion shared/java/EventMouseMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
public class EventMouseMove implements Event {
@ApiStatus.Internal public final int _x;
@ApiStatus.Internal public final int _y;
@ApiStatus.Internal public final int _movementX; // for when cursor is locked
@ApiStatus.Internal public final int _movementY;
@ApiStatus.Internal @Getter(AccessLevel.NONE) public final int _buttons;
@ApiStatus.Internal @Getter(AccessLevel.NONE) public final int _modifiers;

Expand All @@ -17,4 +19,4 @@ public boolean isButtonDown(MouseButton button) {
public boolean isModifierDown(KeyModifier modifier) {
return (_modifiers & modifier._mask) != 0;
}
}
}
9 changes: 9 additions & 0 deletions shared/java/Window.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ public Window hideMouseCursorUntilMoved() {
@NotNull @Contract("_ -> this")
public abstract Window hideMouseCursorUntilMoved(boolean value);

/**
* <p>Locks and hides mouse cursor. Call with `false` to unlock and unhide.</p>
*
* @param value true to lock/hide, false to unlock/unhide
* @return this
*/
@NotNull @Contract("_ -> this")
public abstract Window lockMouseCursor(boolean value);

/**
* <p>Set window visibility.</p>
*
Expand Down
3 changes: 2 additions & 1 deletion windows/cc/WindowWin32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,8 @@ LRESULT jwm::WindowWin32::processEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
int buttons = _getMouseButtons();
int modifiers = _getModifiers();

JNILocal<jobject> eventMouseMove(env, classes::EventMouseMove::make(env, _lastMousePosX, _lastMousePosY, buttons, modifiers));
int movementX = 0, movementY = 0; // TODO: impl me!
JNILocal<jobject> eventMouseMove(env, classes::EventMouseMove::make(env, _lastMousePosX, _lastMousePosY, movementX, movementY, buttons, modifiers));
dispatch(eventMouseMove.get());
return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions windows/java/WindowWin32.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public Window hideMouseCursorUntilMoved(boolean value) {
return this;
}

@Override
public Window lockMouseCursor(boolean value) {
// TODO impl me!
return this;
}

@Override
public Window setVisible(boolean isVisible) {
assert _onUIThread();
Expand Down

0 comments on commit e38b3c4

Please sign in to comment.