Changeset 100


Ignore:
Timestamp:
Jul 23, 2006, 9:21:05 PM (19 years ago)
Author:
dmik
Message:

Widgets: Fixed:

  • Siblings of top-level widgets were not clipped out when drawing in those widgets.
  • Scrolling a widget partly placed outside screen bounds could produce garbage.
  • Scrolling a widget placed under a top-level widget (tooltip, popup) could produce garbage.
  • Widget's invalid region was not updated (shifted) when scrolling.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel/qwidget_pm.cpp

    r97 r100  
    112112}
    113113
    114 /** \internal flags for qt_WinProcessWindowObstacles() */
    115 enum {
    116     PWO_Children = 0x01,
    117     PWO_Sibings = 0x02,
    118     PWO_Ancestors = 0x04,
    119     PWO_TopLevel = 0x80000000,
    120     // PWO_Default is suitable in most cases (for simple paint operations)
    121     PWO_Default = PWO_Children | PWO_Sibings | PWO_Ancestors,
    122 };
    123 
    124114/**
    125115 *  \internal
     
    216206}
    217207
     208/** \internal flags for qt_WinProcessWindowObstacles() */
     209enum {
     210    PWO_Children = 0x01,
     211    PWO_Sibings = 0x02,
     212    PWO_Ancestors = 0x04,
     213    PWO_Screen = 0x08,
     214    PWO_TopLevel = 0x80000000,
     215    // PWO_Default is suitable in most cases (for simple paint operations)
     216    PWO_Default = PWO_Children | PWO_Sibings | PWO_Ancestors | PWO_Screen,
     217};
     218
    218219/**
    219220 *  \internal
     
    257258    HWND relative;
    258259    SWP swp;
    259    
    260     // first, go through all children (in z-order)
     260
     261    // first, process areas placed outside the screen bounds
     262    if ( flags & PWO_Screen ) {
     263        RECTL rclScr = { 0, 0, QApplication::desktop()->width(),
     264                               QApplication::desktop()->height() };
     265        WinMapWindowPoints( HWND_DESKTOP, hwnd, (PPOINTL) &rclScr, 2 );
     266        // rough check of whether some window part is outside bounds
     267        if ( rclSelf.xLeft < rclScr.xLeft ||
     268             rclSelf.yBottom < rclScr.yBottom ||
     269             rclSelf.xRight > rclScr.xRight ||
     270             rclSelf.yTop > rclScr.yTop ) {
     271            GpiSetRegion( displayPS, whrgn, 1, &rclSelf );
     272            HRGN hrgnScr = GpiCreateRegion( displayPS, 1, &rclScr );
     273            // substract the screen region from this window's region
     274            // to get parts placed outside
     275            GpiCombineRegion( displayPS, whrgn, whrgn, hrgnScr, CRGN_DIFF );
     276            GpiDestroyRegion( displayPS, hrgnScr );
     277            // process the region
     278            if ( hrgn != NULLHANDLE ) {
     279                cmplx = GpiCombineRegion( displayPS, hrgn, hrgn, whrgn, op );
     280            } else {
     281                WinValidateRegion( hwnd, whrgn, FALSE );
     282            }
     283#if defined (DEBUG_WIDGETMASK)
     284            qDebug( " collected areas outside screen bounds" );
     285#endif
     286         }
     287    }
     288   
     289    // next, go through all children (in z-order)
    261290    if ( flags & PWO_Children ) {
    262291        relative = WinQueryWindow( hwnd, QW_BOTTOM );
     
    289318                }
    290319#if defined (DEBUG_WIDGETMASK)
    291                 qDebug( "  extracted" );
     320                qDebug( "  collected" );
    292321#endif
    293322            }
     
    331360            }
    332361#if defined (DEBUG_WIDGETMASK)
    333             qDebug( "  extracted" );
     362            qDebug( "  collected" );
    334363#endif
    335364        }
     
    392421                }
    393422#if defined (DEBUG_WIDGETMASK)
    394                 qDebug( "  extracted" );
     423                qDebug( "  collected" );
    395424#endif
    396425            }
     
    759788        // areas outside the clip region are left unpainted. Instead, we correct
    760789        // the update region of the window ourselves, on every WM_PAINT event.
     790        // Note: for top-level widgets, we specify WS_CLIPSIBLINGS anyway to let
     791        // the system do correct clipping for us (qt_WinProcessWindowObstacles()
     792        // relies on this). It's ok because top-level widgets cannot be non-
     793        // rectangular and therefore don't require our magic clipping procedure.
     794        if ( topLevel /* && !testWFlags( WPaintUnclipped ) */ )
     795            style |= WS_CLIPSIBLINGS;
    761796#else
    762797        /// @todo (dmik)
     
    765800        //  box and list view. This needs to be investigated. Qt/Win32 does also
    766801        //  comment this out...
    767         /* if ( !testWFlags( WPaintUnclipped ) ) */
    768             style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
     802        /* if ( !testWFlags( WPaintUnclipped ) ) */
     803                style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    769804#endif           
    770805        // for all top-level windows except popups we create a WC_FRAME
     
    21502185        HWND i = id;
    21512186        while( (i = WinQueryWindow( i, QW_PREV )) ) {
    2152             if ( WinIsWindowShowing( i ) ) {
     2187            if ( WinIsWindowVisible( i ) ) {
    21532188                WinQueryWindowRect( i, &r );
    21542189                WinMapWindowPoints( i, hwnd, (PPOINTL) &r, 2 );
     
    23062341    HPS hps = WinGetPS( hwnd );
    23072342
     2343    // get the current update (invalid) region
     2344    HRGN hrgnInv = GpiCreateRegion( hps, 0, NULL );
     2345    if ( WinQueryUpdateRegion( hwnd, hrgnInv ) != RGN_NULL ) {
     2346        // validate it (since it's no more up-to-date after scrolling)
     2347        WinValidateRegion( hwnd, hrgnInv, clip == NULL );
     2348        // scroll it to get the new invalid region
     2349        GpiOffsetRegion( hps, hrgnInv, &ptlDelta );
     2350    }
     2351   
    23082352    // get widget bounds (clip region or rect)
    23092353    HRGN hrgnClip = GpiCreateRegion( hps, 0, NULL );
    23102354    qt_WinQueryClipRegionOrRect( hwnd, hrgnClip );
     2355
     2356    if ( clip ) {
     2357        // intersect it with the given clip rect
     2358        HRGN hrgn = GpiCreateRegion( hps, 1, clip );
     2359        GpiCombineRegion( hps, hrgnClip, hrgn, hrgnClip, CRGN_AND );
     2360        GpiDestroyRegion( hps, hrgn );
     2361    }
     2362
    23112363    // compose a region uncovered after scrolling
    23122364    HRGN hrgnUpd = GpiCreateRegion( hps, 0, NULL );
     
    23142366    GpiOffsetRegion( hps, hrgnUpd, &ptlDelta );
    23152367    GpiCombineRegion( hps, hrgnUpd, hrgnClip, hrgnUpd, CRGN_DIFF );
    2316    
    2317     if ( clip ) {
    2318         // intersect it with the given clip rect
    2319         HRGN hrgn = GpiCreateRegion( hps, 1, clip );
    2320         GpiCombineRegion( hps, hrgnUpd, hrgnClip, hrgnUpd, CRGN_AND );
    2321         GpiDestroyRegion( hps, hrgn );
    2322     }
    2323    
    2324     int pwoFlags = PWO_Ancestors | PWO_Sibings | PWO_TopLevel;
     2368
     2369    int pwoFlags = PWO_Ancestors | PWO_Sibings | PWO_TopLevel | PWO_Screen;
    23252370    if ( clip )
    23262371        pwoFlags |= PWO_Children;
     
    23332378    GpiCombineRegion( hps, hrgnDelta, hrgnObst, 0, CRGN_COPY );
    23342379    GpiOffsetRegion( hps, hrgnDelta, &ptlDelta );
    2335     // substract the region of obstaces fro the delta region to get pure delta
     2380    // substract the region of obstaces from the delta region to get pure delta
    23362381    GpiCombineRegion( hps, hrgnDelta, hrgnDelta, hrgnObst, CRGN_DIFF );
    2337     // substract obstacles the clip region
     2382    // substract obstacles from the clip region
    23382383    GpiCombineRegion( hps, hrgnClip, hrgnClip, hrgnObst, CRGN_DIFF );
    23392384    // substract pure delta from the clip region (to reduce flicker)
    23402385    GpiCombineRegion( hps, hrgnClip, hrgnClip, hrgnDelta, CRGN_DIFF );
     2386    // substract the new invalid region from the clip region (to reduce flicker)
     2387    GpiCombineRegion( hps, hrgnClip, hrgnClip, hrgnInv, CRGN_DIFF );
    23412388   
    23422389    // scroll the area
     
    23502397    // invalidate the region uncovered after scrolling
    23512398    WinInvalidateRegion( hwnd, hrgnUpd, clip == NULL );
    2352    
     2399
     2400    // put the new invalid region back
     2401    WinInvalidateRegion( hwnd, hrgnInv, clip == NULL );
     2402   
     2403    GpiDestroyRegion( hps, hrgnInv );
    23532404    GpiDestroyRegion( hps, hrgnDelta );
    23542405    GpiDestroyRegion( hps, hrgnObst );
Note: See TracChangeset for help on using the changeset viewer.