Bug 310497 - Zoom desktop effect only support POT cursor sizes
Summary: Zoom desktop effect only support POT cursor sizes
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: effects-various (show other bugs)
Version: 4.9.3
Platform: Arch Linux Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-11-22 12:38 UTC by Travis Evans
Modified: 2012-12-14 21:55 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In: 4.10


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Travis Evans 2012-11-22 12:38:05 UTC
When using the Zoom desktop effect, the size of mouse cursor selected in the cursor theme settings is not used. Instead, the standard size cursor appears to be used instead.

Reproducible: Always

Steps to Reproduce:
1. In Settings > Workspace Appearance > Cursor Theme, set the Oxygen Blue theme, size 48.
2. In Desktop Effects, enable Zoom and set the options to Zoom Factor 1.05, Mouse cursor to either “keep” or “hide”.
3. Zoom in a small amount
Actual Results:  
Mouse cursor changes from size 48 to what looks like size 24.

Expected Results:  
Mouse should stay at size 48.

This bug doesn't appear to happen when I use the size 72. However, when I'm zoomed out to normal, the mouse cursor is invisible most of the time and I get a lot of corruption/artifacts on the display for some reason with that size setting. (Nvidia driver Linux-x86_64 310.19, GeForce GT240)
Comment 1 Thomas Lübking 2012-11-22 18:48:21 UTC
It's actually more weired.
The cursor configured size is matched to the flooring power of two, then the curso image is fetched whatl in the case of eg. 24px leads to:

read: 24px
floor: 16px
image: 24px (cause at least here is no 16px for my theme)

What is obviously sick =)

@Seastian
do you recall why you added that POT clamping?
commit 58bbe497df888335cbf8be9cf52562b86b80a51a
Comment 2 Sebastian Sauer 2012-11-22 19:50:44 UTC
@Thomas

That is the "nominalCursorSize" function? That logic was taken from kde-workspace/kcontrol/input/xcursor/cursortheme.cpp.

The report wrote that "Mouse cursor changes from size 48 to what looks like size 24."
So, its correct at the beginning and has size 48 but on zoom it changes to 24 if I understood it correct? So, why? Zoom should have no influence.

I think the bug is in zoom.cpp:

[CODE]
    if (zoom != 1.0 && mousePointer != MousePointerHide) {
        // Draw the mouse-texture at the position matching to zoomed-in image of the desktop. Hiding the
        // previous mouse-cursor and drawing our own fake mouse-cursor is needed to be able to scale the
        // mouse-cursor up and to re-position those mouse-cursor to match to the chosen zoom-level.
        int w = imageWidth;
        int h = imageHeight;
        if (mousePointer == MousePointerScale) {
            w *= zoom;
            h *= zoom;
        }
        QPoint p = QCursor::pos();
        QRect rect(p.x() * zoom + data.xTranslation(), p.y() * zoom + data.yTranslation(), w, h);

        if (texture) {
            texture->bind();
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            texture->render(region, rect);
            texture->unbind();
            glDisable(GL_BLEND);
        }
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
        if (xrenderPicture) {
            if (mousePointer == MousePointerScale) {
                XRenderSetPictureFilter(display(), *xrenderPicture, const_cast<char*>("good"), NULL, 0);
                XTransform xform = {{
                    { XDoubleToFixed( 1.0 / zoom ), XDoubleToFixed( 0.0 ), XDoubleToFixed( 0.0 ) },
                    { XDoubleToFixed( 0.0 ), XDoubleToFixed( 1.0 / zoom ), XDoubleToFixed( 0.0 ) },
                    { XDoubleToFixed( 0.0 ), XDoubleToFixed( 0.0 ), XDoubleToFixed( 1.0 ) }
                }};
                XRenderSetPictureTransform( display(), *xrenderPicture, &xform );
            }
            XRenderComposite(display(), PictOpOver, *xrenderPicture, None, effects->xrenderBufferPicture(), 0, 0, 0, 0, rect.x(), rect.y(), rect.width(), rect.height());
            if (mousePointer == MousePointerScale)
                XRenderSetPictureTransform( display(), *xrenderPicture, &xrenderIdentity );
        }
#endif
    }
[/CODE]

See that the xrender codepath handles the mousePointer membervar correct but the gl path just uses the
Comment 3 Sebastian Sauer 2012-11-22 19:53:13 UTC
grrr. damn return-button. To complete my sentence above:

See that the xrender codepath handles the mousePointer membervar correct but the gl path just uses the QRect rect that calculates the zoom in without checking for the actual mousepointer state...

But that does still not explain why 48 becomes 24 at a zoom of 1.2. 48/1.2=40... hmmm
Comment 4 Sebastian Sauer 2012-11-22 19:56:30 UTC
One more try (to bad bugzilla does still not support editing in 2013! - Jira rocks):

Ah, since its only applied once zoom is active there is indeed a bug before already. But why is it 24px when read from the cursorTheme file if 48 got selected? hmmm...
Comment 5 Sebastian Sauer 2012-11-22 20:07:05 UTC
And last extension (start to dislike bugzilla more and more):

I see. Not a bug as noted before cause its only applied to x/y. That leaves the question why its 24 to begin with? I start to believe that the used Oxygen cursor theme (the class that inherits CursorTheme) does just use size*2.

That means we can't trust in the read cursorSize and need to fetch/load the CursorTheme instance and use something like cursorSize=cursorTheme->createIcon(cursorSize).size() or use the returned QPixmap direct what may even be better cause it seems there is no garantee that width==height and a cursor-theme could also do fancy things like manipulating the produced qpixmap by drawing the current time on it (just an example).
Comment 6 Thomas Lübking 2012-11-22 20:37:04 UTC
(In reply to comment #2)
> @Thomas
> 
> That is the "nominalCursorSize" function? That logic was taken from
> kde-workspace/kcontrol/input/xcursor/cursortheme.cpp.

Ok, thanks - not sure what they attempt to do there (try setting the size on the cursortheme kcm, 24 & 32 uses the same icons with obvious linear scaling in on case artifact ;-), but it seems quite unrelated to our task (getting the actually used current cursor size)

> The report wrote that "Mouse cursor changes from size 48 to what looks like size 24."
First rule about GUI bug handling: A dimension measured by the users eye and an empty bag are about as much worth as the bag.
It's not nice, but it's fact.

In this case however 48 will be clamped to 32 by nominalCursorSize and ultimately *might* be resolved to 24 (closer to 32 than 48) in case the theme does not provide 32px (so Travis could actually be right about the 24px =)

> Zoom should have no influence.
Yes, has. W/o zoom there's no texture displayed at all (but the regular cursor)

> I think the bug is in zoom.cpp:
>             texture->render(region, rect);

> See that the xrender codepath handles the mousePointer membervar 
> correct but the gl path just uses the gl path just uses the QRect rect that 
> calculates the zoom in without checking for the actual mousepointer state...

No, the GL code is ok. The rect parameter determines the size, the rect is calculated out of the pointer mode and the texture dimensions (imageWidth/imageHeight * MousePointerScale)

XRender is special cased, because it's often much more expensive on scales.

> But that does still not explain why 48 becomes 24 at a zoom of 1.2.

The scale factor s irrelevant. The dimension calculated from nominalCursorSize causes this gap.

(In reply to comment #5)
> I see. Not a bug as noted before cause its only applied to x/y. That leaves
> the question why its 24 to begin with? 

Trust me (or test yourself): skipping the nominalCursorSiz(iconSize) assignment fixes *this* issue, so if you don't have an actual reason for it, the solution is to drop it.

> I start to believe that the used Oxygen cursor theme
> (the class that inherits CursorTheme) does just use size*2.
No =) Happens with DMZ cursor theme as well.

> That means we can't trust in the read cursorSize
"Yes we can" -- Barack Obama

The size is read right when starting to zoom, unless it has been manipulated by hand or is altered during an active zoom, the value is ok (and it's not worth catching those cases)
Comment 7 Thomas Lübking 2012-12-14 21:55:11 UTC
Git commit ba8a494aca3a1c1c17a6d6b0d6f834ef7a02fd2e by Thomas Lübking.
Committed on 24/11/2012 at 17:50.
Pushed by luebking into branch 'master'.

kick pointless nominalCursor calculation

likely just copypasta from a broken kcm and gets
us a wrong dimensioned cursor texture
FIXED-IN: 4.10

M  +0    -12   kwin/effects/zoom/zoom.cpp

http://commits.kde.org/kde-workspace/ba8a494aca3a1c1c17a6d6b0d6f834ef7a02fd2e