Skip to content

Commit 7d76cb6

Browse files
committed
[GTK3] Issue 371 - Fix crash when taking a snapshot on Wayland
In short, our implementation doesn't seem to support taking snapshots of partially unmapped widgets when running Wayland instead of X11. Instead of trying to implement a workaround in native code, I think it's more efficient (for both the sake of complexity and maintainability) to elevate our snapshot mechanism from C to Java code. Where necessary, we call the native GTK methods either by the GTK/GDK class or via wrapper methods implemented by WindowBuilder. The snapshot is taken by creating a new image using the bounds of the widget and by painting the area it's occupying on the screen via GC. Note that this approach assumes that the widget isn't obstructed. But a similar restriction already exists on the native implementation. Shells represent a special edge-case. Instead of only taking a snapshot of the client area, the whole shell is considered. This way the title bar is included as well, rendering the explicit painting of its decorations obsolete.
1 parent 47146a0 commit 7d76cb6

File tree

9 files changed

+285
-224
lines changed

9 files changed

+285
-224
lines changed

org.eclipse.wb.os.linux/build.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ bin.includes = META-INF/,\
44
.,\
55
plugin.xml,\
66
os/,\
7-
icons/,\
87
plugin.properties,\
98
about.html
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

org.eclipse.wb.os.linux/native/gtk/gtk3/rcp.c

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2011 Google, Inc.
2+
* Copyright (c) 2011, 2023 Google, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -196,6 +196,42 @@ static cairo_surface_t* fetchMenuVisualData(GtkMenu *menu, JNIEnv *envir, jintAr
196196
// JNI
197197
//
198198
////////////////////////////////////////////////////////////////////////////
199+
JNIEXPORT jboolean JNICALL
200+
OS_NATIVE(_1gdk_1window_1is_1visible)
201+
(JNIEnv *envir, jobject that, JHANDLE windowHandle) {
202+
return gdk_window_is_visible((GdkWindow*)unwrap_pointer(envir, windowHandle));
203+
}
204+
JNIEXPORT void JNICALL
205+
OS_NATIVE(_1gdk_1window_1get_1geometry)
206+
(JNIEnv *envir, jobject that, JHANDLE windowHandle, jintArray x, jintArray y, jintArray width, jintArray height) {
207+
jint x1;
208+
jint y1;
209+
jint width1;
210+
jint height1;
211+
gdk_window_get_geometry((GdkWindow*)unwrap_pointer(envir, windowHandle), &x1, &y1, &width1, &height1);
212+
if (x != NULL) {
213+
(*envir) -> SetIntArrayRegion(envir, x, 0, 1, &x1);
214+
}
215+
if (y != NULL) {
216+
(*envir) -> SetIntArrayRegion(envir, y, 0, 1, &y1);
217+
}
218+
if (width != NULL) {
219+
(*envir) -> SetIntArrayRegion(envir, width, 0, 1, &width1);
220+
}
221+
if (height != NULL) {
222+
(*envir) -> SetIntArrayRegion(envir, height, 0, 1, &height1);
223+
}
224+
}
225+
JNIEXPORT JHANDLE JNICALL
226+
OS_NATIVE(_1gtk_1widget_1get_1window)
227+
(JNIEnv *envir, jobject that, JHANDLE widgetHandle) {
228+
return (JHANDLE)wrap_pointer(envir, gtk_widget_get_window((GtkWidget*)unwrap_pointer(envir, widgetHandle)));
229+
}
230+
JNIEXPORT JHANDLE JNICALL
231+
OS_NATIVE(_1gdk_1window_1process_1updates)
232+
(JNIEnv *envir, jobject that, JHANDLE widgetHandle, jboolean update_children) {
233+
gdk_window_process_updates((GdkWindow*)unwrap_pointer(envir, widgetHandle), update_children);
234+
}
199235
JNIEXPORT jboolean JNICALL
200236
OS_NATIVE(_1toggle_1above)
201237
(JNIEnv *envir, jobject that, JHANDLE widgetHandle, jboolean forceToggle) {
@@ -216,26 +252,6 @@ JNIEXPORT jboolean JNICALL
216252
gtk_widget_hide((GtkWidget*)unwrap_pointer(envir, widgetHandle));
217253
return JNI_TRUE;
218254
}
219-
// shot
220-
JNIEXPORT JHANDLE JNICALL OS_NATIVE(_1makeShot)(
221-
JNIEnv *envir, jobject that, JHANDLE widgetHandle, jobject callback) {
222-
m_envir = envir;
223-
if (callback != NULL) {
224-
m_callback = (*envir)->NewGlobalRef(envir, callback);
225-
jclass clazz = (*envir)->GetObjectClass(envir, m_callback);
226-
m_IScreenshotCallback_storeImage = (*envir)->GetMethodID(envir, clazz, "storeImage", CALLBACK_SIG);
227-
/* uncomment this for debug purposes
228-
m_IScreenshotCallback_log = (*envir)->GetMethodID(envir, clazz, "log", "(Ljava/lang/String;)V"); */
229-
}
230-
// make shot
231-
cairo_surface_t* surface = makeShot((GtkWidget*)unwrap_pointer(envir, widgetHandle));
232-
// clean up
233-
if (callback != NULL) {
234-
(*envir)->DeleteGlobalRef(envir, m_callback);
235-
}
236-
m_callback = NULL;
237-
return (JHANDLE)wrap_pointer(envir, surface);
238-
}
239255
// menu
240256
JNIEXPORT JHANDLE JNICALL OS_NATIVE(_1fetchMenuVisualData)(
241257
JNIEnv *envir, jobject that, JHANDLE jmenuHandle, jintArray jsizes) {
@@ -248,11 +264,6 @@ JNIEXPORT void JNICALL OS_NATIVE(_1getWidgetBounds)(
248264
JNIEnv *envir, jobject that, JHANDLE jhandle, jintArray jsizes) {
249265
getWidgetBounds((GtkWidget*)unwrap_pointer(envir, jhandle), envir, jsizes);
250266
}
251-
// unref
252-
JNIEXPORT void JNICALL OS_NATIVE(_1disposeImageHandle)(
253-
JNIEnv *envir, jobject that, JHANDLE jhandle) {
254-
cairo_surface_destroy((cairo_surface_t*)unwrap_pointer(envir, jhandle));
255-
}
256267
// other
257268
static int isValidVersion() {
258269
return gtk_major_version == 3 && gtk_minor_version >= 0;
Binary file not shown.

org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/IScreenshotCallback.java

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)