diff options
author | Maxim Kartashev <maxim.kartashev@jetbrains.com> | 2023-08-21 14:37:40 +0400 |
---|---|---|
committer | Maxim Kartashev <maxim.kartashev@jetbrains.com> | 2023-08-23 15:32:12 +0400 |
commit | 3834f6c24e435ef8df76a936d3146faef6f70ce4 (patch) | |
tree | 29b19300c21bdc9728bfe1edac38a953204b5254 | |
parent | a4e4430a5a7c2860de70ae59e94ba6aa9e3a23c8 (diff) | |
download | JetBrainsRuntime-3834f6c24e435ef8df76a936d3146faef6f70ce4.tar.gz |
JBR-5962 Wayland: fix the main event loop to allow for secondary queuesjb21-b208
Return READ_RESULT_FINISHED_NO_EVENTS from WLToolkit.readEvents() in
case of poll returning with no new data (i.e. via timeout).
-rw-r--r-- | src/java.desktop/unix/native/libawt_wlawt/WLRobotPeer.c | 6 | ||||
-rw-r--r-- | src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c | 53 | ||||
-rw-r--r-- | src/java.desktop/unix/native/libawt_wlawt/WLToolkit.h | 2 |
3 files changed, 32 insertions, 29 deletions
diff --git a/src/java.desktop/unix/native/libawt_wlawt/WLRobotPeer.c b/src/java.desktop/unix/native/libawt_wlawt/WLRobotPeer.c index 817e69cdcf3..e054144dae5 100644 --- a/src/java.desktop/unix/native/libawt_wlawt/WLRobotPeer.c +++ b/src/java.desktop/unix/native/libawt_wlawt/WLRobotPeer.c @@ -331,7 +331,7 @@ Java_sun_awt_wl_WLRobotPeer_getRGBPixelImpl(JNIEnv *env, jclass clazz, jint x, j WAKEFIELD_REQUEST_INIT(pixel_color_request); wakefield_get_pixel_color(wakefield, x, y); - wl_flush_to_server(env); // the event will be delivered on a dedicated thread, see wakefield_pixel_color() + wlFlushToServer(env); // the event will be delivered on a dedicated thread, see wakefield_pixel_color() WAKEFIELD_REQUEST_WAIT_START(pixel_color_request); const uint32_t error_code = pixel_color_request.error_code; @@ -362,7 +362,7 @@ Java_sun_awt_wl_WLRobotPeer_getLocationOfWLSurfaceImpl struct wl_surface * const surface = (struct wl_surface*) wlSurfacePtr; wakefield_get_surface_location(wakefield, surface); - wl_flush_to_server(env); // the event will be delivered on a dedicated thread, see wakefield_surface_location() + wlFlushToServer(env); // the event will be delivered on a dedicated thread, see wakefield_surface_location() WAKEFIELD_REQUEST_WAIT_START(surface_location_request); const uint32_t error_code = surface_location_request.error_code; @@ -397,7 +397,7 @@ Java_sun_awt_wl_WLRobotPeer_setLocationOfWLSurfaceImpl struct wl_surface * const surface = (struct wl_surface*) wlSurfacePtr; wakefield_move_surface(wakefield, surface, x, y); wl_surface_commit(surface); - wl_flush_to_server(env); + wlFlushToServer(env); #endif } diff --git a/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c b/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c index 9209103e114..aebbe6d8c8d 100644 --- a/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c +++ b/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c @@ -356,13 +356,13 @@ wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, } static inline void -reset_pointer_event(struct pointer_event_cumulative *e) +resetPointerEvent(struct pointer_event_cumulative *e) { memset(e, 0, sizeof(struct pointer_event_cumulative)); } static void -fill_java_pointer_event(JNIEnv* env, jobject pointerEventRef) +fillJavaPointerEvent(JNIEnv* env, jobject pointerEventRef) { (*env)->SetBooleanField(env, pointerEventRef, hasEnterEventFID, pointer_event.has_enter_event); (*env)->SetBooleanField(env, pointerEventRef, hasLeaveEventFID, pointer_event.has_leave_event); @@ -396,14 +396,14 @@ wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) pointerEventFactoryMID); JNU_CHECK_EXCEPTION(env); - fill_java_pointer_event(env, pointerEventRef); + fillJavaPointerEvent(env, pointerEventRef); (*env)->CallStaticVoidMethod(env, tkClass, dispatchPointerEventMID, pointerEventRef); JNU_CHECK_EXCEPTION(env); - reset_pointer_event(&pointer_event); + resetPointerEvent(&pointer_event); } static const struct wl_pointer_listener wl_pointer_listener = { @@ -854,7 +854,7 @@ initCursors() { } static void -finalize_init(JNIEnv *env) { +finalizeInit(JNIEnv *env) { // NB: we are NOT on EDT here so shouldn't dispatch EDT-sensitive stuff while (num_of_outstanding_sync > 0) { // There are outstanding events that carry information essential for the toolkit @@ -902,7 +902,7 @@ Java_sun_awt_wl_WLToolkit_initIDs initCursors(); - finalize_init(env); + finalizeInit(env); } JNIEXPORT void JNICALL @@ -915,8 +915,12 @@ Java_sun_awt_wl_WLToolkit_dispatchEventsOnEDT wl_display_dispatch_pending(wl_display); } +/** + * Waits for poll_timeout ms for an event on the Wayland server socket. + * Returns -1 in case of error and 'revents' (see poll(2)) otherwise. + */ static int -wl_display_poll(struct wl_display *display, int events, int poll_timeout) +wlDisplayPoll(struct wl_display *display, int events, int poll_timeout) { int rc = 0; struct pollfd pfd[1] = { {.fd = wl_display_get_fd(display), .events = events} }; @@ -924,11 +928,12 @@ wl_display_poll(struct wl_display *display, int events, int poll_timeout) errno = 0; rc = poll(pfd, 1, poll_timeout); } while (rc == -1 && errno == EINTR); - return rc; + + return rc == -1 ? -1 : (pfd[0].revents & 0xffff); } int -wl_flush_to_server(JNIEnv *env) +wlFlushToServer(JNIEnv *env) { int rc = 0; @@ -939,7 +944,7 @@ wl_flush_to_server(JNIEnv *env) break; } - rc = wl_display_poll(wl_display, POLLOUT, -1); + rc = wlDisplayPoll(wl_display, POLLOUT, -1); if (rc == -1) { JNU_ThrowByName(env, "java/awt/AWTError", "Wayland display error polling out to the server"); return sun_awt_wl_WLToolkit_READ_RESULT_ERROR; @@ -958,7 +963,7 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_WLToolkit_flushImpl (JNIEnv *env, jobject obj) { - (void) wl_flush_to_server(env); + (void) wlFlushToServer(env); } JNIEXPORT void JNICALL @@ -974,16 +979,7 @@ Java_sun_awt_wl_WLToolkit_dispatchNonDefaultQueuesImpl while (rc >= 0) { // Dispatch pending events on the wakefield queue - while (wl_display_prepare_read_queue(wl_display, robot_queue) != 0 && rc >= 0) { - rc = wl_display_dispatch_queue_pending(wl_display, robot_queue); - } - if (rc < 0) { - wl_display_cancel_read(wl_display); - break; - } - - // Wait for new events, wl_display_read_events is a synchronization point between all threads reading events. - rc = wl_display_read_events(wl_display); + rc = wl_display_dispatch_queue(wl_display, robot_queue); } // Simply return in case of any error; the actual error reporting (exception) @@ -1007,7 +1003,7 @@ Java_sun_awt_wl_WLToolkit_readEvents return sun_awt_wl_WLToolkit_READ_RESULT_FINISHED_WITH_EVENTS; } - rc = wl_flush_to_server(env); + rc = wlFlushToServer(env); if (rc != 0) { wl_display_cancel_read(wl_display); return sun_awt_wl_WLToolkit_READ_RESULT_ERROR; @@ -1016,7 +1012,7 @@ Java_sun_awt_wl_WLToolkit_readEvents // Wait for new data *from* the server. // Specify some timeout because otherwise 'flush' above that sends data // to the server will have to wait too long. - rc = wl_display_poll(wl_display, POLLIN, + rc = wlDisplayPoll(wl_display, POLLIN, sun_awt_wl_WLToolkit_WAYLAND_DISPLAY_INTERACTION_TIMEOUT_MS); if (rc == -1) { wl_display_cancel_read(wl_display); @@ -1024,7 +1020,14 @@ Java_sun_awt_wl_WLToolkit_readEvents return sun_awt_wl_WLToolkit_READ_RESULT_ERROR; } - // Transform the data read by the above call into events on the corresponding queues of the display. + const bool hasMoreData = (rc & POLLIN); + if (!hasMoreData) { + wl_display_cancel_read(wl_display); + return sun_awt_wl_WLToolkit_READ_RESULT_FINISHED_NO_EVENTS; + } + + // Read new data from Wayland and transform them into events + // on the corresponding queues of the display. rc = wl_display_read_events(wl_display); if (rc == -1) { // display disconnect has likely happened return sun_awt_wl_WLToolkit_READ_RESULT_ERROR; @@ -1216,7 +1219,7 @@ Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls) void awt_output_flush() { - wl_flush_to_server(getEnv()); + wlFlushToServer(getEnv()); } static void diff --git a/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.h b/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.h index 6a66a4c3bcc..e6f43c5a3e3 100644 --- a/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.h +++ b/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.h @@ -55,6 +55,6 @@ extern uint32_t last_pointer_enter_serial; JNIEnv *getEnv(); -int wl_flush_to_server(JNIEnv* env); +int wlFlushToServer(JNIEnv* env); struct wl_shm_pool *CreateShmPool(size_t size, const char *name, void **data); |