Skip to content

Commit

Permalink
linux system cursor impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex2772 committed Aug 26, 2021
1 parent a96d641 commit 61e2758
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ RUN apt-get update -y && apt-get install -y software-properties-common
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN add-apt-repository -y ppa:openjdk-r/ppa
RUN add-apt-repository -y ppa:git-core/ppa
RUN apt-get update -y && apt-get install -y wget zip python git build-essential g++-9 cmake ninja-build libxcomposite-dev libxrandr-dev libgl1-mesa-dev libxi-dev openjdk-11-jdk-headless
RUN apt-get update -y && apt-get install -y wget zip python git build-essential g++-9 cmake ninja-build libxcomposite-dev libxrandr-dev libgl1-mesa-dev libxi-dev libxcursor-dev openjdk-11-jdk-headless
RUN wget --no-verbose https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz --output-document - | tar -xz
RUN echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64' > /etc/profile.d/02-jdk.sh
RUN echo 'export PATH=$JAVA_HOME/bin:/root/apache-maven-3.6.3/bin:$PATH' >> /etc/profile.d/02-jdk.sh
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Prerequisites:

- Shared: Git, CMake, Ninja, C++ compiler, JDK 11+, $JAVA_HOME, Python 3
- Windows 10: Microsoft Visual C++ (MSVC), x64 Native Tools Command Prompt for VS
- Ubuntu 20.04: `libxcomposite-dev libxrandr-dev libgl1-mesa-dev libxi-dev`
- Ubuntu 20.04: `libxcomposite-dev libxrandr-dev libgl1-mesa-dev libxi-dev libxcursor-dev`

Run:

Expand Down
2 changes: 1 addition & 1 deletion linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ target_include_directories(jwm PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../shared/cc ${
set_target_properties(jwm PROPERTIES OUTPUT_NAME "jwm_${JWM_ARCH}")


target_link_libraries(jwm PRIVATE X11::X11 X11::Xrandr X11::Xi)
target_link_libraries(jwm PRIVATE X11::X11 X11::Xrandr X11::Xcursor X11::Xi)
target_link_libraries(jwm PRIVATE OpenGL::GL)
30 changes: 30 additions & 0 deletions linux/cc/WindowManagerX11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "AppX11.hh"
#include <X11/extensions/sync.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
#include "KeyX11.hh"
#include "MouseButtonX11.hh"
Expand All @@ -26,6 +28,7 @@ int WindowManagerX11::_xerrorhandler(Display* dsp, XErrorEvent* error) {
WindowManagerX11::WindowManagerX11():
display(XOpenDisplay(nullptr)),
_atoms(display) {

XSetErrorHandler(_xerrorhandler);
screen = DefaultScreenOfDisplay(display);

Expand Down Expand Up @@ -138,6 +141,33 @@ WindowManagerX11::WindowManagerX11():
}
}
}

// load system cursors
{
const char* themeName = XcursorGetTheme(display);
int defaultSize = themeName != nullptr ? XcursorGetDefaultSize(display) : 0;
auto loadCursor = [&](const char* name, unsigned alternativeId) {
if (themeName) {
auto image = XcursorLibraryLoadImage(name, themeName, defaultSize);
if (image) {
auto cursor = XcursorImageLoadCursor(display, image);
XcursorImageDestroy(image);
return cursor;
}
}

// fallback to non-theme cursor
return XCreateFontCursor(display, alternativeId);
};

_cursors[static_cast<int>(jwm::MouseCursor::ARROW )] = loadCursor("default" , XC_left_ptr );
_cursors[static_cast<int>(jwm::MouseCursor::CROSSHAIR )] = loadCursor("crosshair" , XC_left_ptr );
_cursors[static_cast<int>(jwm::MouseCursor::HELP )] = loadCursor("help" , XC_left_ptr );
_cursors[static_cast<int>(jwm::MouseCursor::POINTING_HAND )] = loadCursor("pointer" , XC_hand2 );
_cursors[static_cast<int>(jwm::MouseCursor::IBEAM )] = loadCursor("text" , XC_xterm );
_cursors[static_cast<int>(jwm::MouseCursor::NOT_ALLOWED )] = loadCursor("not-allowed" , XC_left_ptr );
_cursors[static_cast<int>(jwm::MouseCursor::WAIT )] = loadCursor("watch" , XC_left_ptr );
}
}

void WindowManagerX11::_xi2IterateDevices() {
Expand Down
3 changes: 3 additions & 0 deletions linux/cc/WindowManagerX11.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <queue>
#include <mutex>
#include <condition_variable>
#include "MouseCursor.hh"

namespace jwm {
class WindowX11;
Expand Down Expand Up @@ -72,6 +73,8 @@ namespace jwm {
*/
XIM _im;

Cursor _cursors[static_cast<int>(jwm::MouseCursor::COUNT)];

std::mutex _taskQueueLock;
std::condition_variable _taskQueueNotify;
std::queue<std::function<void()>> _taskQueue;
Expand Down
14 changes: 14 additions & 0 deletions linux/cc/WindowX11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ const ScreenInfo& WindowX11::getScreen() {
return *jwm::app.getScreens().begin();
}

void jwm::WindowX11::setCursor(jwm::MouseCursor cursor) {
if (auto x11Cursor = _windowManager._cursors[static_cast<int>(cursor)]) {
XDefineCursor(_windowManager.display, _x11Window, x11Cursor);
} else {
XUndefineCursor(_windowManager.display, _x11Window);
}
}

// JNI

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_jwm_WindowX11__1nMake
Expand Down Expand Up @@ -382,4 +390,10 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_jwm_WindowX11__1nSetTitle
env->ReleaseByteArrayElements(title, bytes, 0);

instance->setTitle(titleS);
}
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_jwm_WindowX11__1nSetMouseCursor
(JNIEnv* env, jobject obj, jint idx) {
jwm::WindowX11* instance = reinterpret_cast<jwm::WindowX11*>(jwm::classes::Native::fromJava(env, obj));

instance->setCursor(static_cast<jwm::MouseCursor>(idx));
}
2 changes: 1 addition & 1 deletion linux/cc/WindowX11.hh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace jwm {
XIC getIC() const {
return _ic;
}

void setCursor(jwm::MouseCursor cursor);
void setLayer(ILayer* layer) {
_layer = layer;
}
Expand Down
6 changes: 1 addition & 5 deletions linux/java/org/jetbrains/jwm/WindowX11.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ public Window setTitle(String title) {
return this;
}

@ApiStatus.Internal @Override
public void _nSetMouseCursor(int cursorIdx) {
// TODO #99
}

@Override
public Window setIcon(File icon) {
// TODO #95
Expand Down Expand Up @@ -136,6 +131,7 @@ public Window restore() {
@ApiStatus.Internal public native UIRect _nGetContentRect();
@ApiStatus.Internal public native void _nSetWindowPosition(int left, int top);
@ApiStatus.Internal public native void _nSetWindowSize(int width, int height);
@ApiStatus.Internal public native void _nSetMouseCursor(int cursorId);
@ApiStatus.Internal public native void _nSetContentSize(int width, int height);
@ApiStatus.Internal public native Screen _nGetScreen();
@ApiStatus.Internal public native void _nRequestFrame();
Expand Down
5 changes: 4 additions & 1 deletion shared/cc/MouseCursor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ namespace jwm {
IBEAM = 4,
NOT_ALLOWED = 5,
WAIT = 6,
WIN_UPARROW = 7
WIN_UPARROW = 7,

// total enum count; keep this at the end
COUNT,
};

static const char* mouseCursorToStr(MouseCursor cursor) {
Expand Down

0 comments on commit 61e2758

Please sign in to comment.