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

[Bug] KryptonForms do not know how to do RTL setting correctly #343

Closed
Smurf-IV opened this issue Sep 13, 2021 · 15 comments
Closed

[Bug] KryptonForms do not know how to do RTL setting correctly #343

Smurf-IV opened this issue Sep 13, 2021 · 15 comments
Labels
awaiting feedback A fix for this issue has been implemented, waiting for feedback on the fix. bug Something isn't working help wanted Extra attention is needed superseded Another issue has superseded this one.

Comments

@Smurf-IV
Copy link
Member

As seen with the fix for #313
Both Set:
image

RightAlign only:
image

RTL Only:
image

Originally posted by @Smurf-IV in #313 (comment)

And an old reference to an active Component Krypton Bug:
ComponentFactory/Krypton#94

Smurf-IV added a commit that referenced this issue Sep 13, 2021
@Smurf-IV Smurf-IV added bug Something isn't working help wanted Extra attention is needed labels Sep 13, 2021
@Smurf-IV Smurf-IV changed the title KryptonForms do not know how to do RTL setting correctly [Bug] KryptonForms do not know how to do RTL setting correctly Sep 13, 2021
@Smurf-IV
Copy link
Member Author

Help needed with RTL Language Developers to check if Normal font in an RTL is revered like the Bug indicates above, or is "Normal" and only RTL languages are reversed, or it's the RTL font that does the standard reversing.

@PWagner1
Copy link
Contributor

Help needed with RTL Language Developers to check if Normal font in an RTL is revered like the Bug indicates above, or is "Normal" and only RTL languages are reversed, or it's the RTL font that does the standard reversing.

Posting a pinned comment to Discord

@Ahmed-Abdelhameed
Copy link
Contributor

Help needed with RTL Language Developers to check if Normal font in an RTL is revered like the Bug indicates above, or is "Normal" and only RTL languages are reversed, or it's the RTL font that does the standard reversing.

I'm not sure if I understand you correctly. Does my screenshot posted to the linked issue not help with this? If not, please try to elaborate and I'll be happy to help if it's still needed.

@Smurf-IV
Copy link
Member Author

@Ahmed-Abdelhameed Help needed is for a developer who has RTL set as the OS, would be needed to work out why the internals of Krypton do not work, and then to apply the fix across all components and related dll's (Navigator / Ribbon / Extended / etc.)
Your images are the same as the ones at the start of this bug.

But, you have also added that the Title elements should also be swapped around as well. 👍

@Ahmed-Abdelhameed
Copy link
Contributor

@Smurf-IV Okay, here's my progress so far...

First of all, I don't think the OS language or RTL plays a role here since the RightToLeft and RightToLeftLayout properties can be toggled regardless. Please correct me if I missed something but I got the same behavior when I tested on Windows with Arabic language (RTL layout).

So, after a lot of investigating, I figured out the cause of the text (and buttons) being flipped/mirrored. I'm not submitting a PR though because I don't have a complete solution yet. I'm just posting what I found so far and maybe you or @Wagnerp can pick up from where I left as you both obviously have more experience with the internals of Krypton than me.

The problem begins in the VisualForm.OnNonClientPaint() method, specifically at this line:

using (Graphics g = Graphics.FromHdc(_screenDC))

Here's the complete code for context:

// Create one the correct size and cache for future drawing
IntPtr hBitmap = PI.CreateCompatibleBitmap(hDC, windowBounds.Width, windowBounds.Height);

// If we managed to get a compatible bitmap
if (hBitmap != IntPtr.Zero)
{
    try
    {
        // Must use the screen device context for the bitmap when drawing into the 
        // bitmap otherwise the Opacity and RightToLeftLayout will not work correctly.
        PI.SelectObject(_screenDC, hBitmap);

        // Drawing is easier when using a Graphics instance
        using (Graphics g = Graphics.FromHdc(_screenDC))
        {
            WindowChromePaint(g, windowBounds);
        }

        // Now blit from the bitmap to the screen
        PI.BitBlt(hDC, 0, 0, windowBounds.Width, windowBounds.Height, _screenDC, 0, 0, PI.SRCCOPY);
    }
    finally
    {
        // Delete the temporary bitmap
        PI.DeleteObject(hBitmap);
    }
}
else
{
    // Drawing is easier when using a Graphics instance
    using Graphics g = Graphics.FromHdc(hDC);
    WindowChromePaint(g, windowBounds);
}

As you can see, it's using the screen's device context and only when that fails does it fall back to using the window's device context (i.e., hDC) in the else block. What I found out is that when creating a Graphics instance from the window's hdc, we get one that is already set up with RTL rendering (assuming RTL is enabled). However, when using the screen's device context, the Graphics instance is not set up for that (hence, the mirroring).

Now, I'm not entirely sure whether using the screen device context is necessary or how the caching mentioned in the code comment above works. If it's not necessary, then we can just get rid of the if block and use the code that's in the else block (i.e., Graphics.FromHdc(hDC)). If it is necessary, then we need to set up the Graphics instance to (un-)mirror the rendering. This can be achieved using something like the following:

using (Graphics g = Graphics.FromHdc(_screenDC))
{
    if (this.RightToLeftLayout && this.RightToLeft == RightToLeft.Yes)
    {
        g.TranslateTransform(windowBounds.Width, 0);
        g.ScaleTransform(-1, 1);
    }
    WindowChromePaint(g, windowBounds);
}

Using either of the fixes described above causes the RTL layout to work correctly (icon and text on the right, displayed correctly/unmirrored, and the buttons are on the left):

image

However, there are two things I still didn't figure out.

  1. Part of the form/border is still not displayed. I'm not sure why yet.
  2. Even though the buttons are now on the left, the HitTest (triggered by WM_NCHITTEST) still thinks they're on the right. So, the HitTest logic needs to be fixed too; I just didn't have enough time to investigate this part yet. Here's a demo that shows both issues:

RTL

@PWagner1
Copy link
Contributor

As per comment in #786, button specs including help should be flipped along with the hit areas.

@PWagner1
Copy link
Contributor

PWagner1 commented Jan 16, 2024

@Smurf-IV & @Ahmed-Abdelhameed These may help adjust the 'hit' targets, but they're not used in KForm

image

@giduac
Copy link
Contributor

giduac commented Jun 15, 2024

Hi @Smurf-IV,

Is this still being worked on?

@PWagner1
Copy link
Contributor

Hi @Smurf-IV,

Is this still being worked on?

Hi @giduac

No, but the bug still remains. Hit test logic needs to be flipped plus a slice of the KForm is sliced off. You can see for yourself if you toggle the RightToLeftLayout property.

@PWagner1
Copy link
Contributor

Hi @Smurf-IV

Do we know where the bug is on this one, or is it a case of creating a 'special' KForm?

@Smurf-IV
Copy link
Member Author

Do we know where the bug is on this one, or is it a case of creating a 'special' KForm?

@Ahmed-Abdelhameed: created a demo (As in the gif above), but did not supply it.
So yes, "we" will need to replicate of not supplied

@Smurf-IV Smurf-IV added the awaiting feedback A fix for this issue has been implemented, waiting for feedback on the fix. label Jun 23, 2024
@PWagner1
Copy link
Contributor

Do we know where the bug is on this one, or is it a case of creating a 'special' KForm?

@Ahmed-Abdelhameed: created a demo (As in the gif above), but did not supply it. So yes, "we" will need to replicate of not supplied

@Smurf-IV

I wonder if there's something in the WinForms repo that can be used?

@PWagner1
Copy link
Contributor

Hi @Smurf-IV

Created a demo, the behaviour is even more unusual...

RTLBug.zip

@PWagner1
Copy link
Contributor

Hi @Smurf-IV & @giduac

I think I've found something... look at https://github.com/dotnet/winforms/blob/main/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs, specifically lines 867 - 873...

@PWagner1 PWagner1 added the superseded Another issue has superseded this one. label Jul 4, 2024
@PWagner1
Copy link
Contributor

PWagner1 commented Jul 4, 2024

Superseded by #1570

@PWagner1 PWagner1 closed this as completed Jul 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting feedback A fix for this issue has been implemented, waiting for feedback on the fix. bug Something isn't working help wanted Extra attention is needed superseded Another issue has superseded this one.
Projects
None yet
Development

No branches or pull requests

4 participants