Skip to content
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

JDK-8311113: Remove invalid pointer cast and clean up setLabel() in awt_MenuItem.cpp #15276

Closed
wants to merge 9 commits into from

Conversation

honkar-jdk
Copy link
Contributor

@honkar-jdk honkar-jdk commented Aug 14, 2023

In awt_MenuItem.cpp (712,22): mii.dwTypeData = (LPTSTR)(*sb) produces invalid pointer cast warning when complied on clang and moreover this is a no-op.

mii.dwTypeData is used only when MIIM_STRING flag is set in the fMask (as per Docs), which is not the case in JDK Ln#705. Hence the assignment mii.dwTypeData = (LPTSTR)(*sb) is not required and so is the label parameter. Additionally necessary cleanup is done at the following places -

  • WMenuItemPeer.java - to the native function call
  • awt_MenuItem.cpp - WMenuItemPeer__1setLabel() ,_SetLabel(), SetLabel()
  • awt_MenuItem.h

Added a test which checks setLabel() functionality on Menu, MenuItem and PopupMenu.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8311113: Remove invalid pointer cast and clean up setLabel() in awt_MenuItem.cpp (Bug - P4)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/15276/head:pull/15276
$ git checkout pull/15276

Update a local copy of the PR:
$ git checkout pull/15276
$ git pull https://git.openjdk.org/jdk.git pull/15276/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 15276

View PR using the GUI difftool:
$ git pr show -t 15276

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/15276.diff

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Aug 14, 2023

👋 Welcome back honkar! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Aug 14, 2023
@openjdk
Copy link

openjdk bot commented Aug 14, 2023

@honkar-jdk The following label will be automatically applied to this pull request:

  • client

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the client client-libs-dev@openjdk.org label Aug 14, 2023
@mlbridge
Copy link

mlbridge bot commented Aug 14, 2023

Webrevs

@honkar-jdk honkar-jdk changed the title JDK-8311113: [Win] Remove invalid pointer cast and clean up setLabel() in awt_MenuItem.cpp JDK-8311113: Remove invalid pointer cast and clean up setLabel() in awt_MenuItem.cpp Aug 14, 2023
@mrserb
Copy link
Member

mrserb commented Aug 16, 2023

Please double-check how the external tools like jaws/narrator will work after this change, will they be able to read the correct content of the menu item?

@aivanov-jdk
Copy link
Member

I would also add that the pointer saved to mii.dwTypeData becomes invalid as soon as m->SetLabel(labelPtr) returns because the code in _SetLabel releases the pointer labelPtr.

Essentially, this was the code flow in _SetLabel:

LPCTSTR labelPtr = JNU_GetStringPlatformChars(env, label, 0);
m->SetLabel(labelPtr);
JNU_ReleaseStringPlatformChars(env, label, labelPtr);

If any code had dereferenced the pointer stored for a menu item in dwTypeData, the process would've crashed with access violation, or it could've led to a memory corruption.

@@ -709,7 +708,6 @@ void AwtMenuItem::SetLabel(LPCTSTR sb)
::GetMenuItemInfo(hMenu, GetID(), FALSE, &mii);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update the fMask to use MIIM_FTYPE instead of MIIM_TYPE? The latter requests both fType and dwTypeData whereas the former requests only fType, as we don't use dwTypeData.

(I understand that this code was written before Windows introduced new values for fMask field, which probably happened in Windows 98. Now we can update the code to document our intentions clearer.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated fMask to use MIIM_FTYPE

test/jdk/java/awt/MenuItem/SetLabelTest.java Outdated Show resolved Hide resolved
test/jdk/java/awt/MenuItem/SetLabelTest.java Outdated Show resolved Hide resolved
test/jdk/java/awt/MenuItem/SetLabelTest.java Outdated Show resolved Hide resolved
Comment on lines 149 to 161
private static boolean checkLabels() {
for (int i = 0; i < 2; i++) {
Menu m1 = mb.getMenu(i);
String menuLabel = m1.getLabel();
String menuItemLabel = m1.getItem(0).getLabel();
if (!(menuLabel.equals(newLabels[i][0])
&& menuItemLabel.equals(newLabels[i][1]))) {
passed = false;
break;
}
}
return passed;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern here is that the test doesn't ensure that the menu has updated on the screen.

The data inside the Java object are always updated?

The test should probably make a screenshot before a label is changed, then make a screenshot after the label is changed — there should be differences on the screenshots.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test updated to compare after and before screenshots.

test/jdk/java/awt/MenuItem/SetLabelTest.java Show resolved Hide resolved
test/jdk/java/awt/MenuItem/SetLabelTest.java Outdated Show resolved Hide resolved
@honkar-jdk
Copy link
Contributor Author

@mrserb

Please double-check how the external tools like jaws/narrator will work after this change, will they be able to read the correct content of the menu item?

The updating of the label works correctly since the application handles the drawing/updating of the string as specified by the mii.fType = MFT_OWNERDRAW without requiring to set dwTypeData. To double-check ran JAWS and it works as expected & reads out the new label name when updated.

@honkar-jdk
Copy link
Contributor Author

@aivanov-jdk @mrserb Please review updated changes.

@prrace
Copy link
Contributor

prrace commented Aug 30, 2023

I would also add that the pointer saved to mii.dwTypeData becomes invalid as soon as m->SetLabel(labelPtr) returns because the code in _SetLabel releases the pointer labelPtr.

Essentially, this was the code flow in _SetLabel:

LPCTSTR labelPtr = JNU_GetStringPlatformChars(env, label, 0);
m->SetLabel(labelPtr);
JNU_ReleaseStringPlatformChars(env, label, labelPtr);

If any code had dereferenced the pointer stored for a menu item in dwTypeData, the process would've crashed with access violation, or it could've led to a memory corruption.

I don't think that's relevant. "mii" is stack allocated and the code does
::InsertMenuItem(hMenu, idx, TRUE, &mii);

and this pattern occurs in other places too.

So I conclude that - although it isn't documented SFAICS - that GDI deep copies what it needs out of the struct.

@prrace
Copy link
Contributor

prrace commented Aug 30, 2023

@mrserb

Please double-check how the external tools like jaws/narrator will work after this change, will they be able to read the correct content of the menu item?

The updating of the label works correctly since the application handles the drawing/updating of the string as specified by the mii.fType = MFT_OWNERDRAW without requiring to set dwTypeData. To double-check ran JAWS and it works as expected & reads out the new label name when updated.

Hmm, so where does JAWS get that info if we no longer set it ? It isn't scraping pixels and doing OCR.

Seems like a lot of changes here to silence a warning we don't even get.

@aivanov-jdk
Copy link
Member

aivanov-jdk commented Aug 30, 2023

I would also add that the pointer saved to mii.dwTypeData becomes invalid as soon as m->SetLabel(labelPtr) returns because the code in _SetLabel releases the pointer labelPtr.

Essentially, this was the code flow in _SetLabel:

LPCTSTR labelPtr = JNU_GetStringPlatformChars(env, label, 0);
m->SetLabel(labelPtr);
JNU_ReleaseStringPlatformChars(env, label, labelPtr);

If any code had dereferenced the pointer stored for a menu item in dwTypeData, the process would've crashed with access violation, or it could've led to a memory corruption.

I don't think that's relevant. "mii" is stack allocated and the code does ::InsertMenuItem(hMenu, idx, TRUE, &mii);

and this pattern occurs in other places too.

So I conclude that - although it isn't documented SFAICS - that GDI deep copies what it needs out of the struct.

Yes, I was wrong. I realised it later after I looked at the docs more.

The description of the MENUITEMINFOW says, To retrieve a menu item of type MFT_STRING, first find the size of the string by setting the dwTypeData member of MENUITEMINFO to NULL and then calling GetMenuItemInfo. This implies the menu string is stored in the Window Manager.

Yet this applies to menus of type MFT_STRING, and AWT menus are of type MFT_OWNERDRAW.

@aivanov-jdk
Copy link
Member

aivanov-jdk commented Aug 30, 2023

Please double-check how the external tools like jaws/narrator will work after this change, will they be able to read the correct content of the menu item?

The updating of the label works correctly since the application handles the drawing/updating of the string as specified by the mii.fType = MFT_OWNERDRAW without requiring to set dwTypeData. To double-check ran JAWS and it works as expected & reads out the new label name when updated.

Hmm, so where does JAWS get that info if we no longer set it ? It isn't scraping pixels and doing OCR.

Isn't JAWS using Accessible interfaces?

@prrace The string has never been set because AWT menus aren't of MFT_STRING type.

When a new menu item is added to menu, we use AppendMenuW:

LPCTSTR itemInfo = (LPCTSTR) this;
if (_tcscmp(item->GetClassName(), TEXT("SunAwtMenu")) == 0) {
flags |= MF_POPUP;
itemInfo = (LPCTSTR) item;
}
VERIFY(::AppendMenu(GetHMenu(), flags, item->GetID(), itemInfo));

The last parameter passed to the AppendMenuW is itemInfo, its value is either this or a pointer AwtMenuItem* passed to the AddItem method.

So, the string value of a menu item is never set if setLabel is never called.

The code above confusingly “sets” the MF_STRING flag:

UINT flags = MF_STRING | (enabled ? MF_ENABLED : MF_GRAYED);
flags |= MF_OWNERDRAW;

which is overridden by the MF_OWNERDRAW.

Because the value of MF_STRING is 0, it cannot be combined with MF_BITMAP or MF_OWNERDRAW. Thus the menu is a regular string menu if and only if neither MF_BITMAP or MF_OWNERDRAW are set, which is never true for AWT menus because MF_OWNERDRAW is always set.

The above holds true for the flags in MENUITEMINFOW structure.

Seems like a lot of changes here to silence a warning we don't even get.

Even though we don't get this warning, the value set to mii.dwTypeData has no meaning, neither to the OS nor to AWT.

I strongly think that we should remove the code which copies the string label because it's never used.

@mrserb
Copy link
Member

mrserb commented Aug 30, 2023

Isn't JAWS using Accessible interfaces?

What about Narrator? I think it will use the actuall data from the windows, same as for other "native" awt components. Unlike JAWS which know how to use our internal a11y interface.

@honkar-jdk
Copy link
Contributor Author

Isn't JAWS using Accessible interfaces?

What about Narrator? I think it will use the actuall data from the windows, same as for other "native" awt components. Unlike JAWS which know how to use our internal a11y interface.

Checked with Narrator and JAWS. It works the same in both cases - with and without the changes.

In case of JAWS, it reads out label names as in "Item-1" and the changed labels "New Item-1".
In case of narrator, it announces just the component name as in "Menu" , "Menu item" and not the label name itself and it works the same with and without the changes.

@honkar-jdk
Copy link
Contributor Author

honkar-jdk commented Aug 31, 2023

Hmm, so where does JAWS get that info if we no longer set it ? It isn't scraping pixels and doing OCR.

I'll have to check this further.

@mrserb
Copy link
Member

mrserb commented Aug 31, 2023

I'll have to check this further

It will get it via javaaccessbridge we provided(kind of native interface) and this native lib uses our a11y java code for each component.

@aivanov-jdk
Copy link
Member

@mrserb @prrace If the string label was stored in the menu structure by Windows, we could retrieve it, right? Let's do it.

I applied the following patch to the original awt_MenuItem.cpp:

diff --git a/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp b/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp
index 69a7f4606e2..ccdc82c63f5 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp
@@ -34,6 +34,7 @@
 #include <tchar.h>
 #include <imm.h>
 #include <ime.h>
+#include <stdio.h>
 // End -- Win32 SDK include files

 //add for multifont menuitem
@@ -685,6 +686,51 @@ void AwtMenuItem::DoCommand()
     }
 }

+static void PrintMenuItemInfo(HMENU hMenu, UINT id)
+{
+    MENUITEMINFO mii;
+
+    memset(&mii, 0, sizeof(MENUITEMINFO));
+    mii.cbSize = sizeof(MENUITEMINFO);
+    mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID
+              | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
+
+    if (!::GetMenuItemInfo(hMenu, id, FALSE, &mii)) {
+        wprintf(L"GetMenuItemInfo returned an error for %u, %p\n", id, hMenu);
+        return;
+    }
+
+    wprintf(L"Menu info for %u, %p\n", id, hMenu);
+    wprintf(L"    dwItemData = %p\n", (void *) mii.dwItemData);
+    wprintf(L"    cch = %u\n", mii.cch);
+    wprintf(L"    dwTypeData = %p\n", mii.dwTypeData);
+    if (mii.cch > 0) {
+        mii.dwTypeData = new TCHAR[mii.cch + 1];
+        if (!::GetMenuItemInfo(hMenu, id, FALSE, &mii)) {
+            wprintf(L"    failed to get label\n");
+        } else {
+            wprintf(L"    label = %s\n", mii.dwTypeData);
+        }
+        delete[] mii.dwTypeData;
+    }
+
+    // fType
+    wprintf(L"    fType = %x = ", mii.fType);
+    if (mii.fType & MFT_OWNERDRAW) {
+        wprintf(L"MFT_OWNERDRAW ");
+    }
+    if (mii.fType & MFT_BITMAP) {
+        wprintf(L"MFT_BITMAP ");
+    }
+    if ((mii.fType & (MFT_OWNERDRAW | MFT_BITMAP)) == 0) {
+        wprintf(L"MFT_STRING ");
+    }
+    if (mii.fType & MFT_SEPARATOR) {
+        wprintf(L"MFT_SEPARATOR ");
+    }
+    wprintf(L"\n");
+}
+
 void AwtMenuItem::SetLabel(LPCTSTR sb)
 {
     AwtMenu* menu = GetMenuContainer();
@@ -700,6 +746,13 @@ void AwtMenuItem::SetLabel(LPCTSTR sb)
     HMENU hMenu = menu->GetHMenu();
     MENUITEMINFO mii, mii1;

+    wprintf(L"AwtMenuItem::SetLabel(this = %p, id = %u, hMenu = %p\n",
+            this, GetID(), hMenu);
+    wprintf(L"> Before\n");
+    PrintMenuItemInfo(hMenu, GetID());
+    wprintf(L"< Before\n");
+
+
     // get full information about menu item
     memset(&mii, 0, sizeof(MENUITEMINFO));
     mii.cbSize = sizeof(MENUITEMINFO);
@@ -725,6 +778,10 @@ void AwtMenuItem::SetLabel(LPCTSTR sb)
     ::RemoveMenu(hMenu, idx, MF_BYPOSITION);
     ::InsertMenuItem(hMenu, idx, TRUE, &mii);

+    wprintf(L"> After\n");
+    PrintMenuItemInfo(hMenu, GetID());
+    wprintf(L"< After\n");
+
     RedrawMenuBar();
 }

By running Harshitha's test, I get the following output:

AwtMenuItem::SetLabel(this = 000001F97CA87F50, id = 131645, hMenu = 0000000000030239
> Before
Menu info for 131645, 0000000000030239
    dwItemData = 000001F97CA87F50
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< Before
> After
Menu info for 131645, 0000000000030239
    dwItemData = 000001F97CA87F50
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< After

AwtMenuItem::SetLabel(this = 000001F97CA87EE0, id = 0, hMenu = 000000000002023D
> Before
Menu info for 0, 000000000002023D
    dwItemData = 000001F97CA87F50
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< Before
> After
Menu info for 0, 000000000002023D
    dwItemData = 000001F97CA87F50
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< After

AwtMenuItem::SetLabel(this = 000001F97CA88490, id = 2, hMenu = 000000000002023D
> Before
Menu info for 2, 000000000002023D
    dwItemData = 000001F97CA87F50
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< Before
> After
Menu info for 2, 000000000002023D
    dwItemData = 000001F97CA87F50
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< After

AwtMenuItem::SetLabel(this = 000001F97CA88730, id = 3, hMenu = 000000000002019F
> Before
Menu info for 3, 000000000002019F
    dwItemData = 000001F97D5413B0
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< Before
> After
Menu info for 3, 000000000002019F
    dwItemData = 000001F97D5413B0
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< After

AwtMenuItem::SetLabel(this = 000001F97CA89300, id = 5, hMenu = 000000000002019F
> Before
Menu info for 5, 000000000002019F
    dwItemData = 000001F97D5413B0
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< Before
> After
Menu info for 5, 000000000002019F
    dwItemData = 000001F97D5413B0
    cch = 0
    dwTypeData = 0000000000000000
    fType = 100 = MFT_OWNERDRAW 
< After

As you can see, in all the cases, the cch member of the MENUITEMINFO is zero — the string label cannot be retrieved. The before cases are expected to have no string data because AppendMenu doesn't allow setting it, I explained it above. Yet the after case can't still retrieve the string label even though we went through the hoops to set it.

This proves what's done in _SetLabel is dead code: it's not used by us, it's not used by the OS. Removing more than 100 lines which essentially do nothing is a good thing in my opinion.

@aivanov-jdk
Copy link
Member

As for MIIM_TYPE: the flag sets or retrieves both fType and dwTypeData members. In Windows 95, the MENUITEMINFO structure was shorter, the dwTypeData field was a string if menu item is of type MFT_STRING (this implies neither MFT_BITMAP nor MFT_OWNERDRAW are set), it was an HBITMAP if the type is MFT_BITMAP. If the menu type is MFT_OWNERDRAW, the dwTypeData member contains an application-defined value. However, as we can see, it's not preserved.

Windows 98 added new members to the MENUITEMINFO structure. It allowed combining both MFT_STRING and MFT_BITMAP at the same time, which allows displaying a bitmap icon next to a string label. This feature is actively used by Windows to these days in the window system menu which you can access by left-clicking the app icon in the window title bar or by right-clicking the window title bar: the icons that you see next to Restore, Minimize, Maximize, and Close are displayed by combining MFT_STRING | MFT_BITMAP.

At the same time, MIIM_TYPE was replaced by more specific mask flags MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING which set or retrieve a designated member of the MENUITEMINFO structure.

This is why we should switch to using MIIM_FTYPE mask flag which clearly indicates neither dwTypeData nor cch are used.

Copy link
Member

@aivanov-jdk aivanov-jdk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good to me.

test/jdk/java/awt/MenuItem/SetLabelTest.java Outdated Show resolved Hide resolved
test/jdk/java/awt/MenuItem/SetLabelTest.java Outdated Show resolved Hide resolved
@openjdk
Copy link

openjdk bot commented Aug 31, 2023

@honkar-jdk This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8311113: Remove invalid pointer cast and clean up setLabel() in awt_MenuItem.cpp

Reviewed-by: aivanov, serb

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 398 new commits pushed to the master branch:

  • 11d431b: 8316228: jcmd tests are broken by 8314828
  • eb37c7e: 8315971: ProblemList containers/docker/TestMemoryAwareness.java on linux-all
  • 23fab11: 8314828: Mark 3 jcmd command-line options test as vm.flagless
  • 1741d13: 8315726: Open source several AWT applet tests
  • 92ad4a2: 8315789: Minor HexFormat performance improvements
  • ce93d27: 6228794: java.text.ChoiceFormat pattern behavior is not well documented.
  • 3b0a6d2: 8314226: Series of colon-style fallthrough switch cases with guards compiled incorrectly
  • ff240a9: 8316087: Test SignedLoggerFinderTest.java is still failing
  • a731a24: 8315934: RISC-V: Disable conservative fences per vendor
  • b3dad24: 8316021: Serial: Remove unused Generation::post_compact
  • ... and 388 more: https://git.openjdk.org/jdk/compare/88b4e3b8539c2beb29ad92bd74b300002c2ef84b...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Aug 31, 2023
@honkar-jdk
Copy link
Contributor Author

@prrace The drawing of the label is being handled by the application here AwtMenuItem::DrawItem & AwtMenuItem::DrawSelf.

@prrace
Copy link
Contributor

prrace commented Aug 31, 2023

I'll have to check this further

It will get it via javaaccessbridge we provided(kind of native interface) and this native lib uses our a11y java code for each component.

Hmm, I didn't know the AWT heavyweights participated in that. Only the Swing components.
On mac, AWT components are implemented as LW so I can see it working there but not GDI.
Can someone confirm Sergey is correct ?

@prrace
Copy link
Contributor

prrace commented Aug 31, 2023

This proves what's done in _SetLabel is dead code: it's not used by us, it's not used by the OS. Removing more than 100 lines which essentially do nothing is a good thing in my opinion.

OK. So it doesn't pull it because we don't tell it it is there to be read.
Which does make it sound very much like JAWS is getting the data from somewhere else.

@honkar-jdk
Copy link
Contributor Author

honkar-jdk commented Aug 31, 2023

I'll have to check this further

It will get it via javaaccessbridge we provided(kind of native interface) and this native lib uses our a11y java code for each component.

Hmm, I didn't know the AWT heavyweights participated in that. Only the Swing components. On mac, AWT components are implemented as LW so I can see it working there but not GDI. Can someone confirm Sergey is correct ?

I see the two a11y native libraries - src/jdk.accessibility/windows/native/libjavaaccessbridge, src/jdk.accessibility/windows/native/libwindowsaccessbridge. But I'm missing the part on how AccessibleAWTMenuItem gets mapped to a11y functionality within the lib and where does JAWS obtain label name.

@aivanov-jdk
Copy link
Member

This proves what's done in _SetLabel is dead code: it's not used by us, it's not used by the OS. Removing more than 100 lines which essentially do nothing is a good thing in my opinion.

OK. So it doesn't pull it because we don't tell it it is there to be read.

It's a limitation of Windows Menu API: the system doesn't store any additional data for owner drawn menu items. We tell the system, here's the label, but it ignores it.

It seems there's nothing we can do about it.

I tried setting MIIM_FTYPE | MIIM_STRING in fMask which explicitly tells the system the dwTypeData member is valid. The system ignores it all the same, the label cannot be retrieved.

Which does make it sound very much like JAWS is getting the data from somewhere else.

There's no other way…

Hmm, I didn't know the AWT heavyweights participated in that. Only the Swing components.

It is also my understanding, so I was surprised JAWS can read AWT menus.

It is not a surprise Narrator can't read menus (or anything else in a Java app) since Java doesn't implement native Windows accessibility APIs.

@aivanov-jdk
Copy link
Member

Which does make it sound very much like JAWS is getting the data from somewhere else.

There's no other way…

Hmm, I didn't know the AWT heavyweights participated in that. Only the Swing components.

It is also my understanding, so I was surprised JAWS can read AWT menus.

Menu.java and MenuItem.java have Accessibility support sections where AccessibleAWTMenu and AccessibleAWTMenuItem classes are defined.

* Inner class of Menu used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* This class implements accessibility support for the
* {@code Menu} class. It provides an implementation of the
* Java Accessibility API appropriate to menu user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTMenu extends AccessibleAWTMenuItem

* Inner class of MenuItem used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* This class implements accessibility support for the
* {@code MenuItem} class. It provides an implementation of the
* Java Accessibility API appropriate to menu item user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTMenuItem extends AccessibleAWTMenuComponent

Thus AWT components implement the same accessibility interfaces that Swing components do. JAWS uses these interfaces. Mystery solved.

Copy link
Member

@mrserb mrserb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine if the a11y things works fine, we probably can check for a possible cleanups in other places we use ownerdraw logic.

@honkar-jdk
Copy link
Contributor Author

honkar-jdk commented Sep 18, 2023

Looks fine if the a11y things works fine, we probably can check for a possible cleanups in other places we use ownerdraw logic.

I will be creating a separate issue to handle cleanup at other places.

@honkar-jdk
Copy link
Contributor Author

/integrate

@openjdk
Copy link

openjdk bot commented Sep 19, 2023

Going to push as commit 0c97246.
Since your change was applied there have been 483 commits pushed to the master branch:

  • d2b2f67: 8315952: Open source several Swing JToolbar JTooltip JTree tests
  • 5f6cee8: 8316056: Open source several Swing JTree tests
  • b685ee0: 8314830: runtime/ErrorHandling/ tests ignore external VM flags
  • e0f8d16: 8314829: serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java ignores vm flags
  • 7b1e2bf: 8315415: OutputAnalyzer.shouldMatchByLine() fails in some cases
  • da57d2a: 8308592: Framework for CA interoperability testing
  • a6d120d: 8316513: Serial: Remove unused invalidate_remembered_set
  • 607bd4e: 8316294: AIX: Build fopen system call fails on file _BUILD_LIBJDWP_objectfilenames.txt
  • f25c920: 8314774: Optimize URLEncoder
  • 7c5f2a2: 8315669: Open source several Swing PopupMenu related tests
  • ... and 473 more: https://git.openjdk.org/jdk/compare/88b4e3b8539c2beb29ad92bd74b300002c2ef84b...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Sep 19, 2023
@openjdk openjdk bot closed this Sep 19, 2023
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Sep 19, 2023
@openjdk
Copy link

openjdk bot commented Sep 19, 2023

@honkar-jdk Pushed as commit 0c97246.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client client-libs-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

4 participants