RFR: 8334868: Ensure CheckUninstallModalHook is called in WPageDialogPeer._show
Alisen Chung
achung at openjdk.org
Wed Jun 26 23:45:09 UTC 2024
On Wed, 26 Jun 2024 23:37:48 GMT, Alisen Chung <achung at openjdk.org> wrote:
>> This is somewhat a continuation for [JDK-8307160](https://bugs.openjdk.org/browse/JDK-8307160) and [JDK-8334509](https://bugs.openjdk.org/browse/JDK-8334509).
>>
>> The former removed the `doIt` flag in #18584, but it introduced a regression.
>> The regression is resolved by the latter in #19786, and it added the 'doIt' flag again.
>>
>> I think using a flag makes the code less clear. When reading the code, one has to keep track of the current value of the `doIt` flag.
>>
>> I raised my concern in [comments in PR 19786](https://github.com/openjdk/jdk/pull/19786#discussion_r1649191308):
>>
>>> I'd rather keep `JNI_FALSE` here — it's more explicit and therefore clearer. You don't have to keep track of the value of `doIt` flag while reading the code.
>>>
>>> In fact, I'd prefer no `doIt` flag at all… yet it makes handling the code below `if (ret)` slightly harder.
>>
>> I came up with a solution which simplifies handling the clean-up. The solution relies on C++ destructors which are called when the declared objects go out of scope.
>>
>> The C++ object wraps a lambda function to clean up and invokes this function in its destructor. Such C++ class has to be a templated class because there's no defined type to represent a lambda. The class has to be declared at the top of the file because it needs C++ linkage.
>>
>> There are two `Cleaner` objects declared in the code of `Java_sun_awt_windows_WPageDialogPeer__1show`:
>>
>> **`refCleaner`** is declared right after all the references to Java objects are initialised. The corresponding `refCleanup` lambda deletes all the references and replaces the `CLEANUP_SHOW` macro. Before JDK-8307160, the code jumped to a go-to label to perform the clean-up.
>>
>> **`postCleaner`** is declared after `AwtDialog::CheckInstallModalHook` is called. Its lambda `postCleanup` uninstalls the modal hook and handles focus transfer as well as saves the updated printer parameters.
>>
>> It is `postCleaner` that resolves the bug JDK-8334868 by ensuring `CheckUninstallModalHook` and `ModalActivateNextWindow` are called if `::PageSetupDlg` is called.
>>
>> As the result of using `refCleaner`, all the `return` statements in the function use an explicit value, which makes the code cleaner. There's no need to use a `go to` statement or insert a macro to delete references to Java objects, about which one had to remember — the destructor of the `refCleaner` handles deleting references when `refCleaner` goes out of scope, that is when the function returns.
>
> src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp line 640:
>
>> 638: HGLOBAL oldG = AwtPrintControl::getPrintHDMode(env, self);
>> 639: if (setup.hDevMode != oldG) {
>> 640: AwtPrintControl::setPrintHDMode(env, self, setup.hDevMode);
>
> what does setPrintHDMode and setPrintHDName do? do they need to be called as part of cleanup even if there is an exception and we return JNI_FALSE?
i think this code preserves the printer settings after the dialog closes (and only on success before this fix), so is it possible in the case the printer is removed and causes an exception, we shouldn't preserve these settings?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/19867#discussion_r1655642352
More information about the client-libs-dev
mailing list