Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions foo_spider_monkey_panel/js_objects/gdi_graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,10 @@ void JsGdiGraphics::DrawRect( float x, float y, float w, float h, float line_wid
void JsGdiGraphics::DrawRoundRect( float x, float y, float w, float h, float arc_width, float arc_height, float line_width, uint32_t colour )
{
qwr::QwrException::ExpectTrue( pGdi_, "Internal error: Gdiplus::Graphics object is null" );
qwr::QwrException::ExpectTrue( 2 * arc_width <= w && 2 * arc_height <= h, "Arc argument has invalid value" );

Gdiplus::Pen pen( colour, line_width );
Gdiplus::GraphicsPath gp;
GetRoundRectPath( gp, Gdiplus::RectF{ x, y, w, h }, arc_width, arc_height );
GetRoundRectPath( gp, Gdiplus::RectF{ x, y, w, h }, std::min( w / 2, arc_width ), std::min( h / 2, arc_height ) );

Gdiplus::Status gdiRet = pen.SetStartCap( Gdiplus::LineCapRound );
qwr::error::CheckGdi( gdiRet, "SetStartCap" );
Expand Down Expand Up @@ -435,12 +434,10 @@ void JsGdiGraphics::FillRoundRect( float x, float y, float w, float h, float arc
{
qwr::QwrException::ExpectTrue( pGdi_, "Internal error: Gdiplus::Graphics object is null" );

qwr::QwrException::ExpectTrue( 2 * arc_width <= w && 2 * arc_height <= h, "Arc argument has invalid value" );

Gdiplus::SolidBrush br( colour );
Gdiplus::GraphicsPath gp;
const Gdiplus::RectF rect{ x, y, w, h };
GetRoundRectPath( gp, rect, arc_width, arc_height );
GetRoundRectPath( gp, rect, std::min( w / 2, arc_width ), std::min( h / 2, arc_height ) );

Gdiplus::Status gdiRet = pGdi_->FillPath( &br, &gp );
qwr::error::CheckGdi( gdiRet, "FillPath" );
Expand Down
66 changes: 53 additions & 13 deletions foo_spider_monkey_panel/panel/js_panel_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,24 +306,54 @@ void js_panel_window::ExecuteEvent_Basic( EventId id )
{
break;
}

// from ms-docs: The update rectange retrieved by GetUpdateRect
// is identical to the one retrieved by the BeginPaint function.

// BeginPaint automatically validates the update region, so any
// call to GetUpdateRect made immediately after the call to BeginPaint
// retrieves an empty update region.

// skip redraw if the update rectangle is empty
CRect updateRect;
wnd_.GetUpdateRect( &updateRect, FALSE );
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might bork the repaint, since isBgRepaintNeeded_ won't be reset to false.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, that might be true, however the bg repaint would still be needed as it didn't really happen (?)

so now that i looked at the code / msdn docs for a while, it seems that isBgRepaintNeeded is set by the next case item (which is proxying from WM_ERASEBACKGROUND, and from OnSizeUser), with both cases occuring on a resize event indicating that the updateRect shouldn't be empty at all in these cases.
giving some mre tought, setting the flag here to false couldn't hurt (in the case of resizing the panel to 0 width/height)


if ( updateRect.IsRectEmpty() )
{
if ( settings_.isPseudoTransparent )
{
// theoretically a bg repaint is only needed when the user resizes the window (panel)
// however, in the case of the new size being 0 width/height and the WM_ERASEBACKGROUND
// still happening from the OS side:
// it should be safe to set the bg repaint needed flag to false
isBgRepaintNeeded_ = false;
}
break;
}

isPaintInProgress_ = true;

if ( settings_.isPseudoTransparent && isBgRepaintNeeded_ )
{ // Two pass redraw: paint BG > Repaint() > paint FG
CRect rc;
wnd_.GetUpdateRect( &rc, FALSE );
RepaintBackground( &rc ); ///< Calls Repaint() inside
{
// Two pass redraw: paint BG > Repaint() > paint FG
RepaintBackground( &updateRect ); ///< Calls Repaint() inside

isBgRepaintNeeded_ = false;
isPaintInProgress_ = false;

Repaint( true );
break;
}

{
///< BeginPaint() called here
CPaintDC dc{ wnd_ };
OnPaint( dc, dc.m_ps.rcPaint );
}
if ( dc.RectVisible( updateRect ) )
{
OnPaint( dc, updateRect );
}
///< Endpaint called here
};

isPaintInProgress_ = false;

Expand Down Expand Up @@ -1345,8 +1375,10 @@ void js_panel_window::RepaintBackground( const CRect& updateRc )
{
continue;
}

std::array<wchar_t, 64> buff;
GetClassName( hwnd, buff.data(), buff.size() );

if ( wcsstr( buff.data(), L"SysTabControl32" ) )
{
wnd_parent = hwnd;
Expand All @@ -1356,9 +1388,15 @@ void js_panel_window::RepaintBackground( const CRect& updateRc )

CRect rc_child{ 0, 0, static_cast<int>( width_ ), static_cast<int>( height_ ) };
CRgn rgn_child{ ::CreateRectRgnIndirect( &rc_child ) };
rgn_child.CombineRgn( ::CreateRectRgnIndirect( &updateRc ), RGN_DIFF );

CRect rc_combined{};
rgn_child.GetRgnBox( &rc_combined );

// bail out if the computed region('s bounding box) is empty
if ( rc_combined.IsRectEmpty() )
{
CRgn rgn{ ::CreateRectRgnIndirect( &updateRc ) };
rgn_child.CombineRgn( rgn, RGN_DIFF );
return;
}

CPoint pt{ 0, 0 };
Expand All @@ -1384,6 +1422,7 @@ void js_panel_window::RepaintBackground( const CRect& updateRc )
}

wnd_.SetWindowRgn( nullptr, FALSE );

if ( smp::config::EdgeStyle::NoEdge != settings_.edgeStyle )
{
wnd_.SendMessage( WM_NCPAINT, 1, 0 );
Expand Down Expand Up @@ -1675,11 +1714,12 @@ void js_panel_window::OnPaintJs( HDC memdc, const CRect& updateRc )
{
Gdiplus::Graphics gr( memdc );

// SetClip() may improve performance slightly
gr.SetClip( Gdiplus::Rect{ updateRc.left,
updateRc.top,
updateRc.Width(),
updateRc.Height() } );
// note: the default clip region is the update rect
// check if the redraw would be visible at all
if ( gr.IsClipEmpty() || gr.IsVisibleClipEmpty() )
{
return;
}

pJsContainer_->InvokeOnPaint( gr );
}
Expand Down
14 changes: 10 additions & 4 deletions foo_spider_monkey_panel/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@

// Spider Monkey ESR60 and CUI support only Win7+
#define _WIN32_WINNT _WIN32_WINNT_WIN7
#define WINVER _WIN32_WINNT_WIN7
#define WINVER _WIN32_WINNT_WIN7

// enable GdiPlus v1.1 features (available since Vista+)
#define GDIPVER 0x0110

// Fix std min max conflicts
#define NOMINMAX
#define NOMINMAX 1

#include <algorithm>

namespace Gdiplus
{
using std::min;
using std::max;
// note: not needed on SDK 19041+
using std::min;
using std::max;
};

#include <WinSock2.h>
Expand Down