Skip to content

8207333: [Linux, macOS] Column sorting is triggered always after context menu request on table header #1754

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

jperedadnr
Copy link
Collaborator

@jperedadnr jperedadnr commented Apr 1, 2025

Note: The JBS issue JDK-8207333 refers to Linux, but it happens on macOS too.

When a TableColumn has a ContextMenu, if the user right clicks on the tableColumnHeader, the ContextMenu shows up, but, as described on the issue, on macOS and Linux, the table gets sorted as well.

Currently, TableColumnHeader#mouseReleasedHandler checks for MouseEvent::isPopupTriggered, but it doesn't have a check on mousePressed. However, it can be seen that a right click on the header has the following values for MouseEvent:: isPopupTriggered on the different platforms and mouse pressed and released events:

isPopupTriggered on: Windows macOS Linux
mousePressed false true true
mouseReleased true false false 

Also, the JavaDoc for MouseEvent::isPopupTriggered clearly states that:

Note: Popup menus are triggered differently on different systems. Therefore, popupTrigger should be checked in both onMousePressed and mouseReleased for proper cross-platform functionality.

Therefore, this PR adds a check to MouseEvent::isPopupTrigger in the mouse pressed event, that can be used later on to cancel the header sorting when the mouse released event happens.

Also a system test has been added. It fails on macOS and Linux, and passes on Windows before this PR, and passes on the three platforms with this PR.


Progress

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

Issue

  • JDK-8207333: [Linux, macOS] Column sorting is triggered always after context menu request on table header (Bug - P4)

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 1754

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

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1754.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Apr 1, 2025

👋 Welcome back jpereda! 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
Copy link

openjdk bot commented Apr 1, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot added the rfr Ready for review label Apr 1, 2025
@mlbridge
Copy link

mlbridge bot commented Apr 1, 2025

Webrevs

@andy-goryachev-oracle
Copy link
Contributor

I'll take a look.
Should we update the JBS and this PR title to remove [linux] as it applies to both platforms?

@andy-goryachev-oracle
Copy link
Contributor

I can only test it on macOS and Windows. Could someone with a linux system help please?
/reviewers 2

@openjdk
Copy link

openjdk bot commented Apr 1, 2025

@andy-goryachev-oracle
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

Copy link
Contributor

@andy-goryachev-oracle andy-goryachev-oracle left a comment

Choose a reason for hiding this comment

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

thank you for fixing this bug, @jperedadnr !

testing with the monkey tester looks good on macOS 15.3.2 and windows 11.

@jperedadnr jperedadnr changed the title 8207333: [linux] Column sorting is triggered always after context menu request on table header 8207333: [Linux, macOS] Column sorting is triggered always after context menu request on table header Apr 1, 2025
@andy-goryachev-oracle
Copy link
Contributor

andy-goryachev-oracle commented Apr 7, 2025

@Ziad-Mid could you be the second reviewer?

@Ziad-Mid
Copy link
Contributor

Ziad-Mid commented Apr 8, 2025

@Ziad-Mid could you be the second reviewer?

I can't test on Linux , I will check same for macOS

@@ -243,6 +245,7 @@ public TableColumnHeader(final TableColumnBase tc) {
}

if (me.isConsumed()) return;
popupTriggeredOnMousePressed = me.isPopupTrigger();
me.consume();

header.getTableHeaderRow().columnDragLock = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

On Mac a context menu can be invoked using the right button or the left button in conjunction with the Control key. In the second case the pop trigger flag will be set and the primary button will be down. If I'm reading the code correctly this could get the header stuck in column re-ordering mode.

Copy link
Contributor

Choose a reason for hiding this comment

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

Testing on macOS 15.3.2, it does not get stuck when using control+left-click, works as expected.

There is one (existing and unrelated) problem - if the user tries to dismiss the popup menu by clicking on the header, it dismisses the popup (correctly), but then proceeds to re-sort the table (unexpected).

One can say it works as designed, since the click falls on a header cell and the expected operation is to toggle the sorting, with the side effect of dismissing the popup.

On the other hand, Excel (both mac and windows) behaves differently - a click on the spreadsheet header dismisses the popup and does not select the column, as it normally does when no popup is present.

What do you guys think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

control+left-click works as expected for me too.

When the context menu is showing, clicking anywhere outside of it, closes the popup (because of the autohide property), but doesn't consume the event. If you click on a button, for instance, it will be fired. In any case, this is the same before and after this PR, so maybe an issue for a later discussion.

Copy link
Contributor

Choose a reason for hiding this comment

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

definitely an unrelated issue, I just wanted to ask whether you guys think it crosses the threshold for a bug.

Copy link
Contributor

Choose a reason for hiding this comment

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

control+left-click works as expected for me too.

For control+left-click it looks like the code will call columnReordingStarted but on the released event it won't call columnReorderingComplete. I have no idea if this will lead to problems or not.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@beldenfox Do you think we should address that issue (ctrl+left click + columnReordering) in this PR? Else, do we need to do anything else to move it forward?

Copy link
Contributor

Choose a reason for hiding this comment

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

You should be good with a few tweaks. If the press event is a popup trigger don't set the columnDragLock or call columnReorderingStarted (since you might not get a release event). In the drag handler check popupTriggeredOnMousePressed and do nothing if it's set. Your released handler looks fine as-is. I think that should cover it.

By the way, in a perfect world you would have more predictable behavior. When the popup menu is shown it would grab the mouse pointer and you would never see the release event. That would allow the user to click to bring up the popup and start dragging across the menu items without having to release the mouse.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, @beldenfox! I've included your suggestions, and also added the ctrl+left click macOS case to the test.

@@ -271,7 +274,10 @@ public TableColumnHeader(final TableColumnBase tc) {
TableColumnHeader header = (TableColumnHeader) me.getSource();
header.getTableHeaderRow().columnDragLock = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

On Ubuntu 22.04 the table column header is not receiving a mouse released event if a context menu is shown. Not sure where the released event is going but it's not to any node on the primary stage. The docs are vague on this but this looks like a separate bug that's making it hard to test this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

what happens in the master branch (without this PR's changes)?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was having trouble reproducing the original bug on the master branch; the sorting is done when the mouse is released and most of the time that event never arrives (I think it does every now and then).

Copy link
Contributor

Choose a reason for hiding this comment

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

this is strange - the bug is immediately apparent. which macOS version do you have? although I don't think the version matters.

I am testing with an external mouse, with control-left-click, and with the double-finger-click gesture on the trackpad.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was having problems reproducing on Linux. No problem reproducing on macOS.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

On Linux I have some issues too: the test that I attached to the JBS issue doesn't fail for me on Linux, but the test that I added to this PR does fail without the fix.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you try the monkey tester? it allows setting properties on the table view / table column at runtime...

Copy link
Contributor

Choose a reason for hiding this comment

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

I just verified that on Linux the released event usually goes to the popup window. Basically it's whatever window is under the cursor at the time; if I move the mouse fast enough it may go to a node on the primary stage. I don't think this is our doing, it's how GTK is delivering the event.

On the JavaFX side I'm not sure this counts as a bug. The docs state that entered and released events should arrive in pairs during drag and drop operations but doesn't address this case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The Monkey tester app works for me on Linux (Ubuntu 22.04, either mouse or pad), before and after this PR (so I can't reproduce the issue there, as I mentioned, though the test added to the PR fails without the patch).

@openjdk openjdk bot removed the rfr Ready for review label Apr 28, 2025
@andy-goryachev-oracle
Copy link
Contributor

Some tests in TableColumnHeaderTest are failing in CI.

@jperedadnr
Copy link
Collaborator Author

Indeed... this test fails: TableColumnHeaderTest::testColumnRightClickDoesAllowResizingWhenConsumed.

It has this JavaDoc:

/**
     * When a right click is done on a table column header and consumed by a self added event handler, the column
     * drag lock should be set to true in the pressed handler, but still to false again in the released handler.<br>
     * By that we guarantee, that the column resizing still works.
     */

This was changed based on @beldenfox suggestion. I'll change it back.

@openjdk openjdk bot added the rfr Ready for review label Apr 28, 2025
@jperedadnr
Copy link
Collaborator Author

Tests are green now, except for the Windows one, which fails for the chmodArtifactsSdkWin task, that seems totally unrelated to this PR.

@andy-goryachev-oracle
Copy link
Contributor

much better, thank you. btw, you can re-start failing tasks - I hope it's just an intermittent failure.

@jperedadnr
Copy link
Collaborator Author

It has failed three times in a row. Most likely this has already been fixed with JDK-8354337, so I'll sync from head.

@jperedadnr
Copy link
Collaborator Author

It is green now (https://github.com/jperedadnr/jfx/actions/runs/14715013268) after I ran again the failed gradle wrapper validation.

@beldenfox
Copy link
Contributor

This was changed based on @beldenfox suggestion. I'll change it back.

If the mouse pressed event triggers a context menu you might never see the mouse released event. So you have to consider what it means if column drag lock gets set and then never cleared.

The failing test strikes me as odd, it is explicitly testing a bit of internal state to verify that a right-click drag operation will work. Users don't expect this to work and overloading right-click makes life complicated so right-click drags are generally disabled even on Windows. I understand that this test case was added because the table header was getting into a persistent bad state but unless I'm missing something (and I certainly might be) the bug should have been resolved by turning right-click drag into a no-op. (It doesn't help that the test uses the MouseEventFirer which sets the isPopupTrigger flag on both pressed and release which doesn't match the behavior of any platform.)

@andy-goryachev-oracle
Copy link
Contributor

I see a difference in behavior between this PR and the master branch. Admittedly, the scenario is weird:

  • click and drag a column
  • while dragging, right click

What I sort of expect is the behavior of JTable: the right click completes the drag to reorder gesture.

What I see in the master branch is quite weird (testing on macOS): the drag to reorder gesture completes with the column being repositioned, but the popup menu flashes on and then off as the right mouse button is released.

With this PR (again, on macOS) the behavior is different: the popup appears, at the same time the dragging continues uninterrupted. On Windows, the position of the highlight indicating the column being dragged jumps to the original place after right mouse button is released.

It looks to me as if the original developers did not think of such a scenario (while JTable ones did).

We could deal with this scenario in a separate bug, though I think the Windows case needs to be fixed in this PR. Alternatively, we might want to handle this weird scenario in this PR.

What do you think?

P.S. I can't test on Linux, and we should probably also test in on the latest Ubuntu as it seems to work slightly different?

@jperedadnr
Copy link
Collaborator Author

@beldenfox I understand your concerns about columnDragLock and the related tests testColumnRightClickDoesAllowResizing() and testColumnRightClickDoesAllowResizingWhenConsumed(), but if I get it right, this PR doesn't really modify the behaviour of such lock.

So I suggest we take this on a follow up issue, revisiting the need to change the lock from true to false when the popup is triggered, and modifying or removing those tests accordingly.

What do you think?

@jperedadnr
Copy link
Collaborator Author

@andy-goryachev-oracle About this edge case, on macOS it seems better behaviour after this PR: before the highlighting jumps unexpectedly, while after it, the highlighted area is updated smoothly. And I don't see the popup flashing.
About Windows, do you mean we should try to reproduce the same behaviour as on macOS? I'm not sure this should be part of this PR (the issue was only on macOS/Linux).

@andy-goryachev-oracle
Copy link
Contributor

My immediate thought was we should finish the drag to reorder gesture and avoid showing the popup if the right mouse button is pressed during the drag operation, regardless of the platform (this will change the behavior but I think it makes more sense). I would recommend doing it as a part of this PR, but it's up to you.

Doing this will also avoid the issue we saw on windows where the highlighted column being dragged jumps suddenly to the original position which is simply wrong.

What do you think?

@beldenfox
Copy link
Contributor

I think this PR should probably be accepted as-is. It fixes an obvious problem and doesn't introduce any new ones. Someone should enter a follow-up PR citing some of the other problems but most of those have been around for years and only affect users who are looking for trouble (most wouldn't even consider using the right mouse button to drag).

Here you have separate behavior on click vs drag-click and have to deal with two different approaches to context menus. I've tackled this sort of thing before and it usually takes two or four or six tries to get right. To reduce the complexity you have be aggressive at ignoring irrelevant events (no right-click drag!) and avoid setting up state related to dragging until the user actually starts dragging. So this code needs a modest re-write but, again, it doesn't need to happen in this PR.

@kevinrushforth
Copy link
Member

I think this PR should probably be accepted as-is. It fixes an obvious problem and doesn't introduce any new ones. Someone should enter a follow-up PR citing some of the other problems but most of those have been around for years and only affect users who are looking for trouble ...

I tend to agree, as long as any remaining problems are preexisting and not likely to be encountered in the primary use case.

@andy-goryachev-oracle
Copy link
Contributor

The windows problem is pre-existing.

The after-the-fix behavior is slightly better. I'll create the follow-up ticket.

@andy-goryachev-oracle
Copy link
Contributor

created https://bugs.openjdk.org/browse/JDK-8355939

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rfr Ready for review
Development

Successfully merging this pull request may close these issues.

5 participants