Skip to content

[GTK3] Issue 371 - Fix crash when taking a snapshot on Wayland #465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 30, 2023

Conversation

ptziegler
Copy link
Contributor

@ptziegler ptziegler commented May 25, 2023

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.

Using the high-level SWT API for taking the snapshot also means we can
drastically reduce the complexity of our code. Instead of having to deal
with pointers, we can use the high-level construct of images.

May resolve #371

@github-actions
Copy link

github-actions bot commented May 25, 2023

Unit Test Results

       16 files         16 suites   59m 18s ⏱️
  7 214 tests   7 214 ✔️ 0 💤 0
14 436 runs  14 436 ✔️ 0 💤 0

Results for commit f0281f6.

♻️ This comment has been updated with latest results.

@ptziegler ptziegler marked this pull request as draft May 27, 2023 11:04
@ptziegler ptziegler changed the title cairo_create() is deprecated; Use gdk_window_begin_draw_frame() instead. [GTK3] Fix segfault when taking SWT screen shot on Wayland May 29, 2023
@ptziegler
Copy link
Contributor Author

For comparison, this is what the shell currently looks like:

image

This is the shell when capturing the decorations directly:

image

@ptziegler ptziegler changed the title [GTK3] Fix segfault when taking SWT screen shot on Wayland [GTK3] Issue 371 - Fix crash when taking a snapshot on Wayland Jun 10, 2023
@ptziegler ptziegler force-pushed the issue371 branch 2 times, most recently from 5f3e92e to 5f771d3 Compare June 10, 2023 22:57
@ptziegler
Copy link
Contributor Author

For example, this code snippet will cause WindowBuilder to crash, when opened on Wayland:

class Test extends Shell {
	Test() {
	{
		Button button = new Button(this, SWT.NONE);
		button.setBounds(10, 10, 50, 40);
		button.setText("000");
	}
	{
		Button button = new Button(this, SWT.NONE);
		button.setBounds(70, -10, 100, 80);
		button.setText("111");
	}
	}
}

Because the button "111" is partially outside the visible area, we are unable to create a snapshot of it. This seems to be an issue within Wayland itself. And I don't know if/how this could be resolved. So my solution is to delegate this problem to SWT, which seems to have a much more stable snapshot implementation.

@ptziegler ptziegler force-pushed the issue371 branch 7 times, most recently from fb4526f to a24be13 Compare June 13, 2023 14:12
@ptziegler
Copy link
Contributor Author

As mentioned in the initial comment, this should fix the crash when using WindowBuilder with Wayland. In short, taking a screenshot of a partially mapped widget is not something that Wayland can handle very well.

@vogella Since you initially reported the bug, can you check whether the JUnit tests finish on your machine, when using this branch? I'm using X11, so I only have limited access to Wayland, so I can't say for certain whether I've missed something. The pull request might still a draft, but I don't expect any major deviation from the current solution.

Please note that there is a high chance that the preview in the Design page will be complete blank (on Wayland at least). It seems like taking a simple screenshot of a widget is also something that doesn't work very well in Wayland. But that problem also exists on the master. See eclipse-platform/eclipse.platform.swt#673.

@ptziegler ptziegler force-pushed the issue371 branch 2 times, most recently from b7dd260 to 62d6de7 Compare June 15, 2023 05:00
@vogella
Copy link
Contributor

vogella commented Jun 15, 2023

@ptziegler sorry, this week busy with something else. If it is still relevent next week, please ping me again, unfortunately my Eclipse email flow is steady and without me looking at it regulary, things scroll out of sight fast.

@ptziegler
Copy link
Contributor Author

No worries :) Even though I only used a very limited Wayland test-environment, I was able to reproduce and fix the problem within it. So I assume it should work in general.
I'll test some more screens over the weekend and if everything looks fine, then I'll probably just commit it.

@ptziegler ptziegler marked this pull request as ready for review June 20, 2023 04:11
@ptziegler ptziegler force-pushed the issue371 branch 2 times, most recently from ec67122 to 2aa6ecb Compare June 21, 2023 19:29
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.
@ptziegler ptziegler merged commit 87d34be into eclipse-windowbuilder:master Jun 30, 2023
@ptziegler ptziegler deleted the issue371 branch August 12, 2023 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants