Skip to content
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

Image has wrong scale with multiple monitors in different scale #518

Open
jerome-cui opened this issue Oct 11, 2023 · 2 comments
Open

Image has wrong scale with multiple monitors in different scale #518

jerome-cui opened this issue Oct 11, 2023 · 2 comments

Comments

@jerome-cui
Copy link

jerome-cui commented Oct 11, 2023

I have my primary monitor scale at 150%, and the external monitor scale at 100%. Then qimgv will display image at wrong scale in the external monitor and not fill the window, just like below:
Screenshot_20231011_143012

System info:

OS: Kubuntu 23.04
Graphis platform: Wayland
KDE plasma: 5.27.8
Primary monitor: 3072 * 1920, 150%
External monitor: 1920 * 1080, 100%
Image size: 6885 * 4534

@jerome-cui jerome-cui changed the title Image has wrong scale with multiple monitors and in different scale Image has wrong scale with multiple monitors in different scale Oct 11, 2023
@jerome-cui
Copy link
Author

jerome-cui commented Oct 11, 2023

It is caused by the fixed dpr in ImageViewerV2, which the value is from the primary monitor. I fixed this issue with the following code updates:

diff --git a/qimgv/gui/viewers/imageviewerv2.cpp b/qimgv/gui/viewers/imageviewerv2.cpp
index 2bf906cd..571c5cfb 100644
--- a/qimgv/gui/viewers/imageviewerv2.cpp
+++ b/qimgv/gui/viewers/imageviewerv2.cpp
@@ -31,7 +31,7 @@ ImageViewerV2::ImageViewerV2(QWidget *parent) : QGraphicsView(parent),
     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     setAcceptDrops(false);

-    dpr = this->devicePixelRatioF();
+    // dpr = this->devicePixelRatioF();
     hs = horizontalScrollBar();
     vs = verticalScrollBar();

@@ -235,7 +235,7 @@ bool ImageViewerV2::showAnimationFrame(int frame) {

 void ImageViewerV2::updatePixmap(std::unique_ptr<QPixmap> newPixmap) {
     pixmap = std::move(newPixmap);
-    pixmap->setDevicePixelRatio(dpr);
+    pixmap->setDevicePixelRatio(this->devicePixelRatioF());
     pixmapItem.setPixmap(*pixmap);
     pixmapItem.show();
     pixmapItem.update();
@@ -276,7 +276,7 @@ void ImageViewerV2::showImage(std::unique_ptr<QPixmap> _pixmap) {
     if(_pixmap) {
         pixmapItemScaled.hide();
         pixmap = std::move(_pixmap);
-        pixmap->setDevicePixelRatio(dpr);
+        pixmap->setDevicePixelRatio(this->devicePixelRatioF());
         pixmapItem.setPixmap(*pixmap);
         Qt::TransformationMode mode = Qt::SmoothTransformation;
         if(mScalingFilter == QI_FILTER_NEAREST)
@@ -323,11 +323,11 @@ void ImageViewerV2::closeImage() {
 }

 void ImageViewerV2::setScaledPixmap(std::unique_ptr<QPixmap> newFrame) {
-    if(!movie && newFrame->size() != scaledSizeR() * dpr)
+    if(!movie && newFrame->size() != scaledSizeR() * this->devicePixelRatioF())
         return;

     pixmapScaled = std::move(newFrame);
-    pixmapScaled->setDevicePixelRatio(dpr);
+    pixmapScaled->setDevicePixelRatio(this->devicePixelRatioF());
     pixmapItemScaled.setPixmap(*pixmapScaled);
     pixmapItem.hide();
     pixmapItemScaled.show();
@@ -433,7 +433,7 @@ void ImageViewerV2::requestScaling() {
     // request "real" scaling when graphicsscene scaling is insufficient
     // (it uses a single pass bilinear which is sharp but produces artifacts on low zoom levels)
     if(currentScale() < FAST_SCALE_THRESHOLD)
-        emit scalingRequested(scaledSizeR() * dpr, mScalingFilter);
+        emit scalingRequested(scaledSizeR() * this->devicePixelRatioF(), mScalingFilter);
 }

 bool ImageViewerV2::imageFits() const {
@@ -517,7 +517,7 @@ void ImageViewerV2::mouseMoveEvent(QMouseEvent *event) {
     } else if(event->buttons() & Qt::RightButton) {
         // ------------------- ZOOM ----------------------
         // filter out possible mouse jitter by ignoring low delta drags
-        if(mouseInteraction == MouseInteractionState::MOUSE_ZOOM || abs(mousePressPos.y() - event->pos().y()) > zoomThreshold / dpr) {
+        if(mouseInteraction == MouseInteractionState::MOUSE_ZOOM || abs(mousePressPos.y() - event->pos().y()) > zoomThreshold / this->devicePixelRatioF()) {
             if(cursor().shape() != Qt::SizeVerCursor) {
                 setCursor(Qt::SizeVerCursor);
             }
@@ -677,7 +677,7 @@ void ImageViewerV2::mouseMoveZoom(QMouseEvent *event) {
     float stepMultiplier = 0.003f; // this one feels ok
     int currentPos = event->pos().y();
     int moveDistance = mouseMoveStartPos.y() - currentPos;
-    float newScale = currentScale() * (1.0f + stepMultiplier * moveDistance * dpr);
+    float newScale = currentScale() * (1.0f + stepMultiplier * moveDistance * this->devicePixelRatioF());
     mouseMoveStartPos = event->pos();
     imageFitMode = FIT_FREE;

@drocheam
Copy link

If I remember correctly, different scales between monitors aren't supported by X11, so this only affects Wayland.

Until this is fixed qimgv can also be run with enforced usage of X11:

env QT_QPA_PLATFORM=xcb qimgv

Also see https://wiki.archlinux.org/title/Wayland#Qt.

Or just add the environment variable QT_QPA_PLATFORM=xcb to the .desktop entry.

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

No branches or pull requests

2 participants