wxWidgets icon indicating copy to clipboard operation
wxWidgets copied to clipboard

when drag the wxAUI window edge, there are some ugly lines shows in the desktop like edge shadows

Open asmwarrior opened this issue 1 year ago • 45 comments

I'm on Windows 10 64bit, and by using wx 3.2.3, I see this issue, see the image below:

aui-edge-drag-ugly-lines

The ugly lines normally are parallel with the dragged wxAUI window edge, but shown in other places.

This issue happens not only on the wxAUI sample code, I see this in Code::Blocks from time to time. This is not a new issue in wx 3.2.3, but it happens for a very long time.

In the above image shot, my desk setting has NO DPI scale, I mean it is 100% on a screen 1920*1080 resolution.

Maybe, this issue is DPI related, see:

github issue: New AUI notebook splitter drawn at incorrect position when dragged on scaled display Issue #18098 wxWidgets/wxWidgets

github issue: wrong xor line is drawn when I drag the wxSplitterWindow' sash bar with wxSP_LIVE_UPDATE disabled Issue #18090 wxWidgets/wxWidgets

wx-user maillist discussion: wrong xor line is drawn when I drag the wxSplitterWindow' sash bar with wxSP_LIVE_UPDATE disabled

C::B forum discussion: ugly lines when I drag the aui panel in Code::Blocks

asmwarrior avatar Oct 22 '23 08:10 asmwarrior

Sorry, this is rather confusing: why do you think this is DPI-related if you're using normal DPI? The linked issues don't seem to have anything to do with this, especially because one of them is about wxSplitterWindow and not wxAUI at all.

What is really needed is a way to reproduce this reliably. I don't see the problem myself in master. Before I retest with 3.2.3, could you please at least tell if you see it when using live update (this can be toggled in the sample) or not and, also, if you have any precise instructions for reproducing it in the sample?

vadz avatar Oct 22 '23 13:10 vadz

Sorry, this is rather confusing: why do you think this is DPI-related if you're using normal DPI? The linked issues don't seem to have anything to do with this, especially because one of them is about wxSplitterWindow and not wxAUI at all.

This is only my guess, if I remember correctly, the sash bar in wxSplitterWindow also draw such kinds of gray shadow lines. In my mentioned github issues, it is DPI related. Anyway, this is only my guess.

What is really needed is a way to reproduce this reliably. I don't see the problem myself in master. Before I retest with 3.2.3, could you please at least tell if you see it when using live update (this can be toggled in the sample) or not

I just tried the "Live Resize Update" option enabled or disabled in wxAUI sample. I can only tell you that this option is disabled by default, so my screen shot (showing the ugly lines) was in the condition with this option disabled.

But sorry, I can't precisely reproduce this issue. Sometimes, it happens, and sometimes it doesn't. I will try to find a way to reproduce this bug.

asmwarrior avatar Oct 22 '23 14:10 asmwarrior

Hi, I think I can find a clean way to reproduce this bug.

This happens when I have multiple monitors. I have two monitors, the main monitor is my notebook monitor A 19201080 with 100%DPI, and another extended monitor B, it is 1600900 with 100 DPI scale.

Now if I start C::B or wxAUI sample in the monitor A, and than I drag the application from the monitor A to monitor B, and later drag the AUI window edge to resize it, I see that the shadow lines will be drawn in the monitor A.

EDIT: the shadow lines won't happen if I enable the "Live Resize Update" option in the wxAUI sample.

asmwarrior avatar Oct 23 '23 10:10 asmwarrior

My guess is that the shadow line drawing system has some cache. The cache may remember the monitor(display) where it was initially started. So, when I drag edges in monitor B, it still draws in monitor A.

asmwarrior avatar Oct 23 '23 10:10 asmwarrior

I suffer this issue also on my application just shaking the splitter long enough. The "live resize update" option reduces probability, but it is not zero.

I am using one monitor on MSW10 with wxWidgets 3.2.3.

wh11204 avatar Oct 23 '23 11:10 wh11204

If this is really multi-monitor specific I'm going to have trouble testing this because I don't have a multi-monitor Windows system any more (it's supposed to work with QEMU/KVM but it just doesn't for me... if anybody has any hints about setting this up, they'd be very welcome).

@wh11204 Just to make sure, do you mean AUI splitter or wxSplitterWindow?

vadz avatar Oct 23 '23 12:10 vadz

I mean the AUI splitter, as seen in the OP's image.

wh11204 avatar Oct 23 '23 15:10 wh11204

I found another issue, in my two monitor condition, when I drag the AUI splitter in monitor A, there is NO shadow lines(hint lines) shown around the mouse position. My guess is that in this case, the shadow lines were drawn out of the the screen.

Those shadow lines(hint lines) are drawn by the wxAUI system, so the position calculation is wrong here.

asmwarrior avatar Oct 24 '23 00:10 asmwarrior

wxWidgets-3.2.3\src\aui\framemanager.cpp

static void DrawResizeHint(wxDC& dc, const wxRect& rect)
{
    wxBitmap stipple = wxPaneCreateStippleBitmap();
    wxBrush brush(stipple);
    dc.SetBrush(brush);
#ifdef __WXMSW__
    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    PatBlt(GetHdcOf(*impl), rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight(), PATINVERT);
#else
    dc.SetPen(*wxTRANSPARENT_PEN);

    dc.SetLogicalFunction(wxXOR);
    dc.DrawRectangle(rect);
#endif
}

I just did some text search on the source files, the above function looks like to draw the hint lines.

void wxAuiManager::OnMotion(wxMouseEvent& event)
{
    // sometimes when Update() is called from inside this method,
    // a spurious mouse move event is generated; this check will make
    // sure that only real mouse moves will get anywhere in this method;
    // this appears to be a bug somewhere, and I don't know where the
    // mouse move event is being generated.  only verified on MSW

    wxPoint mouse_pos = event.GetPosition();
    if (m_lastMouseMove == mouse_pos)
        return;
    m_lastMouseMove = mouse_pos;


    if (m_action == actionResize)
    {
        // It's necessary to reset m_actionPart since it destroyed
        // by the Update within DoEndResizeAction.
        if (m_currentDragItem != -1)
            m_actionPart = & (m_uiParts.Item(m_currentDragItem));
        else
            m_currentDragItem = m_uiParts.Index(* m_actionPart);

        if (m_actionPart)
        {
            wxPoint pos = m_actionPart->rect.GetPosition();
            if (m_actionPart->orientation == wxHORIZONTAL)
                pos.y = wxMax(0, event.m_y - m_actionOffset.y);
            else
                pos.x = wxMax(0, event.m_x - m_actionOffset.x);

            if (HasLiveResize())
            {
                m_frame->ReleaseMouse();
                DoEndResizeAction(event);
                m_frame->CaptureMouse();
            }
            else
            {
                wxRect rect(m_frame->ClientToScreen(pos),
                    m_actionPart->rect.GetSize());
                wxScreenDC dc;

                if (!m_actionHintRect.IsEmpty())
                {
                    // remove old resize hint
                    DrawResizeHint(dc, m_actionHintRect);
                    m_actionHintRect = wxRect();
                }

                // draw new resize hint, if it's inside the managed frame
                wxRect frameScreenRect = m_frame->GetScreenRect();
                if (frameScreenRect.Contains(rect))
                {
                    DrawResizeHint(dc, rect);
                    m_actionHintRect = rect;
                }
            }
        }
    }

The code above may draw the hint lines. My guess is that the

wxScreenDC dc;

Is not correct?

wxWidgets: wxScreenDC Class Reference

It said:

A wxScreenDC can be used to paint on the screen.

This should normally be constructed as a temporary stack object; don't store a wxScreenDC object.

When using multiple monitors, wxScreenDC corresponds to the entire virtual screen composed of all of them. Notice that coordinates on wxScreenDC can be negative in this case, see wxDisplay::GetGeometry() for more.

So, this is the whole desktop???

We just need a single desktop where the application frame locates.

asmwarrior avatar Oct 24 '23 01:10 asmwarrior

I read some source code especially in src/aui/framemanager.cpp, and I see that when it try to draw something(hint lines or hint rectangles) on the wxScreenDC, the coordinates were translated to virtual screen coordinates by the wxWindow::ClientToScreen(). Maybe this function got the wrong coordinates.

asmwarrior avatar Nov 01 '23 03:11 asmwarrior

I just build a debug version of wx 3.2.3, and try to debug it. I found that the reason is ClientToScreen function only return the coordinates of the current desktop(screen), not the whole desktop. But when it try to draw the rectangle, it use the wxScreenDC, and which is in the whole desktop. So, it draws on the wrong place.

I'm not sure why the ClientToScreen failed, I see it correctly pass the window HWND, the coordinates of relative to the current wxFrame to the Windows API.

asmwarrior avatar Nov 04 '23 08:11 asmwarrior

Maybe this article is related, ScreenToVirtual, also this article: The Virtual Screen - Win32 apps | Microsoft Learn

It looks like the virtual screen coordinates' origin are the top left point of the primary screen. (As mentioned in the above Microsoft link)

But when wx try to draw on the wxScreenDC, the origin is on my other screen's top left point.

asmwarrior avatar Nov 04 '23 08:11 asmwarrior

I just upload the image here, suppose I have monitor 1 and monitor 2.

image

In the image, the red arrow is the origin of the ClientToScreen returned coordinates.

While when we draw the rectangle, it looks like the wxScreenDC has the origin pointed by blue arrow.

asmwarrior avatar Nov 04 '23 12:11 asmwarrior

Are you sure about wxScreenDC origin part? I'd expect it to be at the top left corner of the primary monitor too.

This is, of course, easy to test: just write a tiny program drawing a line from (0,0) to (1000,1000) using wxScreenDC and check where does it appear.

vadz avatar Nov 04 '23 13:11 vadz

image

This is the screen shot of my primary monitor 1, a very simple wx program

    void OnMouseMotion(wxMouseEvent& event)
    {
        if (event.Dragging() && event.LeftIsDown())
        {
                wxScreenDC dc;
                wxPen pen(wxColor(255, 0, 0), 5);
                dc.SetPen(pen);
                dc.DrawLine(0, 0, 3000, 500);

        }
    }

My monitor 1 is 1920x1080 with 100%DPI, and the extended monitor 2 is 1600x900 with 100 DPI scale.

Please note that in my test case, I have only monitor 1. I have unplugged the monitor 2, which means I only have one monitor. But it looks like the wxScreenDC are still using the top left corner of the monitor 2 as the origin.

asmwarrior avatar Nov 04 '23 14:11 asmwarrior

I don't understand how can wxScreenDC "know" about the other monitor if you don't see it in Windows any more. We do need to stop using wxScreenDC anyhow, but this is not that simple to do, unfortunately.

vadz avatar Nov 04 '23 15:11 vadz

My guess is maybe wxScreenDC caches some states that I had two monitors.

asmwarrior avatar Nov 04 '23 15:11 asmwarrior

I can reproduce it too with a monitor setup like in the image from @asmwarrior

I can fix drawing on the main monitor by using:

                    rect.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
                    rect.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
                    DrawResizeHint(dc, rect);
                    m_actionHintRect = rect;

Note that the hint is drawn with PatBlt, and not wxScreenDC directly: https://github.com/wxWidgets/wxWidgets/blob/9bae94022c6aa8bb2b1b207f0f64bc362e5cd6af/src/aui/framemanager.cpp#L283-L286

Also I'm not able to get it to draw hints on the top-left monitor at all.

MaartenBent avatar Nov 04 '23 15:11 MaartenBent

After logging out and in again, this patch doesn't work anymore, but the unmodified code works fine. Seems like it is only an issue when you change monitor layout without logging out/in or restarting.

MaartenBent avatar Nov 04 '23 15:11 MaartenBent

Hi, @MaartenBent thanks for the test.

Do we need some method to detect the display changes? I mean when a monitor added or removed, we should know the display got changed?

Search on the internet, I found this:

Multiple Display Monitors - Win32 apps | Microsoft Learn

Maybe, there are some API's to query the values, or maybe we can catch some event.

Thanks.

asmwarrior avatar Nov 04 '23 22:11 asmwarrior

I can fix drawing on the main monitor by using:

                    rect.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
                    rect.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
                    DrawResizeHint(dc, rect);
                    m_actionHintRect = rect;

Note that the hint is drawn with PatBlt, and not wxScreenDC directly:

https://github.com/wxWidgets/wxWidgets/blob/9bae94022c6aa8bb2b1b207f0f64bc362e5cd6af/src/aui/framemanager.cpp#L283-L286

Also I'm not able to get it to draw hints on the top-left monitor at all.

With the above code patch, I see you just "Add" a X,Y coordinates shift to the rect's position.

Do you mean that by adding this shift, the PatBlt function just sets the monitor 2's top left corner as the origin?

After logging out and in again, this patch doesn't work anymore, but the unmodified code works fine. Seems like it is only an issue when you change monitor layout without logging out/in or restarting.

I haven't tested your patch, but it looks like if I log out and log in, if I have only one monitor, the GetSystemMetrics(SM_XVIRTUALSCREEN) and GetSystemMetrics(SM_YVIRTUALSCREEN) should be 0.

GetSystemMetrics function (winuser.h) - Win32 apps | Microsoft Learn

asmwarrior avatar Nov 04 '23 23:11 asmwarrior

OK, I wrote a simple program(which is mostly generated by chatGPT)

#include <Windows.h>
#include <iostream>

int main()
{
    int numMonitors = GetSystemMetrics(SM_CMONITORS);
    std::cout << "Number of Monitors: " << numMonitors << std::endl;

    int virtualScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    int virtualScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    std::cout << "Virtual Screen Width: " << virtualScreenWidth << std::endl;
    std::cout << "Virtual Screen Height: " << virtualScreenHeight << std::endl;


    int virtualScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
    int virtualScreenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
    std::cout << "Virtual Screen X: " << virtualScreenX << std::endl;
    std::cout << "Virtual Screen Y: " << virtualScreenY << std::endl;

    return 0;
}

The result is:

Number of Monitors: 2
Virtual Screen Width: 3520
Virtual Screen Height: 1080
Virtual Screen X: -1600
Virtual Screen Y: 0

So, I think we need the GetSystemMetrics(SM_XVIRTUALSCREEN); and GetSystemMetrics(SM_YVIRTUALSCREEN) instead of the SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN. Which is the X,Y position of the monitor 2. When I have only one monitor, those two values should be 0.

asmwarrior avatar Nov 05 '23 00:11 asmwarrior

I wrote another test:

    void OnMouseMotion(wxMouseEvent& event)
    {
        if (event.Dragging() && event.LeftIsDown())
        {
            wxScreenDC dc;
            wxPen pen(wxColor(255, 0, 0), 5);
            dc.SetPen(pen);
            int virtualScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
            int virtualScreenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
            dc.DrawLine(0 + virtualScreenX, 0 + virtualScreenY, 1000 + virtualScreenX, 500 + virtualScreenY);

        }
    }

It looks like in this case, I can draw the line from (0,0) to (1000, 500) in the expected position in the monitor 1, see below image shot:

image

But it looks like the wxScreenDC has some issue, and it mistakenly copies monitor 2's area to monitor 1, so you can see the blue background.

asmwarrior avatar Nov 05 '23 01:11 asmwarrior

https://github.com/wxWidgets/wxWidgets/blob/9bae94022c6aa8bb2b1b207f0f64bc362e5cd6af/src/msw/dc.cpp#L976

When debugging, I see this line has a typo, whether.

asmwarrior avatar Nov 05 '23 02:11 asmwarrior

I did a pure Windows C++ application, which is also generated by chatGPT, I try to draw a line from (0,0) to (virtualScreenWidth, virtualScreenHeight), in my test case, it is (0,0) to (3520, 1080).

#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_PAINT:
        {
            HDC hdc = GetDC(nullptr); // Get the desktop DC

            // Get the virtual screen dimensions
            int virtualScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
            int virtualScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);

            // Create a pen and select it into the device context
            HPEN pen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
            SelectObject(hdc, pen);

            // Draw a line from top-left to bottom-right of the virtual screen
            MoveToEx(hdc, 0, 0, nullptr);
            LineTo(hdc, virtualScreenWidth, virtualScreenHeight);

            // Clean up
            DeleteObject(pen);
            ReleaseDC(nullptr, hdc);
            return 0;
        }

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // Register the window class
    const wchar_t CLASS_NAME[] = L"MyWindowClass";

    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    // Create the window
    HWND hwnd = CreateWindowEx(
        0,                      // Optional window styles
        CLASS_NAME,             // Window class name
        L"Draw on Virtual Screen", // Window title
        WS_OVERLAPPEDWINDOW,    // Window style
        CW_USEDEFAULT,          // X position
        CW_USEDEFAULT,          // Y position
        CW_USEDEFAULT,          // Width
        CW_USEDEFAULT,          // Height
        nullptr,                // Parent window
        nullptr,                // Menu
        hInstance,              // Instance handle
        nullptr                 // Additional application data
    );

    if (hwnd == nullptr)
        return 0;

    ShowWindow(hwnd, nCmdShow);

    // Run the message loop
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

But the result screen shot shows that the line is NOT start from the (0,0) of the monitor 1(the top left of monitor 1).

See image shot below of the monitor 1

image

asmwarrior avatar Nov 05 '23 02:11 asmwarrior

I just skimmed the thread, so I apologize in advance if I missed something.

Are you sure that the top left coordinate of your left monitor is 0,0? I have two monitors side by side, the right one being my primary display (DISPLAY1 in the screenshot below) and it has display coordinates starting with 0,0 but my left screen (DISPLAY2) has negative x coordinates:

I think if one really wants the top-left coordinate of the whole virtual screen (not sure if this is the case here), this should be obtained with ::GetSystemMetrics(SM_XVIRTUALSCREEN) and ::GetSystemMetrics(SM_YVIRTUALSCREEN).

EDIT Removed the edits created in confusion.

PBfordev avatar Nov 05 '23 13:11 PBfordev

I tried the win32 line example with SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN instead of 0, 0. I moved monitor 2 from the right to the position in the screenshot. Virtual screen coordinates are -1920;-1040 It won't draw the line on monitor 2. The line is flipped and shown on monitor 1 instead. And all kinds of weird artifacts show. Screenshot 2023-11-05 150300

It works correct after I logout and login again (with the same monitor layout). Line is shown on both monitors and no artifacts. The virtual screen coordinates and size are still the same. It must be something in Windows that messes things up.

The aui, splitter and sash examples all show the same problem. Because they use wxScreenDC. I have no idea how to fix this. Or even how to detect that this is happening.

MaartenBent avatar Nov 05 '23 14:11 MaartenBent

Hi, @MaartenBent I try to fix this issue today, and I have take several hours to debug and test the code to find the reason.

I first try to debug the wx source code, and later I see this issue also happens on a pure Win32 code.

Now, even a simple Win32 line drawing on the desktop fails, see my comment, screen shot and source code here: https://github.com/wxWidgets/wxWidgets/issues/23982#issuecomment-1793614165

The strange thing is:

Case A: If I put the primary monitor in the left, and the second monitor in the right, I don't see the issue in Win32 line drawing code.

Case B: But if I put the primary monitor in the right, and the second monitor in the left, I can see the issue.

Now, I think this is a bug from either the video driver or the Windows 10 itself, so I try to upgrade my Win10. In-fact, the upgrade feature is disable by myself, so I have to enable it, I'm not finishing the upgrade, but it looks like after running some update, I see that my "Win32 line drawing" issue in Case A is gone!!!

I will do more test tomorrow.

asmwarrior avatar Nov 05 '23 15:11 asmwarrior

I can't say I understand the virtual screen coordinates. Running this:

#include <wx/wx.h>

class MyFrame: public wxFrame
{
public:
    MyFrame(wxWindow* parent = nullptr) : wxFrame(parent, wxID_ANY, "Test")
    {
        wxPanel* mainPanel = new wxPanel(this);
        wxBoxSizer* mainPanelSizer = new wxBoxSizer(wxVERTICAL);

        wxButton* button = new wxButton(mainPanel, wxID_ANY, "Draw Screen Lines");
        mainPanelSizer->Add(button, wxSizerFlags().Expand().Border());
        button->Bind(wxEVT_BUTTON, &MyFrame::DrawScreenLines, this);

        wxTextCtrl* logCtrl = new wxTextCtrl(mainPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));
        mainPanelSizer->Add(logCtrl, wxSizerFlags().Proportion(1).Expand().Border());

        mainPanel->SetSizer(mainPanelSizer);
    }
private:
    void DrawScreenLines(wxCommandEvent&)
    {
        HDC screenDC = ::GetDC(nullptr);
        const int x      = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
        const int y      = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
        const int width  = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
        const int height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
        HPEN pen = ::CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
        HPEN oldPen = (HPEN)::SelectObject(screenDC, pen);

        if ( !screenDC )
            wxLogError("Could not obtain the screen DC!");
        if ( !::MoveToEx(screenDC, x, y, nullptr) )
            wxLogError("MoveToEx() failed!");
        if ( !::LineTo(screenDC, width, height) )
            wxLogError("LineTo() failed!");

        ::SelectObject(screenDC, oldPen);
        ::DeleteObject(pen);
        ::ReleaseDC(nullptr, screenDC);

        wxLogMessage("Screen DC x = %d, y = %d, width = %d, height = %d", x, y, width, height);
    }
};

class MyApp : public wxApp
{
    bool OnInit() override
    {
        (new MyFrame())->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

as DPI PMv2 aware application on Win10 setup where the primary screen (right) is 2560x1440@125% DPI and secondary 1680x1050@100 (left, vertically centered), I get this wx-screendc

I understand that I have different resolutions on the two displays, so there are "virtual height" pixels (black area on the top and bottom on the left), but I still find surprising that the line does not hit either corner.

PBfordev avatar Nov 05 '23 20:11 PBfordev

Hi, @PBfordev, thanks for the help!

I think I have the same behavior as yours.

I just run the code in your comment, I got the result:

Here is my monitor layout: image

And here is the result: image

You see, you draw a line from (x,y) to the (width, height).

The (x,y) is the top left corner of the virtual desktop, and the width is the total width of the desktop.

So, the above red line is correct.

If I make the monitors layout like below: image

I think it is still correct, I mean the top left corner is in the result image below(I pointed it by a red arrow)

image

Since the (0,0) is always the top left corner of the primary monitor, the (width, height) point exceeds the right boundary of the primary monitor, so it cannot be displayed.

After the update of my Win10, I think I don't see the ugly lines now. So maybe Microsoft has fixed such drawing issue in the update.

asmwarrior avatar Nov 06 '23 13:11 asmwarrior