Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@brian6932
Copy link
Contributor

@brian6932 brian6932 commented Jul 29, 2025

This is a feature from qView I use, and really like.

  • I haven't been able to get it to work as fast and smoothly as qView though. The performance of this PR doesn't feel good enough to be out of draft Imo. I don't know if it's my fault, notan's, or egui's tbh. I actually can't get holding a folder direction (scrubbing) at all to really be as fast as qView (when on a fast drive; however, Oculante seems much faster when viewing things off a NAS, disregarding this PR), relative to qView's Preloading = Extended, and Oculante's Number of images to cache = 1000. I'm open to ideas here, and if that should be done in a separate PR, that's perfectly fine and understandable too.
  • The scrubber, info, and header panels aren't offset/accounted for yet, should be doable with state though. Zen mode non-borderless is the primary way I see people using this, it's how I used qView anyway.
  • I chose to center images at the center of the screen, instead of the center of the previous image (which is what qView does). I don't think this really matters, as long as it's within bounds. This keeps it more in bounds than qView does.
  • I don't know if there's a way to check whether a window's maximized in notan. qView doesn't resize maximized windows, and realistically this feature shouldn't either, but I haven't found a way to do that yet.
  • qView maintains the aspect ratio of the window to the image, I think that looks better than the way I did it, which occasionally doesn't fit windows perfectly, because each dimension's checked for individually.
  • Ideally screen_size would be determined before any windows were initialized, this isn't possible with notan. If it was, that'd remove the code in the update function, and avoid repeating the branch. I think glutin may support this, but I wasn't going to add a dependency for no reason here.
  • There should be an event that gets spawned when you've moved the window from one monitor to another, currently max_window_size is determined by the launched monitor. Launching the program on a monitor's currently required to set this automatically.
  • Ignore the default state of the setting for now, it's just for testing.

@Stoppedpuma
Copy link
Collaborator

Stoppedpuma commented Jul 30, 2025

I'm not entirely sure on this feature. I'm not really sure who it's for, a good use case for it, and how well this will work between Windows, Mac, Linux, BSD. I'm already currently unable to run this PR under Sway (uses wayland). To me this feature feels weird to have but I also don't really have a use case for this. Is there anything in particular that makes this feature useful for you? A few examples would be great so I can get an understanding!

Notan will likely end up being dropped sometime soon. The reasoning behind this is that it's being deprecated. There's also some things that have been a bit of a headache like not being able to update egui until recently because Notan has been very slow in development for a while. Woelper was invited to be an admin of the Notan repo so he could maintain it if he wanted, but we are instead considering either going with Bevy, or completely on our own since we believe it will be easier in the long run.

relative to qView's Preloading = Extended, and Oculante's Number of images to cache = 1000. I'm open to ideas here, and if that should be done in a separate PR, that's perfectly fine and understandable too.

Some ideas we've had are caching an entire directory (not sure if we want a flag, keybind, or what), and allow "cache ahead" as an option. If you in interested in this, it should be a separate PR.

@brian6932
Copy link
Contributor Author

brian6932 commented Jul 30, 2025

how well this will work between Windows, Mac, Linux, BSD.

This feature's intended for people that use floating window managers, I don't see why it wouldn't work well across platforms, qView manages that just fine. I obviously wouldn't enable it by default normally, hence the:

  • Ignore the default state of the setting for now, it's just for testing.

Is there anything in particular that makes this feature useful for you?

On floating window managers, it's nice to have the a program's window be as small and space-efficient as possible, especially when browsing images, it just looks nice and saves space 🤷. I personally prefer not to resize my window, or have it be the full size of my screen when it's unnecessary. This feature was one of the main reasons I chose to use qView in the first place. I'm not using qView or Oculante to do much editing, even if they can do it, just to view an image (gallery).

A few examples would be great so I can get an understanding!

When working on an image in Photoshop (I pretty much always use it maximized, as it doesn't scale very well to smaller dimensions), I often set an image viewer window to always on top through my wm, and save an image as a snapshot of the past. It's useful to me for comparing what I'm working on, to it's past state at a glance. This avoids having to potentially overwrite, and/or fiddle with a very long undo history. Having the window auto-sized to it's smallest possible without scaling, and even when it's still too big, Fit image on window resize (I use the equivalent of this feature on qView too) lets you scale down from the largest dimensions, to the smallest you're ok with.

I'd recommend trying out qView's approach, if you want to see how it'd be better implemented.

Some ideas we've had are caching an entire directory (not sure if we want a flag, keybind, or what), and allow "cache ahead" as an option.

Yea, one thought I had when writing this, was maybe storing the pre-computed window dimensions+positions queued per image, and then just apply them as a cached property, I'm unsure how much it'd help, but it's an idea I had regardless. Each time max_window_size and min_window_size change, you'd have to re-update the cache.

@Stoppedpuma
Copy link
Collaborator

This feature's intended for people that use floating window managers, I don't see why it wouldn't work well across platforms, qView manages that just fine.

I say this because some window managers may have issues with this. For example, Hyprland is anything but stable and is filled with weird bugs that no other window manager has. A good example is right-click context menus just disappearing all together sometimes and requiring a complete restart of the application, or them just appearing in random spots around the screen.

Even on Sway, qView seems to like to resize the window towards the left side of the screen (or maybe this is intentional on qviews part?) instead of being in the centre. Nor can I get Oculante to run with this PR under Sway.

Yea, one thought I had when writing this, was maybe storing the pre-computed window dimensions+positions queued per image, and then just apply them as a cached property, I'm unsure how much it'd help, but it's an idea I had regardless. Each time max_window_size and min_window_size change, you'd have to re-update the cache.

This would mean just expanding the current caching option we currently have. This works by caching to memory, not disk. Caching ahead would basically just cache the next x amount of images, caching the entire directory would be self explanatory. I'm assuming you're concern means that it would have to update if the user changes the fitting percentage?

@brian6932
Copy link
Contributor Author

brian6932 commented Jul 30, 2025

I'm assuming you're concern means that it would have to update if the user changes the fitting percentage?

Ah sorry, not concerned, just thinking out loud. I'm not really sure of how to improve the performance in a meaningful way right now, caching dimensions+position may help just a little bit, but I really don't think that they're what's causing the lag (I even tried disabling position calculation altogether, and testing was still just as laggy). I tried to move the execution of the fit_window_to_image from the update function->draw->process_events, which as far as I understand is the earliest point this can even be set, that's why I don't know if it's my fault, notan's, or egui's tbh. There's no reason that simply resizing a window should be as slow as it is.

Nor can I get Oculante to run with this PR under Sway.

Hmm I wonder why, it could be related to it not liking that I'm setting a max window size, other than that I don't really see why it wouldn't work. I initialize max to u32::max_value(), I think that's the most likely to break anything here.

@Stoppedpuma
Copy link
Collaborator

Stoppedpuma commented Jul 30, 2025

that's why I don't know if it's my fault, notan's, or egui's tbh. There's no reason that simply resizing a window should be as slow as it is.

If you feel up to a bit of refactoring, see how well it works against #666 since the Notan update brings egui up to date. It's currently pretty outdated (over a year). Beware that this branch is very buggy, not at all ready to daily drive in its current state.

Hmm I wonder why, it could be related to it not liking that I'm setting a max window size, other than that I don't really see why it wouldn't work. I initialize max to u32::max_value(), I think that's the most likely to break anything here.

error: internal compiler error: compiler/rustc_mir_transform/src/validate.rs:80:25: broken MIR in Item(DefId(0:870 ~ libblur[14cf]::filter1d::avx::filter_rgb_row::filter_rgb_row_avx_u8_f32_impl)) (after phase change to runtime-optimized) at bb149[0]:
                                Projecting into SIMD type std::arch::x86_64::__m256i is banned by MCP#838
  --> /home/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libblur-0.14.10/avx/v_store.rs:69:10
   |
69 |     let (v0, v1, v2) = _mm256_interleave_rgb(v.0, v.1,...
   |          ^^


thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:80:25:

@woelper
Copy link
Owner

woelper commented Aug 1, 2025

Thanks for this!

Generally, for new features like this I would love if we could discuss the need for it before implementation is done so we make sure your time is valued. Nonetheless thank you for your work!

Am I understanding correctly that you just want the image to fit to the window at all times when a setting is active?

The image is just a texture, so resizing it every frame even should not be a performance issue. I could see that the resize signals might not be coming in fast enough to make it appear smoothly though.

@Stoppedpuma
Copy link
Collaborator

Thanks for this!

Generally, for new features like this I would love if we could discuss the need for it before implementation is done so we make sure your time is valued. Nonetheless thank you for your work!

Am I understanding correctly that you just want the image to fit to the window at all times when a setting is active?

The image is just a texture, so resizing it every frame even should not be a performance issue. I could see that the resize signals might not be coming in fast enough to make it appear smoothly though.

Here's a video of the behaviour in qView that the user is wanting to replicate in Oculante:

1754069617.mp4

@brian6932
Copy link
Contributor Author

brian6932 commented Aug 1, 2025

Am I understanding correctly that you just want the image to fit to the window at all times when a setting is active?

No, only when you first open the image. I want to be able to resize it after, intended to be used with Fit image on window resize, so you start out with the largest dimension, then can scale down. Basically this PR's a scuffed execution of qView's feature so far.

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