Skip to content

Commit

Permalink
X11: add setIconData
Browse files Browse the repository at this point in the history
  • Loading branch information
dzaima authored and tonsky committed Sep 27, 2024
1 parent 2df254a commit 3e5990c
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
1 change: 1 addition & 0 deletions linux/cc/WindowManagerX11.hh
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ namespace jwm {
DEFINE_ATOM(_MOTIF_WM_HINTS);
DEFINE_ATOM(_NET_WM_STATE);
DEFINE_ATOM(_NET_WM_NAME);
DEFINE_ATOM(_NET_WM_ICON);
DEFINE_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
DEFINE_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
DEFINE_ATOM(_NET_FRAME_EXTENTS);
Expand Down
32 changes: 32 additions & 0 deletions linux/cc/WindowX11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ void WindowX11::setClass(const std::string& name, const std::string& appClass) {
}
}

void WindowX11::setIconData(int width, int height, const unsigned char* argb) {
size_t size = width * height;
size_t count = size + 2;
std::unique_ptr<long[]> buffer{new long[count]};
buffer[0] = width;
buffer[1] = height;
for (size_t i = 0; i < size; i++) {
uint32_t c = static_cast<uint32_t>(argb[i*4]) |
static_cast<uint32_t>(argb[i*4 + 1]) << 8 |
static_cast<uint32_t>(argb[i*4 + 2]) << 16 |
static_cast<uint32_t>(argb[i*4 + 3]) << 24;
buffer[i+2] = c;
}
XChangeProperty(_windowManager.getDisplay(),
_x11Window,
_windowManager.getAtoms()._NET_WM_ICON,
XA_CARDINAL,
32,
PropModeReplace,
reinterpret_cast<const unsigned char*>(buffer.get()),
count);
}

void WindowX11::setTitlebarVisible(bool isVisible) {
MotifHints motifHints = {0};

Expand Down Expand Up @@ -586,6 +609,15 @@ extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowX11__1nSetCl
instance->setClass(bytesToString(env, name), bytesToString(env, appClass));
}

extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowX11__1nSetIconData
(JNIEnv* env, jobject obj, jint width, jint height, jbyteArray data) {
jwm::WindowX11* instance = reinterpret_cast<jwm::WindowX11*>(jwm::classes::Native::fromJava(env, obj));

jbyte* bytes = env->GetByteArrayElements(data, nullptr);
instance->setIconData(width, height, reinterpret_cast<const unsigned char*>(bytes));
env->ReleaseByteArrayElements(data, bytes, 0);
}

extern "C" JNIEXPORT void JNICALL Java_io_github_humbleui_jwm_WindowX11__1nSetTitlebarVisible
(JNIEnv* env, jobject obj, jboolean isVisible) {
jwm::WindowX11* instance = reinterpret_cast<jwm::WindowX11*>(jwm::classes::Native::fromJava(env, obj));
Expand Down
1 change: 1 addition & 0 deletions linux/cc/WindowX11.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace jwm {
}
void setTitle(const std::string& title);
void setClass(const std::string& name, const std::string& class_);
void setIconData(int width, int height, const unsigned char* argb);
void setTitlebarVisible(bool isVisible);

void maximize();
Expand Down
19 changes: 19 additions & 0 deletions linux/java/WindowX11.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,24 @@ public Window setClassHint(String name, String appClass) {
return this;
}

/**
* <p>Set window icon from raw image bytes.</p>
*
* <p>{@code data} must have a length of {@code width * height * 4}, representing per-pixel ARGB data.</p>
*
* @param width icon width in pixels
* @param height icon height in pixels
* @param data icon image data
* @return this
*/
@NotNull @Contract("-> this")
public Window setIconData(int width, int height, byte[] data) {
assert _onUIThread() : "Should be run on UI thread";
assert data.length == width*height*4 : "Incorrect icon data array length";
_nSetIconData(width, height, data);
return this;
}

@Override
public Window setTitlebarVisible(boolean value) {
_nSetTitlebarVisible(value);
Expand Down Expand Up @@ -246,6 +264,7 @@ public boolean isFullScreen() {
@ApiStatus.Internal public native void _nRestore();
@ApiStatus.Internal public native void _nSetTitle(byte[] title);
@ApiStatus.Internal public native void _nSetClassHint(byte[] name, byte[] appClass);
@ApiStatus.Internal public native void _nSetIconData(int width, int height, byte[] data);
@ApiStatus.Internal public native void _nSetTitlebarVisible(boolean isVisible);
@ApiStatus.Internal public native void _nSetFullScreen(boolean isFullScreen);
@ApiStatus.Internal public native boolean _nIsFullScreen();
Expand Down

0 comments on commit 3e5990c

Please sign in to comment.