Skip to content

(fix/UX) Track menu: Left key in Search related & Crates menus closes them again - #13602

Open
ronso0 wants to merge 1 commit into
mixxxdj:2.6from
ronso0:trackmenu-left-close-submenu
Open

(fix/UX) Track menu: Left key in Search related & Crates menus closes them again#13602
ronso0 wants to merge 1 commit into
mixxxdj:2.6from
ronso0:trackmenu-left-close-submenu

Conversation

@ronso0

@ronso0 ronso0 commented Aug 26, 2024

Copy link
Copy Markdown
Member

If a QWidgetAction in either Search related & Crates menu is focused, Left/Right keys are translated to Up/Down which prevents closing the submenus with Left key like in other submenus.
(in the Crates menu left works as soon as the New Crate button is reached)

Fix:

Translate Left to Esc to close this submenu.
Call hide() of the respective sumenu.

For fixing the crates menu this should actually go to 2.4 ("Search related Tracks" has QWidgetActions only in 2.5), but since we're going to release that shortly before 2.5 I think it's okay to merge the double fix to 2.5-beta

@github-actions github-actions Bot added the ui label Aug 26, 2024
@ronso0 ronso0 added this to the 2.5.0 milestone Sep 6, 2024
@ronso0
ronso0 force-pushed the trackmenu-left-close-submenu branch from bba8f41 to 693c17e Compare September 9, 2024 22:17
@ronso0 ronso0 changed the title (fix/UX) Track menu: translate Left key to Esc in Search related & Crates menus (fix/UX) Track menu: Left key in Search related & Crates menus closes them again Sep 10, 2024

@cr7pt0gr4ph7 cr7pt0gr4ph7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. The issue fixed by this is still present in main, so maybe merge it to main if it should already be too late for 2.5.

cr7pt0gr4ph7 added a commit to cr7pt0gr4ph7/mixxx that referenced this pull request Oct 31, 2024
@JoergAtGithub

Copy link
Copy Markdown
Member

I tried this and it crashed with:
Exception thrown: read access violation. this->d_ptr.**d** was 0x10001004A.

 	Qt6Core.dll!QObject::parent() Line 376	C++
>	[Inline Frame] mixxx.exe!parented_ptr<QWidgetAction>::{dtor}() Line 37	C++
 	[Inline Frame] mixxx.exe!parented_ptr<QWidgetAction>::operator=(parented_ptr<QWidgetAction> &&) Line 65	C++
 	mixxx.exe!WSearchRelatedTracksMenu::addActionsForTrack(const Track & track={...}) Line 364	C++
 	[Inline Frame] mixxx.exe!WTrackMenu::createMenus::__l29::<lambda_1>::operator()() Line 255	C++
 	[Inline Frame] mixxx.exe!QtPrivate::FunctorCall<QtPrivate::IndexesList<>,QtPrivate::List<>,void,`WTrackMenu::createMenus'::`29'::<lambda_1>>::call(WTrackMenu::createMenus::__l29::<lambda_1> &) Line 129	C++
 	[Inline Frame] mixxx.exe!QtPrivate::Functor<`WTrackMenu::createMenus'::`29'::<lambda_1>,0>::call(WTrackMenu::createMenus::__l29::<lambda_1> &) Line 243	C++
 	mixxx.exe!QtPrivate::QFunctorSlotObject<`WTrackMenu::createMenus'::`29'::<lambda_1>,0,QtPrivate::List<>,void>::impl(int which, QtPrivate::QSlotObjectBase * this_=0x000001fd0829df70, QObject * r=0x000000516c6fb500, void * * a=0x00007ffed961946d, bool * ret=0x0000000000000000) Line 457	C++
 	[Inline Frame] Qt6Core.dll!QtPrivate::QSlotObjectBase::call(QObject *) Line 374	C++
 	Qt6Core.dll!doActivate<0>(QObject * sender=0x000001fd13bd6420, int signal_index=7, void * * argv) Line 4036	C++
 	Qt6Core.dll!QMetaObject::activate(QObject * sender=0x000001fd13bd6420, const QMetaObject * m, int local_signal_index=0, void * * argv=0x0000000000000000) Line 4097	C++
 	[Inline Frame] Qt6Widgets.dll!QMenu::aboutToShow() Line 352	C++
 	Qt6Widgets.dll!QMenuPrivate::popup(const QPoint & p={...}, QAction * atAction=0x0000000000000000, std::function<QPoint __cdecl(QSize const &)> positionFunction={...}) Line 2369	C++
 	[Inline Frame] Qt6Widgets.dll!QMenu::popup(const QPoint &) Line 2306	C++
 	Qt6Widgets.dll!QMenu::internalDelayedPopup() Line 3627	C++
 	[Inline Frame] Qt6Widgets.dll!QEvent::accept() Line 303	C++
 	Qt6Widgets.dll!QMenu::keyPressEvent(QKeyEvent * e=0x000000516c6fc6e0) Line 3418	C++
 	Qt6Widgets.dll!QWidget::event(QEvent * event=0x000000516c6fc6e0) Line 9005	C++
 	Qt6Widgets.dll!QMenu::event(QEvent * e=0x000000516c6fc6e0) Line 3047	C++
 	Qt6Widgets.dll!QApplicationPrivate::notify_helper(QObject * receiver=0x000001fd07da7700, QEvent * e=0x000000516c6fc6e0) Line 3292	C++
 	Qt6Widgets.dll!QApplication::notify(QObject * receiver=0x000001fd07da7700, QEvent * e=0x000000516c6fc6e0) Line 2718	C++
 	Qt6Core.dll!QCoreApplication::notifyInternal2(QObject * receiver=0x000001fd07da7700, QEvent * event=0x000000516c6fc6e0) Line 1118	C++
 	Qt6Widgets.dll!QWidgetWindow::event(QEvent * event=0x000000516c6fc6e0) Line 313	C++
 	Qt6Widgets.dll!QApplicationPrivate::notify_helper(QObject * receiver=0x000001fd35e643f0, QEvent * e=0x000000516c6fc6e0) Line 3292	C++
 	Qt6Widgets.dll!QApplication::notify(QObject * receiver=0x000001fd35e643f0, QEvent * e=0x000000516c6fc6e0) Line 3244	C++
 	Qt6Core.dll!QCoreApplication::notifyInternal2(QObject * receiver=0x000001fd35e643f0, QEvent * event=0x000000516c6fc6e0) Line 1118	C++
 	Qt6Gui.dll!QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent * e=0x000001fd15e06ce0) Line 2459	C++
 	Qt6Gui.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 1100	C++
 	Qt6Core.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 464	C++
 	Qt6Gui.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 37	C++
 	[Inline Frame] Qt6Core.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag>) Line 100	C++
 	Qt6Core.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 182	C++
 	Qt6Core.dll!QCoreApplication::exec() Line 1439	C++
 	mixxx.exe!`anonymous namespace'::runMixxx(MixxxApplication * pApp=0x000000516c6ffc48, const CmdlineArgs & args={...}) Line 108	C++
 	mixxx.exe!main(int argc=1, char * * argv=0x000001fd36dfc1b0) Line 243	C++
 	[Inline Frame] mixxx.exe!invoke_main() Line 78	C++
 	mixxx.exe!__scrt_common_main_seh() Line 288	C++
 	kernel32.dll!BaseThreadInitThunk()	Unknown
 	ntdll.dll!RtlUserThreadStart()	
```Unknown

For consistency, I would also filter the Right key.

@daschuer

Copy link
Copy Markdown
Member

@JoergAtGithub I can't reproduce the crasher. It looks like a dangling pointer access. Unfortunately I cannot reproduce the issue.
Do you have receipt for it?

@acolombier acolombier left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

friendly ping @JoergAtGithub - are you able to provide reproduction steps for this bug?

Comment thread src/widget/wtrackmenu.cpp Outdated
@ronso0

ronso0 commented Feb 22, 2025

Copy link
Copy Markdown
Member Author

I extended that to ignore Right key as suggested by @JoergAtGithub

@daschuer
daschuer requested a review from JoergAtGithub April 25, 2025 06:36
@ronso0
ronso0 force-pushed the trackmenu-left-close-submenu branch from 6ce08a7 to 7ca7aea Compare June 6, 2025 23:17
@ronso0 ronso0 added this to the 2.5.2 milestone Jun 7, 2025
@daschuer daschuer modified the milestones: 2.5.2, 2.5.3 Jun 13, 2025
@JoergAtGithub

Copy link
Copy Markdown
Member

I just tested 7ca7aea on Windows and it still crashes sporadic with a read access violation:

Exception thrown: read access violation.
this->d_ptr.**d** was nullptr.

The stacktrace below was from an exception after pressing the right arrow button to open the search menu, which I closed immediately before with the left arrow button:

	Qt6Core.dll!QObject::parent() Line 376	C++
 	[Inline Frame] mixxx.exe!parented_ptr<QWidgetAction>::{dtor}() Line 37	C++
 	[Inline Frame] mixxx.exe!parented_ptr<QWidgetAction>::operator=(parented_ptr<QWidgetAction> &&) Line 65	C++
 	mixxx.exe!WSearchRelatedTracksMenu::addActionsForTrack(const Track & track={...}) Line 364	C++
 	[Inline Frame] mixxx.exe!WTrackMenu::createMenus::__l29::<lambda_1>::operator()() Line 259	C++
 	[Inline Frame] mixxx.exe!QtPrivate::FunctorCall<QtPrivate::IndexesList<>,QtPrivate::List<>,void,`WTrackMenu::createMenus'::`29'::<lambda_1>>::call(WTrackMenu::createMenus::__l29::<lambda_1> &) Line 129	C++
 	[Inline Frame] mixxx.exe!QtPrivate::Functor<`WTrackMenu::createMenus'::`29'::<lambda_1>,0>::call(WTrackMenu::createMenus::__l29::<lambda_1> &) Line 243	C++
 	mixxx.exe!QtPrivate::QFunctorSlotObject<`WTrackMenu::createMenus'::`29'::<lambda_1>,0,QtPrivate::List<>,void>::impl(int which, QtPrivate::QSlotObjectBase * this_=0x000002073aa39820, QObject * r=0x00000015688fb350, void * * a=0x00007ff80819946d, bool * ret=0x0000000000000000) Line 457	C++
 	[Inline Frame] Qt6Core.dll!QtPrivate::QSlotObjectBase::call(QObject *) Line 374	C++
 	Qt6Core.dll!doActivate<0>(QObject * sender=0x000002077b5c9580, int signal_index=0x00000007, void * * argv) Line 4036	C++
 	Qt6Core.dll!QMetaObject::activate(QObject * sender=0x000002077b5c9580, const QMetaObject * m, int local_signal_index=0x00000000, void * * argv=0x0000000000000000) Line 4097	C++
 	[Inline Frame] Qt6Widgets.dll!QMenu::aboutToShow() Line 352	C++
 	Qt6Widgets.dll!QMenuPrivate::popup(const QPoint & p={...}, QAction * atAction=0x0000000000000000, std::function<QPoint __cdecl(QSize const &)> positionFunction={...}) Line 2369	C++
 	[Inline Frame] Qt6Widgets.dll!QMenu::popup(const QPoint &) Line 2306	C++
 	Qt6Widgets.dll!QMenu::internalDelayedPopup() Line 3627	C++
 	[Inline Frame] Qt6Widgets.dll!QEvent::accept() Line 303	C++
 	Qt6Widgets.dll!QMenu::keyPressEvent(QKeyEvent * e=0x00000015688fc530) Line 3418	C++
 	Qt6Widgets.dll!QWidget::event(QEvent * event=0x00000015688fc530) Line 9005	C++
 	Qt6Widgets.dll!QMenu::event(QEvent * e=0x00000015688fc530) Line 3047	C++
 	Qt6Widgets.dll!QApplicationPrivate::notify_helper(QObject * receiver=0x000002076cbb5740, QEvent * e=0x00000015688fc530) Line 3292	C++
 	Qt6Widgets.dll!QApplication::notify(QObject * receiver=0x000002076cbb5740, QEvent * e=0x00000015688fc530) Line 2718	C++
 	Qt6Core.dll!QCoreApplication::notifyInternal2(QObject * receiver=0x000002076cbb5740, QEvent * event=0x00000015688fc530) Line 1118	C++
 	Qt6Widgets.dll!QWidgetWindow::event(QEvent * event=0x00000015688fc530) Line 313	C++
 	Qt6Widgets.dll!QApplicationPrivate::notify_helper(QObject * receiver=0x00000207113ec0d0, QEvent * e=0x00000015688fc530) Line 3292	C++
 	Qt6Widgets.dll!QApplication::notify(QObject * receiver=0x00000207113ec0d0, QEvent * e=0x00000015688fc530) Line 3244	C++
 	Qt6Core.dll!QCoreApplication::notifyInternal2(QObject * receiver=0x00000207113ec0d0, QEvent * event=0x00000015688fc530) Line 1118	C++
 	Qt6Gui.dll!QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent * e=0x000002071125e350) Line 2459	C++
 	Qt6Gui.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 1100	C++
 	Qt6Core.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 464	C++
 	Qt6Gui.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 37	C++
 	[Inline Frame] Qt6Core.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag>) Line 100	C++
 	Qt6Core.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...}) Line 182	C++
 	Qt6Core.dll!QCoreApplication::exec() Line 1439	C++
 	mixxx.exe!`anonymous namespace'::runMixxx(MixxxApplication * pApp=0x00000015688ffaa0, const CmdlineArgs & args={...}) Line 108	C++
 	mixxx.exe!main(int argc=0x00000001, char * * argv=0x000002071eb37070) Line 243	C++

@ronso0

ronso0 commented Nov 13, 2025

Copy link
Copy Markdown
Member Author

@JoergAtGithub Do you use the Search Related menu currently?
If yes, do you experience crashes when you leave that menu to auto-close it (hover main track menu)?

@ronso0
ronso0 force-pushed the trackmenu-left-close-submenu branch from 7ca7aea to 7b971e8 Compare November 13, 2025 10:58
@ronso0
ronso0 marked this pull request as draft November 13, 2025 11:03
@ronso0

ronso0 commented Nov 13, 2025

Copy link
Copy Markdown
Member Author

I have reworked the creation of Search Related so it's not cleared on every aboutToShow event.
= identical to Crates menu
And I added an assertion for action->parent()

Hopefully that fixes the crasher.

@ronso0
ronso0 force-pushed the trackmenu-left-close-submenu branch from 7b971e8 to 63ff487 Compare November 13, 2025 11:16
@ronso0
ronso0 force-pushed the trackmenu-left-close-submenu branch from 63ff487 to 39a5996 Compare November 13, 2025 13:24
@ronso0 ronso0 modified the milestones: 2.5.4, 2.6.0 Dec 9, 2025
@acolombier
acolombier changed the base branch from 2.5 to 2.6 March 13, 2026 16:33
@daschuer

Copy link
Copy Markdown
Member

Is this still in draft state?

@ronso0
ronso0 marked this pull request as ready for review March 30, 2026 11:31
@ronso0

ronso0 commented Mar 30, 2026

Copy link
Copy Markdown
Member Author

It's ready for review.
I decided to leave it as draft until we figure the cause of the the crash Jörg experienced, but I still don't see how that is related to these changes.

@ronso0 ronso0 modified the milestones: 2.6.0, 2.6.1 May 22, 2026
@ronso0

ronso0 commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

@JoergAtGithub I think the crash you saw #13602 (comment) is #15197, hence unrelated to this PR

@daschuer

daschuer commented Aug 2, 2026

Copy link
Copy Markdown
Member

Conflict have developed.

@ronso0
ronso0 force-pushed the trackmenu-left-close-submenu branch from 39a5996 to 0706518 Compare August 2, 2026 23:49
@ronso0

ronso0 commented Aug 2, 2026

Copy link
Copy Markdown
Member Author

I rebased now that #16697 has been merged

@daschuer

daschuer commented Aug 3, 2026

Copy link
Copy Markdown
Member

@JoergAtGithub can this be merged now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants