Skip to content

Improve fade/animation behavior #1291

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

Merged
merged 36 commits into from
May 20, 2025
Merged

Conversation

scrubbbbs
Copy link
Collaborator

@scrubbbbs scrubbbbs commented Mar 23, 2025

In this PR I am aiming to improve the fade/animation part of nomacs UI with a couple of objectives.

  • refactor DkFadeWidget and friends which share a lot of common code
  • Add option to disable all animations #922
  • be able to disable animations in some situations like when when switching modes or window is first created.

TODO: Decide if we should be fading things we did not before. The following are now fading because behavior was masked before. I think I am ok with all of this but the animation could be a bit quicker

  • settings/batch pages on show/hide (removed fade)
  • settings/batch tabs on show/hide (removed fade)
  • thumbs panel (Shift+T) (removed fade)
  • recent files (removed fade)
  • crop widget (C) (RETAINED)

Full list of widgets now fading:
image

@scrubbbbs scrubbbbs force-pushed the ui-animation branch 6 times, most recently from 8428eb3 to 4f55700 Compare March 26, 2025 20:49
@scrubbbbs scrubbbbs mentioned this pull request Mar 26, 2025
@scrubbbbs scrubbbbs requested review from novomesk and leejuyuu March 27, 2025 15:37
@scrubbbbs scrubbbbs marked this pull request as ready for review March 27, 2025 15:42
@scrubbbbs
Copy link
Collaborator Author

This seems to be ready now. The most noticeable change is the fades I listed above, which could be taken out if you guys don't like it. I'm on the fence at the moment.

@novomesk
Copy link
Collaborator

When trying the appveyor build, I am getting Unhandled exception at 0x00007FFDB106286E (ucrtbase.dll) in nomacs.exe: Fatal program exit requested. when closing nomacs.

image

@novomesk
Copy link
Collaborator

The crash is not related to this PR, I can reproduce it with 3.21.0 version too.

Open batch processing window, select few files and close nomacs.

Thread 1 "nomacs" received signal SIGSEGV, Segmentation fault.

#0  0x00007ffff6f58b29 in QGraphicsItem::group() const () at /usr/lib64/libQt6Widgets.so.6
#1  0x00007ffff6f590ab in QGraphicsItem::isSelected() const () at /usr/lib64/libQt6Widgets.so.6
#2  0x00007ffff7d299ca in nmc::DkThumbScene::getSelectedFiles () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkThumbsWidgets.cpp:1573
#3  0x00007ffff7d2a43f in nmc::DkThumbScrollWidget::enableSelectionActions () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkThumbsWidgets.cpp:2035
#4  0x00007ffff7d3366c in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (nmc::DkThumbScrollWidget::*)()>::call(void (nmc::DkThumbScrollWidget::*)(), nmc::DkThumbScrollWidget*, void**)::{lambda()#1}::operator()() const () at /usr/include/qt6/QtCore/qobjectdefs_impl.h:152
#5  0x00007ffff7d336bf in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (nmc::DkThumbScrollWidget::*)()>::call(void (nmc::DkThumbScrollWidget::*)(), nmc::DkThumbScrollWidget*, void**)::{lambda()#1}>(void**, QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (nmc::DkThumbScrollWidget::*)()>::call(void (nmc::DkThumbScrollWidget::*)(), nmc::DkThumbScrollWidget*, void**)::{lambda()#1}&&) () at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65
#6  QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (nmc::DkThumbScrollWidget::*)()>::call(void (nmc::DkThumbScrollWidget::*)(), nmc::DkThumbScrollWidget*, void**) () at /usr/include/qt6/QtCore/qobjectdefs_impl.h:151
#7  QtPrivate::FunctionPointer<void (nmc::DkThumbScrollWidget::*)()>::call<QtPrivate::List<>, void>(void (nmc::DkThumbScrollWidget::*)(), nmc::DkThumbScrollWidget*, void**) () at /usr/include/qt6/QtCore/qobjectdefs_impl.h:199
#8  0x00007ffff7d33715 in QtPrivate::QCallableObject<void (nmc::DkThumbScrollWidget::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) () at /usr/include/qt6/QtCore/qobjectdefs_impl.h:570
#9  0x00007ffff62eba26 in void doActivate<false>(QObject*, int, void**) () at /usr/lib64/libQt6Core.so.6
#10 0x00007ffff6ffdd68 in QGraphicsScenePrivate::removeItemHelper(QGraphicsItem*) () at /usr/lib64/libQt6Widgets.so.6
#11 0x00007ffff6ffeae5 in QGraphicsItem::~QGraphicsItem() () at /usr/lib64/libQt6Widgets.so.6
#12 0x00007ffff6ffee67 in QGraphicsObject::~QGraphicsObject() () at /usr/lib64/libQt6Widgets.so.6
#13 0x00007ffff7d2e632 in nmc::DkThumbLabel::~DkThumbLabel () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkThumbsWidgets.cpp:850
#14 0x00007ffff7d2e64b in nmc::DkThumbLabel::~DkThumbLabel () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkThumbsWidgets.cpp:850
#15 0x00007ffff6f81a4e in QGraphicsScene::clear() () at /usr/lib64/libQt6Widgets.so.6
#16 0x00007ffff7000eff in QGraphicsScene::~QGraphicsScene() () at /usr/lib64/libQt6Widgets.so.6
#17 0x00007ffff7c5cb6d in nmc::DkThumbScene::~DkThumbScene () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge_build/nomacsCore_autogen/XJ2BUHI2UY/../../../ImageLounge/src/DkGui/DkThumbsWidgets.h:236
#18 0x00007ffff7c5cb7d in nmc::DkThumbScene::~DkThumbScene () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge_build/nomacsCore_autogen/XJ2BUHI2UY/../../../ImageLounge/src/DkGui/DkThumbsWidgets.h:236
#19 0x00007ffff62a7ebd in QObjectPrivate::deleteChildren() () at /usr/lib64/libQt6Core.so.6
#20 0x00007ffff7327708 in QWidget::~QWidget() () at /usr/lib64/libQt6Widgets.so.6
#21 0x00007ffff7c543f6 in nmc::DkWidget::~DkWidget () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkBaseWidgets.h:56
#22 nmc::DkFadeWidget::~DkFadeWidget () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkBaseWidgets.h:64
#23 nmc::DkThumbScrollWidget::~DkThumbScrollWidget () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge_build/nomacsCore_autogen/XJ2BUHI2UY/../../../ImageLounge/src/DkGui/DkThumbsWidgets.h:320
#24 nmc::DkThumbScrollWidget::~DkThumbScrollWidget () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge_build/nomacsCore_autogen/XJ2BUHI2UY/../../../ImageLounge/src/DkGui/DkThumbsWidgets.h:320
#25 0x00007ffff62a7ebd in QObjectPrivate::deleteChildren() () at /usr/lib64/libQt6Core.so.6
#26 0x00007ffff7327708 in QWidget::~QWidget() () at /usr/lib64/libQt6Widgets.so.6
#27 0x00007ffff712ccbd in QStackedWidget::~QStackedWidget() () at /usr/lib64/libQt6Widgets.so.6
#28 0x00007ffff62a7ebd in QObjectPrivate::deleteChildren() () at /usr/lib64/libQt6Core.so.6
#29 0x00007ffff7327708 in QWidget::~QWidget() () at /usr/lib64/libQt6Widgets.so.6
#30 0x00007ffff705321d in QTabWidget::~QTabWidget() () at /usr/lib64/libQt6Widgets.so.6
#31 0x00007ffff62a7ebd in QObjectPrivate::deleteChildren() () at /usr/lib64/libQt6Core.so.6
#32 0x00007ffff7327708 in QWidget::~QWidget() () at /usr/lib64/libQt6Widgets.so.6
#33 0x00007ffff7c5cb02 in nmc::DkWidget::~DkWidget () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge/src/DkGui/DkBaseWidgets.h:56
#34 nmc::DkBatchContent::~DkBatchContent () at /var/tmp/portage/media-gfx/nomacs-3.21.0/work/nomacs-3.21.0/ImageLounge_build/nomacsCore_autogen/XJ2BUHI2UY/../../../ImageLounge/src/DkGui/DkBatch.h:104

@leejuyuu
Copy link
Collaborator

leejuyuu commented Apr 4, 2025

The edit panel loses color for bec4d79.

image

@leejuyuu
Copy link
Collaborator

leejuyuu commented Apr 4, 2025

The Settings tab seems to have fade enabled. I think the previous behavior (no fade) looks better.

2025-04-04.17-18-46.mp4

@leejuyuu
Copy link
Collaborator

leejuyuu commented Apr 4, 2025

Batch process has the same issue.

2025-04-04.17-28-41.mp4

@leejuyuu
Copy link
Collaborator

leejuyuu commented Apr 4, 2025

I am using system theme.

@scrubbbbs scrubbbbs marked this pull request as draft April 9, 2025 23:34
@scrubbbbs
Copy link
Collaborator Author

Back to draft, I found some more issues with system theme.

@scrubbbbs scrubbbbs marked this pull request as ready for review April 10, 2025 12:17
@scrubbbbs
Copy link
Collaborator Author

Fixed a regression from #1140. I think this is ready.

scrubbbbs added 27 commits May 20, 2025 08:05
DkPlayer broken as override of show() with default argument masks
DkFadeMixin::show(). Rename this to showTemporarily() to prevent that.

This matches the previous behavior except for these changes.

1) If the display mode is changed while playing, the player is not
shown. The previous behavior was to show the player and it would not
autohide unless restarting the slideshow.

2) The player controls (pause/play) cannot permanently affect the
visibility of the player. If the user toggles the player visibility
manually (P) then the change is saved.
This is a dialog so it doesn't make sense to use it here, also
it has no effect.
The fade is obscured or cut off by showing of the dialog if the window
manager animates showing the dialog. Also it is the only widget in the
dialog so it isn't transitioning from anything which doesn't make sense.
It is dead code as it was always hidden from view. DkFileInfoLabel has
taken over this function and can in the future provide an option to
toggle what info is displayed (current file name, date, and star rating)
block() is now dead due to removal of DkRatingLabelBg which was also
dead
child of DkFileInfoLabel which is faded already, so this does nothing
definition of virtual hide() makes a conflict with DkFadeMixin because
it also declares hide() with one default argument. It is also a conflict
with QWidget::hide() as that is not virtual.

There is no reason to mask hide()/show() in Qt, as these are not virtual
it can cause bugs. The correct method is to override setVisible(bool)
which is virtual.
MSVC type resolution seems to be different than gcc/clang so try it
another way
always visible so they never fade
Support disabling animations on a per-widget basis. This is desireable
when reusing widgets in different contexts e.g. DkThumbScrollWidget.

Also disable animations if the parent is animating, which could cause a
visual glitch or at best has no effect.

Also adds tighter control of timer by using QTimerEvent instead of
QTimer.
enter/exit fullscreen uses it to make transition smoother;

the hide/show of panels can make panels change position immediately
after the animation completes, which looks bad
only possible if plugins are disabled
The other widgets in the tab don't fade so this shouldn't either
don't use the same setting for disabling animation for user and
temporarily as it could cause unexpected change of user setting
prevents glitch where layout changes shortly after switch due to widgets
becoming hidden, which does not happen until animation ends, which is
some time after the switch finishes

this also disables animation for the initial startup of nomacs; as the
window manager is probably fading in the window anyways we don't want to
pile on more animations.
There are some pitfalls when overriding DkFadeMixin::setVisible() due to
the recursion through QWidget::setVisible, see comment @
DkFadeMixin::setVisible.

Infinite recursion is not possible, but the function body may be
executed multiple times per call to setVisible()

Currently, none of this is strictly required but in the future it would
likely result in bugs.
Broken by removal of fade. Was reliant on paint hack in DkFadeWidget.

Move the paint hack into DkWidget so it will be used again.
Reverts to previous behavior before refactoring fadewidget
On the system theme, when thumbs grid view is displayed,
the background shows through on some widgets. This is most apparent when
the thumbnail ribbon is pinned to the top.

This is a regression since theme overall PR#1140
We should not be using DkSettings for flags such as this which are not
user-modifyable.
Move old functionality into DkRatingLabel so actions work again.

Also remove some clutter.
- unecessary virtual
- excessive inline (inline containing a loop)
- use lambdas instead of trival methods
- use table/loop to make stars
@scrubbbbs scrubbbbs merged commit 7f1ad3b into nomacs:master May 20, 2025
12 checks passed
@scrubbbbs scrubbbbs deleted the ui-animation branch May 20, 2025 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants