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 committed Nov 9, 2024
1 parent d30571a commit 4bc5322
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* 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;

import org.eclipse.swt.widgets.*;

/**
* 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 abstract class AsyncReadyCallback {
/**
* This method is responsible for initializes the asynchronous operation
*
* @param callback The callback address to execute when the operation is
* complete.
*/
protected abstract 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.
*/
protected abstract long await(long result);

/**
* This method executes the asynchronous operation and blocks until it has
* completed.
*
* @param display The display used for blocking.
* @return The result of the asynchronous operation.
*/
public final long run(Display display) {
return SyncDialogUtil.run(display, this::async , this::await);
}
}
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 = new AsyncReadyCallback() {
@Override
protected void async(long result) {
GTK4.gtk_file_dialog_select_folder(handle, shellHandle, 0, result, 0);
}

@Override
protected long await(long result) {
return GTK4.gtk_file_dialog_select_folder_finish(handle, result, null);
}
}.run(display);
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 = new AsyncReadyCallback() {
@Override
protected void async(long callback) {
GTK4.gtk_file_dialog_open_multiple(handle, shellHandle, 0, callback, 0);
}

@Override
protected long await(long result) {
return GTK4.gtk_file_dialog_open_multiple_finish(handle, result, null);
}
}.run(display);
} 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 = new AsyncReadyCallback() {
@Override
protected void async(long callback) {
GTK4.gtk_file_dialog_save(handle, shellHandle, 0, callback, 0);
}

@Override
protected long await(long result) {
return GTK4.gtk_file_dialog_save_finish(handle, result, null);
}
}.run(display);
} 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 = new AsyncReadyCallback() {
@Override
protected void async(long callback) {
GTK4.gtk_file_dialog_open(handle, shellHandle, 0, callback, 0);
}

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

0 comments on commit 4bc5322

Please sign in to comment.