nuttyartist / notes

Fast and beautiful note-taking app written in C++. Write down your thoughts.
https://www.get-notes.com
Mozilla Public License 2.0
3.6k stars 316 forks source link

New Editor Settings font icons, other aesthetic... #589

Closed nuttyartist closed 12 months ago

nuttyartist commented 1 year ago

This PR implements:

Solves #523 Solves #541 Solves #550 Solves #309 Solves #400

On macOS: Screen Shot 2023-06-22 at 10 07 55 AM Screen Shot 2023-06-22 at 10 08 06 AM

On Windows (Dark mode):

Screen Shot 2023-06-21 at 6 32 47 PM

I haven't tested this PR on a Linux distro, but if something is off with the EditorSettins there, I assume that the workaround I did on Windows might fix the issue on Linux. I will try to create a new Linux VM with Qt installed today and test it thre as well.

Some note: the time it took me to do this work was unproportionally affected by debugging many of the C++ UI MCV code. The QML related was a breeze to develop with.

What I need help in:

  1. Only on macOS, the app crashes when doing the following 1. Showing EditorSettings 2. Clicking on it anywhere, then 3. Doing a search and then 4. Clearing the search field. Maybe I'm not managing memory correctly somewhere? Can anyone reproduce this?
  2. Custom Scrollbar background color is not trasnparent (looks bad in dark mode), at least on Windows (you can see in the screenshot above). @zjeffer, any idea? I try different values in the css but to no success.

Some design discussion:

  1. Should I implement the same scrollbar behavior I did for textEdit for notesListView and nodeTreeView (folders pane) for Windows and Linux? I think the app will look much better that way. I can also improve upon the textEdit's implementation and show the scrollbar when the mouse cursor is near/hovering its area as well.
  2. Many users complain of the v2.1 custon native decoration (without searching for the native option in the dots menu). So should we default on using the native window decoration even if in the settings.ini it is set to custom decoration but still allows users to change it back? Is it possible?
  3. Should clicking on Move to Trash close EditorSettings? May feeling is not so the user can keep deleting notes if he wishes so.

To add in the future:

Let me know what you guys think.

EDIT 1: Notice the white strip on the Windows Screenshot in Dark mode (it fits well in Light mode). This is because I couldn't get the right window flags with frameless window and translucency Windows so I went with CustomizeWindowHint and no translucency (luckily it still has drop shadow). Also because Qt:Popup flag on Windows doesn't really work well I implemented the Popup behavior myself (works well imo).

EDIT 2: I'm trying to support Qt 5 as well. It's going well at the moment. Just need to figure how to share C++ ENUMs between QWidgets and QML (The current way doesn't work with Qt 5).

guihkx commented 1 year ago

Just leaving some initial feedback on the Linux build:

I'm hitting that same translucency bug caused by using colors with an alpha channel on the Qt 6 AppImage (top-left side):

image

In addition, none of the options under the three dots menu are clickable.

zjeffer commented 1 year ago

First test on Hyprland (a Wayland compositor):

2023-06-23 21-07-26.webm

It's very buggy, at least on wayland. I'll look at the code in more detail when I have time.

nuttyartist commented 1 year ago

Thanks for the feedback, I think the the Editor Settings window doesn't show up well on Linux because i'm using the wrong window flags on Linux. I think switching to the same ones used in Windows should work. I'll test this soon.

I wonder why it's translucent in both your machines at the top left corner?

And in @zjeffer machine, the tags circles are outlined and not filled, plus I see some fonts not loaded on the QML side. What errors do you see in the terminal?

zjeffer commented 1 year ago

No errors in the terminal

zjeffer commented 1 year ago

From your PR description

Keyboard shortcut: Ctrl + L sets focus on listview

I would change this shortcut to something else. In vscode, Ctrl+L selects the current line, and I was planning to add the same shortcut to Notes.

guihkx commented 1 year ago

@nuttyartist I'm not sure if you're already aware, but on Windows 10 the new menu currently looks borked as well (at least on "text mode view"):

image

After I switch to the Kanban view, then the menu looks okay:

image

Tested with the Qt 6 build from commit fbfc1c5ca2377362c63496f594e1d1e412526295

nuttyartist commented 1 year ago

I tested on Windows 10 as well. I have a feeling different builds produce different results? @guihkx, do you think you can play with the windows flags to get the same result I got? At the code here: https://github.com/nuttyartist/notes/blob/fbfc1c5ca2377362c63496f594e1d1e412526295/src/mainwindow.cpp#L965C63-L965C63

From your PR description

Keyboard shortcut: Ctrl + L sets focus on listview

I would change this shortcut to something else. In vscode, Ctrl+L selects the current line, and I was planning to add the same shortcut to Notes.

@zjeffer What do you suggest? Ctrl+Shift+L?

zjeffer commented 1 year ago

Sure, Ctrl+Shift+L looks good to me.

nuttyartist commented 1 year ago

Sure, Ctrl+Shift+L looks good to me.

We're using this shortcut for mazimizing the window, actually. Any other suggestion?

zjeffer commented 1 year ago

We're using this shortcut for mazimizing the window, actually. Any other suggestion?

Why do we have an app shortcut for maximizing the window? Doesn't the OS already have this? Windows has Windows Key + Up, to maximize, and many linux distributions also have a shortcut for this. Does macOS not have a shortcut for this?

nuttyartist commented 1 year ago

We're using this shortcut for mazimizing the window, actually. Any other suggestion?

Why do we have an app shortcut for maximizing the window? Doesn't the OS already have this? Windows has Windows Key + Up, to maximize, and many linux distributions also have a shortcut for this. Does macOS not have a shortcut for this?

MacOS does not. But you can create a shortcut for this. In any case, since our current code exclude macOS already

void MainWindow::maximizeWindow()
{
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)

And both Windows and Linux distros have a shortcut for that. I think we can use Ctrl+Shift+L.

guihkx commented 1 year ago

@zjeffer Can you please check if commit 079c6d171594b66ec06407bef3c3b68f75568116 fixes the transparency issue on Wayland and, more importantly, if I did things correctly? Thanks!

guihkx commented 1 year ago

do you think you can play with the windows flags to get the same result I got?

On Linux, if I remove the Qt::Popup flag from the settings menu, then I'm able to interact with it.

However, this removes the 'modality' of the menu, which I believe is not ideal. I haven't found a perfect solution yet, but it seems weird to me that the mere presence of Qt::Popup seems to cause the menu to be unclickable...

guihkx commented 1 year ago

Some very minor nitpicks I just thought of as well:

nuttyartist commented 1 year ago

do you think you can play with the windows flags to get the same result I got?

On Linux, if I remove the Qt::Popup flag from the settings menu, then I'm able to interact with it.

However, this removes the 'modality' of the menu, which I believe is not ideal. I haven't found a perfect solution yet, but it seems weird to me that the mere presence of Qt::Popup seems to cause the menu to be unclickable...

Yep, same issue on Windows. But that's not much a problem, as long as you we get either a transucent frameless window, or a frameless window with nice drop down shadow (like what I got on Windows). Then we can use the same code we use on Windows. I'm currently working on smoothing some other things out and then I'll test on Linux.

You're registering enums as com.notes, but now that we have a "real id" (io.github.nuttyartist.notes), it probably makes sense to use that instead

Yes, I agree.

The usage of macros to detect the OS is a bit inconsistent throughout the code base, but from now on I think we should ry to stick with the defined(MACRO) syntax. And let's also use macros provided by the Qt headers, i.e.: Q_OS_WINDOWS / Q_OS_MACOS / Q_OS_UNIX ... etc.

Yes, I noticed that as well. Shouls I change all our macros to use the Qt headers?

guihkx commented 1 year ago

But that's not much a problem, as long as you we get either a transucent frameless window, or a frameless window with nice drop down shadow (like what I got on Windows)

Removing Qt::Popup does fix it. At least on the Qt 6 build, because the Qt 5 one still doesn't have the shadows. But doing that causes the settings menu window to get detached from the main window, and I'm not 100% of the implications of that (e.g. if tiling window managers get mad or something).

Shouls I change all our macros to use the Qt headers?

I think we can leave that to a separate PR. This one already adds/changes a lot of things, so if there's a mistake while updating those, it's not very hard for us to miss it, and we don't want to cause regressions.

I think just updating the ones introduced in this PR is enough for now.

zjeffer commented 1 year ago

@zjeffer Can you please check if commit 079c6d1 fixes the transparency issue on Wayland and, more importantly, if I did things correctly? Thanks!

@guihkx It fixes the issue, and the code looks good. Nice!

nuttyartist commented 1 year ago

Removing Qt::Popup does fix it. At least on the Qt 6 build, because the Qt 5 one still doesn't have the shadows. But doing that causes the settings menu window to get detached from the main window, and I'm not 100% of the implications of that (e.g. if tiling window managers get mad or something).

Oh, will tiling window managers detect it as a separate window? Maybe there are flags for that? Anyway, when I put my hands all Linux I'll try to test.

I think just updating the ones introduced in this PR is enough for now.

👍

guihkx commented 1 year ago

Oh, will tiling window managers detect it as a separate window?

I've only tested on KDE Plasma and that does happen... I was thinking it could be worse on tiling wms... somehow :p

nuttyartist commented 1 year ago

@guihkx For some reason I can't change the enums name to io.github.nuttyartist.notes. Is nuttyartist.notes fine or should I keep com.notes? Maybe only one dot allowed?

guihkx commented 1 year ago

Maybe only one dot allowed?

Perhaps. In any case, I think nuttyartist.notes is a good choice.

nuttyartist commented 1 year ago

What's remaining:

Other issues are minor (I'll open separate issues for them).

@guihkx BTW, we have issue in the building process with homebrew?

Run brew update
remote: fatal: object f8696f9c453a5093bda5ebdc559373d500fa6c7a cannot be read        
remote: aborting due to possible repository corruption on the remote side.

EDIT: Also to fix the warnings we get.

guihkx commented 1 year ago

@guihkx BTW, we have issue in the building process with homebrew?

Seems to be a temporary issue:

guihkx commented 1 year ago

I inspected the source of the SVG added in 7ab93ec4c52f9b26639f99ac65f9e69d4c54ac63, and judging by the <image xlink:href="data:image/png;...> tag there, I think that's not a vector image anymore.

Since we already provide PNGs for the icon in many resolutions, I think that having the SVG icon is not critical.

So, unless you're able to make that SVG a real vector image, feel free to remove the whole scalable directory, and also remove it from CMakeLists.txt:

https://github.com/nuttyartist/notes/blob/bf1f62ec7d1db93f0df31d1e07ddf69bda0bec22/CMakeLists.txt#L443-L447

nuttyartist commented 1 year ago

I inspected the source of the SVG added in 7ab93ec, and judging by the <image xlink:href="data:image/png;...> tag there, I think that's not a vector image anymore.

Since we already provide PNGs for the icon in many resolutions, I think that having the SVG icon is not critical.

So, unless you're able to make that SVG a real vector image, feel free to remove the whole scalable directory, and also remove it from CMakeLists.txt:

https://github.com/nuttyartist/notes/blob/bf1f62ec7d1db93f0df31d1e07ddf69bda0bec22/CMakeLists.txt#L443-L447

Alrighty, I'll try again and check the source. If I can't convert it then I'll remove the folder.

nuttyartist commented 1 year ago

I feel like this PR is now ready to be merged.

guihkx commented 1 year ago

I think it's not a very good practice to merge PRs into master that don't pass all CI checks.

Do you think it will be too hard to get this to build on Qt 5.12.8 (used by Ubuntu 20.04)?

Also, before merging I'd recommend either cleaning up some of those commits, or in the worst case squashing all of them into a single huge commit, which is bad, but not as bad as merging many bad commits into master, as it makes things unnecessarily harder for regression testing in the future.

nuttyartist commented 1 year ago

Do you think it will be too hard to get this to build on Qt 5.12.8 (used by Ubuntu 20.04)?

I'll look into it 👍

Also, before merging I'd recommend either cleaning up some of those commits, or in the worst case squashing all of them into a single huge commit, which is bad, but not as bad as merging many bad commits into master, as it makes things unnecessarily harder for regression testing in the future.

Sure. Can you do that? (I just don't know how).

guihkx commented 1 year ago

Sure. Can you do that? (I just don't know how).

On it...

nuttyartist commented 1 year ago

Do you think it will be too hard to get this to build on Qt 5.12.8 (used by Ubuntu 20.04)?

Seems to work now.

guihkx commented 1 year ago

Commit 252a7334ab84ca80e44772cfbed870c558f614f0 seems to have broken custom decorations on Linux.

This is how the app now starts up when 'native window frame' is disabled (which is still the default behavior):

bad

Seems to work now.

Very nice! Let me just fire up an Ubuntu virtual machine to make sure the deb package works.

nuttyartist commented 1 year ago

Commit https://github.com/nuttyartist/notes/commit/252a7334ab84ca80e44772cfbed870c558f614f0 seems to have broken custom decorations on Linux.

Whoops, I think I forgot some things. On PopOS everything looked fine tho. I'll look into that.

Very nice! Let me just fire up an Ubuntu virtual machine to make sure the deb package works.

👍

nuttyartist commented 1 year ago

@guihkx Can you test if the latest commit solved the issue? I don't have access to Linux at the moment.

guihkx commented 1 year ago

Yup, that fixed it. Nice!

However, I found another major issue on Linux that causes the app to freeze and use a lot of CPU. Steps to reproduce:

  1. Click on the green button to enter fullscreen mode
  2. Click on it again to leave fullscreen mode

Result: The whole app freezes.

Video:

https://github.com/nuttyartist/notes/assets/626206/e78b4429-02d3-4a89-86d1-dc6b778f1f15

This issue is not present on master.

nuttyartist commented 1 year ago

Weird! Does the issue happen due to the latest commit?

guihkx commented 1 year ago

No, it's reproducible even with the AppImage from commit ef6dca4042b08cba778427ad353051ead8e0914d -- which is the first commit from this pull request where the Qt 6 build for Linux was successful.

I tried to grab a stack trace with gdb, but gdb greatly increases its memory usage after I interrupt the notes process, and then my computer always end up freezing (I have only 8 gigs of RAM). :(

nuttyartist commented 1 year ago

Hmm okay. Good catch, I'll try to see what causes this.

guihkx commented 1 year ago

Managed to get one (though I have no idea of a follow-up to this lol):

#0  QTextDocumentLayoutPrivate::floatMargins(QFixed, QTextLayoutStruct const*, QFixed*, QFixed*) const [clone .isra.0] (y=..., layoutStruct=layoutStruct@entry=0x7fffffffa800, left=left@entry=0x7fffffffa4bc, right=right@entry=0x7fffffffa4b8, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3639
#1  0x00007ffff6236dd7 in QTextDocumentLayoutPrivate::layoutBlock(QTextBlock const&, int, QTextBlockFormat const&, QTextLayoutStruct*, int, int, QTextBlockFormat const*) (this=0x5555566f30c0, bl=<optimized out>, blockPosition=<optimized out>, blockFormat=<optimized out>, layoutStruct=0x7fffffffa800, layoutFrom=<optimized out>, layoutTo=<optimized out>, previousBlockFormat=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3552
#2  0x00007ffff62315e6 in QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::iterator, QTextLayoutStruct*, int, int, QFixed) (this=this@entry=0x5555566f30c0, it=..., layoutStruct=layoutStruct@entry=0x7fffffffa800, layoutFrom=layoutFrom@entry=0, layoutTo=layoutTo@entry=2147483647, width=..., width@entry=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3279
#3  0x00007ffff62334fc in QTextDocumentLayoutPrivate::layoutFrame(QTextFrame*, int, int, QFixed, QFixed, QFixed) (this=this@entry=0x5555566f30c0, f=f@entry=0x5555566b3200, layoutFrom=layoutFrom@entry=0, layoutTo=layoutTo@entry=2147483647, frameWidth=..., frameWidth@entry=..., frameHeight=..., parentY=...) at /usr/src/debug/qt6-base/build/include/QtGui/6.5.1/QtGui/private/../../../../../../qtbase-everywhere-src-6.5.1/src/gui/painting/qfixed_p.h:31
#4  0x00007ffff6233a69 in QTextDocumentLayoutPrivate::layoutFrame(QTextFrame*, int, int, QFixed) (this=0x5555566f30c0, f=0x5555566b3200, layoutFrom=0, layoutTo=2147483647, parentY=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:2910
#5  0x00007ffff6238238 in QTextDocumentLayout::doLayout(int, int, int) (this=0x555556412ed0, from=0, oldLength=oldLength@entry=0, length=2147483647) at /usr/src/debug/qt6-base/build/include/QtGui/6.5.1/QtGui/private/../../../../../../qtbase-everywhere-src-6.5.1/src/gui/painting/qfixed_p.h:31
#6  0x00007ffff6238ab0 in QTextDocumentLayoutPrivate::ensureLayoutedByPosition(int) const (position=<optimized out>, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3990
#7  QTextDocumentLayoutPrivate::ensureLayoutedByPosition(int) const (position=1000, this=0x5555566f30c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3982
#8  QTextDocumentLayoutPrivate::layoutStep() const (this=this@entry=0x5555566f30c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3996
#9  0x00007ffff6238fd8 in QTextDocumentLayout::documentChanged(int, int, int) (this=0x555556412ed0, from=0, oldLength=0, length=23) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/text/qtextdocumentlayout.cpp:3784
#10 0x00007ffff7184235 in QTextEditPrivate::relayoutDocument() (this=0x555556782e90) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/tools/qsize.h:128
#11 0x00005555555e2461 in CustomDocument::resizeEvent(QResizeEvent*) (this=0x5555566bac80, event=0x7fffffffae70) at /home/gui/dev/notes/src/customdocument.cpp:33
#12 0x00007ffff6fbdab1 in QWidget::event(QEvent*) (this=0x5555566bac80, event=0x7fffffffae70) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:9107
#13 0x00007ffff7050e76 in QFrame::event(QEvent*) (this=0x5555566bac80, e=0x7fffffffae70) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qframe.cpp:515
#14 0x00007ffff59395d8 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (receiver=receiver@entry=0x5555567016d0, event=event@entry=0x7fffffffae70) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1247
#15 0x00007ffff6f7144b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555567016d0, e=0x7fffffffae70) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3281
#16 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5555567016d0, event=0x7fffffffae70) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#17 0x00007ffff593ab1d in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1533
#18 0x00007ffff6fb8b0c in QWidgetPrivate::setGeometry_sys(int, int, int, int, bool) (this=this@entry=0x5555566aa4c0, x=434, y=0, w=<optimized out>, h=<optimized out>, isMove=<optimized out>, isMove@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7362
#19 0x00007ffff6fb953a in QWidget::setGeometry(QRect const&) (this=0x5555567016d0, r=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7250
#20 0x00007ffff704fbe1 in QAbstractScrollAreaPrivate::layoutChildren_helper(bool*, bool*) (this=<optimized out>, needHorizontalScrollbar=0x7fffffffb116, needVerticalScrollbar=0x7fffffffb117) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qabstractscrollarea.cpp:416
#21 0x00007ffff7184003 in QAbstractScrollAreaPrivate::layoutChildren() (this=0x555556782e90) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qabstractscrollarea.cpp:288
#22 QAbstractScrollAreaPrivate::_q_showOrHideScrollBars() (this=0x555556782e90) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qabstractscrollarea.cpp:1385
#23 QTextEditPrivate::_q_adjustScrollbars() (this=0x555556782e90) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qtextedit.cpp:296
#24 0x0000555555667d0e in MainWindow::setCurrentFontBasedOnTypeface(FontTypeface::Value) (this=0x7fffffffdbe8, selectedFontTypeFace=FontTypeface::SansSerif) at /home/gui/dev/notes/src/mainwindow.cpp:1059
#25 0x00005555556750a1 in MainWindow::eventFilter(QObject*, QEvent*) (this=0x7fffffffdbe8, object=0x5555566bac80, event=0x7fffffffbc20) at /home/gui/dev/notes/src/mainwindow.cpp:3581
#26 0x00007ffff59395d8 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (receiver=receiver@entry=0x5555566bac80, event=event@entry=0x7fffffffbc20) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1247
#27 0x00007ffff6f7144b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555566bac80, e=0x7fffffffbc20) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3281
#28 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5555566bac80, event=0x7fffffffbc20) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#29 0x00007ffff593ab1d in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1533
#30 0x00007ffff6fb8b0c in QWidgetPrivate::setGeometry_sys(int, int, int, int, bool) (this=this@entry=0x555556782e90, x=0, y=36, w=<optimized out>, h=<optimized out>, isMove=<optimized out>, isMove@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7362
#31 0x00007ffff6fb953a in QWidget::setGeometry(QRect const&) (this=0x5555566bac80, r=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7250
#32 0x00007ffff6fa081f in QWidget::setGeometry(int, int, int, int) (ah=<optimized out>, aw=<optimized out>, ay=<optimized out>, ax=<optimized out>, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.h:889
#33 QWidgetItem::setGeometry(QRect const&) (this=<optimized out>, rect=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayoutitem.cpp:478
#34 0x00007ffff6f80254 in QBoxLayout::setGeometry(QRect const&) (this=<optimized out>, r=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qboxlayout.cpp:791
#35 0x00007ffff6fa0621 in QLayoutPrivate::doResize() (this=0x55555673aef0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayout.cpp:507
#36 0x00007ffff6f714b0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555566f9270, e=0x7fffffffbf50) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3276
#37 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5555566f9270, event=0x7fffffffbf50) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#38 0x00007ffff593ab1d in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1533
#39 0x00007ffff6fb8b0c in QWidgetPrivate::setGeometry_sys(int, int, int, int, bool) (this=this@entry=0x5555566f0c20, x=370, y=0, w=<optimized out>, h=<optimized out>, isMove=<optimized out>, isMove@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7362
#40 0x00007ffff6fb953a in QWidget::setGeometry(QRect const&) (this=0x5555566f9270, r=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7250
#41 0x00007ffff71620f6 in QSplitterPrivate::setGeo(QSplitterLayoutStruct*, int, int, bool) (this=this@entry=0x555556107610, sls=sls@entry=0x5555566f0e90, p=370, s=s@entry=510, allowCollapse=allowCollapse@entry=false) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qsplitter.cpp:741
#42 0x00007ffff71628db in QSplitterPrivate::doResize() (this=0x555556107610) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qsplitter.cpp:529
#43 0x00007ffff6fbdab1 in QWidget::event(QEvent*) (this=0x5555563c97b0, event=0x7fffffffc350) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:9107
#44 0x00007ffff7050e76 in QFrame::event(QEvent*) (this=0x5555563c97b0, e=0x7fffffffc350) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qframe.cpp:515
#45 0x00007ffff6f7145b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555563c97b0, e=0x7fffffffc350) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3287
#46 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5555563c97b0, event=0x7fffffffc350) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#47 0x00007ffff593ab1d in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1533
#48 0x00007ffff6fb8b0c in QWidgetPrivate::setGeometry_sys(int, int, int, int, bool) (this=this@entry=0x555556107610, x=0, y=0, w=<optimized out>, h=<optimized out>, isMove=<optimized out>, isMove@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7362
#49 0x00007ffff6fb953a in QWidget::setGeometry(QRect const&) (this=0x5555563c97b0, r=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7250
#50 0x00007ffff6fa081f in QWidget::setGeometry(int, int, int, int) (ah=<optimized out>, aw=<optimized out>, ay=<optimized out>, ax=<optimized out>, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.h:889
#51 QWidgetItem::setGeometry(QRect const&) (this=<optimized out>, rect=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayoutitem.cpp:478
#52 0x00007ffff6f80254 in QBoxLayout::setGeometry(QRect const&) (this=<optimized out>, r=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qboxlayout.cpp:791
#53 0x00007ffff6fa0621 in QLayoutPrivate::doResize() (this=0x555556669850) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayout.cpp:507
#54 0x00007ffff6f714b0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555567093e0, e=0x7fffffffc680) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3276
#55 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5555567093e0, event=0x7fffffffc680) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#56 0x00007ffff593ab1d in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1533
#57 0x00007ffff6fb8b0c in QWidgetPrivate::setGeometry_sys(int, int, int, int, bool) (this=this@entry=0x5555563ee130, x=10, y=10, w=<optimized out>, h=<optimized out>, isMove=<optimized out>, isMove@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7362
#58 0x00007ffff6fb953a in QWidget::setGeometry(QRect const&) (this=0x5555567093e0, r=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7250
#59 0x00007ffff6fa081f in QWidget::setGeometry(int, int, int, int) (ah=<optimized out>, aw=<optimized out>, ay=<optimized out>, ax=<optimized out>, this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.h:889
#60 QWidgetItem::setGeometry(QRect const&) (this=<optimized out>, rect=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayoutitem.cpp:478
#61 0x00007ffff6fa0281 in QGridBox::setGeometry(QRect const&) (r=..., this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qgridlayout.cpp:47
#62 QGridLayoutPrivate::distribute(QRect, int, int) (vSpacing=<optimized out>, hSpacing=<optimized out>, r=..., this=0x55555615a0e0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qgridlayout.cpp:942
#63 QGridLayout::setGeometry(QRect const&) (this=0x555556716330, rect=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qgridlayout.cpp:1341
#64 0x00007ffff6fa0621 in QLayoutPrivate::doResize() (this=0x55555615a0e0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayout.cpp:507
#65 0x00007ffff6f714b0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x55555671ef00, e=0x7fffffffc980) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3276
#66 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55555671ef00, event=0x7fffffffc980) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#67 0x00007ffff593ab1d in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1533
#68 0x00007ffff6fb8b0c in QWidgetPrivate::setGeometry_sys(int, int, int, int, bool) (this=this@entry=0x5555567160e0, x=0, y=0, w=<optimized out>, h=<optimized out>, isMove=<optimized out>, isMove@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7362
#69 0x00007ffff6fb953a in QWidget::setGeometry(QRect const&) (this=0x55555671ef00, r=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidget.cpp:7250
#70 0x00007ffff6fc73d3 in QWidget::qt_metacall(QMetaObject::Call, int, void**) (this=0x55555671ef00, _c=QMetaObject::WriteProperty, _id=3, _a=0x7fffffffca60) at /usr/src/debug/qt6-base/build/src/widgets/Widgets_autogen/include/moc_qwidget.cpp:1038
#71 0x00007ffff5a5bcce in QPropertyAnimationPrivate::updateProperty(QVariant const&) (newValue=..., this=0x555556b8c870) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qpropertyanimation.cpp:104
#72 QPropertyAnimationPrivate::updateProperty(QVariant const&) (newValue=..., this=0x555556b8c870) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qpropertyanimation.cpp:90
#73 QPropertyAnimation::updateCurrentValue(QVariant const&) (this=<optimized out>, value=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qpropertyanimation.cpp:235
#74 0x00007ffff5a5da7d in QVariantAnimationPrivate::setCurrentValueForProgress(double) (progress=<optimized out>, this=0x555556b8c870) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qvariantanimation.cpp:253
#75 QVariantAnimationPrivate::recalculateCurrentInterval(bool) (this=this@entry=0x555556b8c870, force=force@entry=true) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qvariantanimation.cpp:236
#76 0x00007ffff5a618a4 in QVariantAnimationPrivate::setDefaultStartEndValue(QVariant const&) (value=..., this=0x555556b8c870) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qvariantanimation.cpp:300
#77 QPropertyAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State) (this=0x7fffe40057f0, newState=<optimized out>, oldState=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qpropertyanimation.cpp:282
#78 0x00007ffff5a55b89 in QAbstractAnimationPrivate::setState(QAbstractAnimation::State) (this=0x555556b8c870, newState=newState@entry=QAbstractAnimation::Running) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qabstractanimation.cpp:943
#79 0x00007ffff5a561ae in QAbstractAnimation::start(QAbstractAnimation::DeletionPolicy) (this=<optimized out>, policy=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/animation/qabstractanimation.cpp:1371
#80 0x00007ffff704defe in QWidgetAnimator::animate(QWidget*, QRect const&, bool) (this=<optimized out>, widget=<optimized out>, _final_geometry=<optimized out>, animate=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qwidgetanimator.cpp:77
#81 0x00007ffff70c1730 in QDockAreaLayout::apply(bool) (this=0x555556236c40, animate=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qdockarealayout.cpp:3165
#82 0x00007ffff710b32e in QMainWindowLayoutState::apply(bool) (animated=<optimized out>, this=0x555556236b28) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qmainwindowlayout.cpp:681
#83 QMainWindowLayout::applyState(QMainWindowLayoutState&, bool) (this=<optimized out>, newState=<optimized out>, animate=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/widgets/qmainwindowlayout.cpp:2954
#84 0x00007ffff6fa0621 in QLayoutPrivate::doResize() (this=this@entry=0x55555611b260) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayout.cpp:507
#85 0x00007ffff6fa181b in QLayout::activate() (this=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qlayout.cpp:1055
#86 0x00007ffff6f714b0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x7fffffffdbe8, e=0x7fffffffd3c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3276
#87 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7fffffffdbe8, event=0x7fffffffd3c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#88 0x00007ffff593ab0a in QCoreApplication::forwardEvent(QObject*, QEvent*, QEvent*) (receiver=<optimized out>, event=<optimized out>, originatingEvent=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1130
#89 0x00007ffff6fd67c2 in QWidgetWindow::handleResizeEvent(QResizeEvent*) (event=0x7fffffffd3c0, this=0x5555563f9e30) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidgetwindow.cpp:780
#90 QWidgetWindow::event(QEvent*) (this=0x5555563f9e30, event=0x7fffffffd3c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qwidgetwindow.cpp:263
#91 0x00007ffff6f7145b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x5555563f9e30, e=0x7fffffffd3c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/widgets/kernel/qapplication.cpp:3287
#92 0x00007ffff593aad8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x5555563f9e30, event=0x7fffffffd3c0) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1115
#93 0x00007ffff593ab2d in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qcoreapplication.cpp:1547
#94 0x00007ffff5fa0ef4 in QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent*) (e=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/kernel/qguiapplication.cpp:2666
#95 0x00007ffff600ed7c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (flags=flags@entry=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/gui/kernel/qwindowsysteminterface.cpp:1094
#96 0x00007ffff1687f9f in xcbSourceDispatch(GSource*, GSourceFunc, gpointer) (source=<optimized out>) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp:57
#97 0x00007ffff5052a31 in g_main_dispatch (context=0x7fffec000f10) at ../glib/glib/gmain.c:3460
#98 g_main_context_dispatch (context=0x7fffec000f10) at ../glib/glib/gmain.c:4200
#99 0x00007ffff50afcc9 in g_main_context_iterate.isra.0 (context=context@entry=0x7fffec000f10, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4276
#100 0x00007ffff50500e2 in g_main_context_iteration (context=0x7fffec000f10, may_block=1) at ../glib/glib/gmain.c:4343
#101 0x00007ffff5b344d4 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555560f0bf0, flags=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qeventdispatcher_glib.cpp:393
#102 0x00007ffff5944cd3 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (flags=..., this=0x7fffffffd700) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qeventloop.cpp:100
#103 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x7fffffffd700, flags=...) at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/kernel/qeventloop.cpp:182
#104 0x00007ffff593e378 in QCoreApplication::exec() () at /usr/src/debug/qt6-base/qtbase-everywhere-src-6.5.1/src/corelib/global/qflags.h:74
#105 0x000055555564fd20 in main(int, char**) (argc=1, argv=0x7fffffffe008) at /home/gui/dev/notes/src/main.cpp:97
guihkx commented 1 year ago

Two issues I found on Ubuntu 20.04:

nuttyartist commented 1 year ago

Two issues I found on Ubuntu 20.04:

  • [ ] There are some missing QML-related dependencies (probably just qml-module-qtquick-controls2) - I'll fix this
  • [ ] Even after installing the dependency above, the settings menu is blank and these two messages show up in the console:
    qrc:/qml/EditorSettings.qml:221:21: Type FontChooserButton unavailable
    qrc:/qml/FontChooserButton.qml:17:36: Expected token `identifier'

Can you please test if my latest commit fixes the issue?

nuttyartist commented 1 year ago

However, I found another major issue on Linux that causes the app to freeze and use a lot of CPU. Steps to reproduce:

I was able to reproduce this only once but can't anymore (it works fine). Does it consistently freeze for you?

guihkx commented 1 year ago

Can you please test if my latest commit fixes the issue?

I will soon.

I was able to reproduce this only once but can't anymore (it works fine). Does it consistently freeze for you?

Yep. It consistently reproduces on Windows 10 as well:

https://github.com/nuttyartist/notes/assets/626206/780e726b-9624-475f-8c2a-d717e58eadae

I forgot to mention this, but yesterday when I was trying to reproduce this on Linux, I was going to record a video of this bug on my second, smaller screen (which is 1368x760, while my main one is 1920x1080), because it's easier to see it in a video.

However I could no longer reproduce it whenever the app was sitting on my second smaller screen. 🤷

guihkx commented 12 months ago

The QML error on Ubuntu 20.04 has changed slightly (the menu still doesn't work tho):

qrc:/qml/EditorSettings.qml:221:21: Type FontChooserButton unavailable
qrc:/qml/FontChooserButton.qml:16:14: Expected token `:'
guihkx commented 12 months ago

I'm done squashing the commits.

I'm not a big fan of a very big commit, but splitting those 80+ commits into smaller ones would be complicated and probably very messy, especially since I did not write most of the changes. :P

nuttyartist commented 12 months ago

The QML error on Ubuntu 20.04 has changed slightly (the menu still doesn't work tho):

qrc:/qml/EditorSettings.qml:221:21: Type FontChooserButton unavailable
qrc:/qml/FontChooserButton.qml:16:14: Expected token `:'

Agh... that's so weird required properties not require initialization. Actually, I think initialization is either prohibited or actively discouraged in Qt6. The line in question:

required property var fontsModel

EDIT: I'll install Qt 5.12.8 and try to reproduce and solve the issue that way.

nuttyartist commented 12 months ago

Yep. It consistently reproduces on Windows 10 as well:

@guihkx I can't reproduce this on my Windows VM. Using the installer from Version: 2.1.0+g5934378

nuttyartist commented 12 months ago

Merging... (: