Skip to content

Commit

Permalink
[GTK4] Cleanup execution of non-blocking dialog calls
Browse files Browse the repository at this point in the history
This adds a new AsyncReadyCallback class which is used to handle the
asynchronous execution of dialogs. The goal is provide a cleaner and
more readable interface than what is currently available by
SyncDialogUtil.

Note that this class currently simply wraps the call to SyncDialogUtil.
But once all of the remaining dialogs (Color/Font/MessageDialog) have
been migrated, it might make sense to remove this class entirely to
avoid this additional indirection.

Follow-up to 2e61b4b
  • Loading branch information
ptziegler authored and akurtakov committed Nov 27, 2024
1 parent 45405e5 commit 2cc00b7
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2024 Patrick Ziegler and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Patrick Ziegler - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.internal;

/**
* This class implements the GIO AsyncReadyCallback type and is used to
* transform an asynchronous {@code async} and synchronous {@code await}
* operation into a single synchronous {@code run} operation.
*/
public interface AsyncReadyCallback {
/**
* This method is responsible for initializes the asynchronous operation
*
* @param callback The callback address to execute when the operation is
* complete.
*/
void async(long callback);

/**
* This method is called from within the callback function in order to
* finish the executed operation and to return the result.
*
* @param result The generic, asynchronous function result.
* @return The specific result of the operation.
*/
long await(long result);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public class SyncDialogUtil {
* therefore essential that callers use the address of the {@link Callback}
* as address for the {@code AsyncReadyCallback} object.
*/
static public long run(Display display, Consumer<Long> asyncOpen, Function<Long, Long> asyncFinish) {
static public long run(Display display, AsyncReadyCallback callback) {
initializeResponseCallback();

dialogAsyncFinish = asyncFinish;
asyncOpen.accept(dialogResponseCallback.getAddress());
dialogAsyncFinish = callback::await;
callback.async(dialogResponseCallback.getAddress());

while (!display.isDisposed()) {
if (dialogAsyncValue != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,17 @@ Optional<String> openNativeChooserDialog () {
int response;
long file = 0;
if (GTK.GTK4) {
file = SyncDialogUtil.run(display,
asyncCallback -> GTK4.gtk_file_dialog_select_folder(handle, shellHandle, 0, asyncCallback, 0),
asyncResult -> GTK4.gtk_file_dialog_select_folder_finish(handle, asyncResult, null));
file = SyncDialogUtil.run(display, new AsyncReadyCallback() {
@Override
public void async(long result) {
GTK4.gtk_file_dialog_select_folder(handle, shellHandle, 0, result, 0);
}

@Override
public long await(long result) {
return GTK4.gtk_file_dialog_select_folder_finish(handle, result, null);
}
});
response = file != 0 ? GTK.GTK_RESPONSE_ACCEPT : GTK.GTK_RESPONSE_CANCEL;
} else {
display.externalEventLoop = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,18 +404,42 @@ Optional<String> openNativeChooserDialog () {
long file = 0;
if (GTK.GTK4) {
if ((style & SWT.MULTI) != 0) {
file = SyncDialogUtil.run(display,
asyncCallback -> GTK4.gtk_file_dialog_open_multiple(handle, shellHandle, 0, asyncCallback, 0),
asyncResult -> GTK4.gtk_file_dialog_open_multiple_finish(handle, asyncResult, null));
file = SyncDialogUtil.run(display, new AsyncReadyCallback() {
@Override
public void async(long callback) {
GTK4.gtk_file_dialog_open_multiple(handle, shellHandle, 0, callback, 0);
}

@Override
public long await(long result) {
return GTK4.gtk_file_dialog_open_multiple_finish(handle, result, null);
}
});
} else {
if ((style & SWT.SAVE) != 0) {
file = SyncDialogUtil.run(display,
asyncCallback -> GTK4.gtk_file_dialog_save(handle, shellHandle, 0, asyncCallback, 0),
asyncResult -> GTK4.gtk_file_dialog_save_finish(handle, asyncResult, null));
file = SyncDialogUtil.run(display, new AsyncReadyCallback() {
@Override
public void async(long callback) {
GTK4.gtk_file_dialog_save(handle, shellHandle, 0, callback, 0);
}

@Override
public long await(long result) {
return GTK4.gtk_file_dialog_save_finish(handle, result, null);
}
});
} else {
file = SyncDialogUtil.run(display,
asyncCallback -> GTK4.gtk_file_dialog_open(handle, shellHandle, 0, asyncCallback, 0),
asyncResult -> GTK4.gtk_file_dialog_open_finish(handle, asyncResult, null));
file = SyncDialogUtil.run(display, new AsyncReadyCallback() {
@Override
public void async(long callback) {
GTK4.gtk_file_dialog_open(handle, shellHandle, 0, callback, 0);
}

@Override
public long await(long result) {
return GTK4.gtk_file_dialog_open_finish(handle, result, null);
}
});
}
}
response = file != 0 ? GTK.GTK_RESPONSE_ACCEPT : GTK.GTK_RESPONSE_CANCEL;
Expand Down

0 comments on commit 2cc00b7

Please sign in to comment.