Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 22710 | Differences between
and this patch

Collapse All | Expand All

(-)client.cpp.orig (-19 / +774 lines)
Lines 4-9 Link Here
4
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
4
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
5
******************************************************************/
5
******************************************************************/
6
//#define QT_CLEAN_NAMESPACE
6
//#define QT_CLEAN_NAMESPACE
7
#include <math.h>
7
#include <klocale.h>
8
#include <klocale.h>
8
#include <kapplication.h>
9
#include <kapplication.h>
9
#include <kdebug.h>
10
#include <kdebug.h>
Lines 42-49 Link Here
42
#define IconicState XIconicState
43
#define IconicState XIconicState
43
#endif
44
#endif
44
45
46
// wait 200 ms before drawing shadow after move/resize
47
static const int SHADOW_DELAY = 200;
48
45
namespace KWinInternal {
49
namespace KWinInternal {
46
50
51
/* TODO: Remove this once X has real translucency.
52
 *
53
 * A list of the regions covered by all shadows and the Clients to which they
54
 * belong. Used to redraw shadows when a window overlapping or underlying a
55
 * shadow is moved, resized, or hidden.
56
 */
57
struct ShadowRegion {
58
    QRegion region;
59
    Client *client;
60
};
61
static QValueList<ShadowRegion> shadowRegions;
62
47
// NET WM Protocol handler class
63
// NET WM Protocol handler class
48
class WinInfo : public NETWinInfo
64
class WinInfo : public NETWinInfo
49
{
65
{
Lines 97-102 Link Here
97
public:
113
public:
98
    ClientPrivate() {};
114
    ClientPrivate() {};
99
    QCString windowRole;
115
    QCString windowRole;
116
    QWidget *shadowWidget;
117
    QMemArray<double> activeOpacityCache;
118
    QMemArray<double> inactiveOpacityCache;
119
    QMemArray<double> *opacityCache;
120
    QRegion shapeBoundingRegion;
121
    QTimer *shadowDelayTimer;
100
};
122
};
101
123
102
};
124
};
Lines 500-505 Link Here
500
        NET::WMIconGeometry
522
        NET::WMIconGeometry
501
        ;
523
        ;
502
524
525
    d->shadowDelayTimer = new QTimer(this);
526
    d->opacityCache = &d->activeOpacityCache;
527
    d->shadowWidget = NULL;
528
    connect(d->shadowDelayTimer, SIGNAL(timeout()), this, SLOT(slotDrawShadow()));
529
    connect(wspace, SIGNAL(reconfigured()), SLOT(slotUpdateOpacityCache()));
530
503
    info = new WinInfo( this, qt_xdisplay(), win, qt_xrootwin(), properties );
531
    info = new WinInfo( this, qt_xdisplay(), win, qt_xrootwin(), properties );
504
532
505
    wwrap = new WindowWrapper( w, this );
533
    wwrap = new WindowWrapper( w, this );
Lines 601-606 Link Here
601
{
629
{
602
    if (moveResizeMode)
630
    if (moveResizeMode)
603
       stopMoveResize();
631
       stopMoveResize();
632
    slotRemoveShadow();
604
    releaseWindow();
633
    releaseWindow();
605
    delete info;
634
    delete info;
606
    delete d;
635
    delete d;
Lines 608-613 Link Here
608
637
609
void Client::startMoveResize()
638
void Client::startMoveResize()
610
{
639
{
640
    slotRemoveShadow();
611
    moveResizeMode = true;
641
    moveResizeMode = true;
612
    workspace()->setClientIsMoving(this);
642
    workspace()->setClientIsMoving(this);
613
    grabMouse( cursor() );
643
    grabMouse( cursor() );
Lines 628-633 Link Here
628
    workspace()->setClientIsMoving(0);
658
    workspace()->setClientIsMoving(0);
629
    moveResizeMode = false;
659
    moveResizeMode = false;
630
    update();
660
    update();
661
    if (options->shadowEnabled(active)) {
662
        drawIntersectingShadows();
663
        slotDrawDelayedShadow();
664
    }
631
}
665
}
632
666
633
/*!
667
/*!
Lines 794-800 Link Here
794
    // initial desktop placement - note we don't clobber desk if it is
828
    // initial desktop placement - note we don't clobber desk if it is
795
    // set to some value, in case the initial desktop code in the
829
    // set to some value, in case the initial desktop code in the
796
    // constructor has already set a value for us
830
    // constructor has already set a value for us
797
    
831
798
    if ( session  ) {
832
    if ( session  ) {
799
        desk = session->desktop;
833
        desk = session->desktop;
800
        if ( desk <= 0 )
834
        if ( desk <= 0 )
Lines 829-835 Link Here
829
        info->setDesktop( NETWinInfo::OnAllDesktops );
863
        info->setDesktop( NETWinInfo::OnAllDesktops );
830
    } else
864
    } else
831
        info->setDesktop( desk );
865
        info->setDesktop( desk );
832
    
866
833
867
834
    if (isInitial) {
868
    if (isInitial) {
835
        setMappingState( init_state );
869
        setMappingState( init_state );
Lines 879-885 Link Here
879
913
880
    if( isTopMenu() && workspace()->activeClient() != mainClient())
914
    if( isTopMenu() && workspace()->activeClient() != mainClient())
881
	doNotShow = true;
915
	doNotShow = true;
882
	
916
883
    bool showMe = (state == NormalState) && isOnDesktop( workspace()->currentDesktop() );
917
    bool showMe = (state == NormalState) && isOnDesktop( workspace()->currentDesktop() );
884
918
885
    workspace()->clientReady( this ); // will call Workspace::propagateClients()
919
    workspace()->clientReady( this ); // will call Workspace::propagateClients()
Lines 1147-1152 Link Here
1147
{
1181
{
1148
    if ( e.event != windowWrapper()->winId() && !e.send_event )
1182
    if ( e.event != windowWrapper()->winId() && !e.send_event )
1149
      return TRUE;
1183
      return TRUE;
1184
    drawIntersectingShadows();
1150
1185
1151
    switch ( mappingState() ) {
1186
    switch ( mappingState() ) {
1152
    case IconicState:
1187
    case IconicState:
Lines 1206-1212 Link Here
1206
}
1241
}
1207
1242
1208
/*!
1243
/*!
1209
  Handles configure  requests of the client window
1244
  Handles configure requests of the client window
1210
 */
1245
 */
1211
bool Client::configureRequest( XConfigureRequestEvent& e )
1246
bool Client::configureRequest( XConfigureRequestEvent& e )
1212
{
1247
{
Lines 1639-1650 Link Here
1639
    }
1674
    }
1640
}
1675
}
1641
1676
1677
void Client::moveEvent(QMoveEvent *e)
1678
{
1679
    QWidget::moveEvent(e);
1642
1680
1643
/*!
1681
    if (!moveResizeMode) {
1644
 */
1682
        // If the user is manually resizing, let Client::stopMoveResize()
1645
void Client::resizeEvent( QResizeEvent * e)
1683
        // decide when to redraw the shadow
1684
        slotRemoveShadow();
1685
        drawIntersectingShadows();
1686
        if (options->shadowEnabled(isActive()))
1687
            slotDrawDelayedShadow();
1688
    }
1689
}
1690
1691
void Client::resizeEvent(QResizeEvent *e)
1646
{
1692
{
1647
    QWidget::resizeEvent( e );
1693
    QWidget::resizeEvent( e );
1694
    slotUpdateOpacityCache();
1648
}
1695
}
1649
1696
1650
1697
Lines 1833-1838 Link Here
1833
    setMappingState( NormalState );
1880
    setMappingState( NormalState );
1834
    QWidget::show();
1881
    QWidget::show();
1835
    windowWrapper()->map();
1882
    windowWrapper()->map();
1883
1884
    if (options->shadowEnabled(active))
1885
        slotDrawDelayedShadow();
1836
}
1886
}
1837
1887
1838
/*!
1888
/*!
Lines 1841-1846 Link Here
1841
*/
1891
*/
1842
void Client::hide()
1892
void Client::hide()
1843
{
1893
{
1894
    d->shadowDelayTimer->stop();
1895
    slotRemoveShadow();
1896
    drawIntersectingShadows();
1844
    QWidget::hide();
1897
    QWidget::hide();
1845
    workspace()->clientHidden( this );
1898
    workspace()->clientHidden( this );
1846
    windowWrapper()->unmap();
1899
    windowWrapper()->unmap();
Lines 1918-1923 Link Here
1918
 */
1971
 */
1919
void Client::shadeChange( bool )
1972
void Client::shadeChange( bool )
1920
{
1973
{
1974
    slotRemoveShadow();
1975
    if (options->shadowEnabled(active))
1976
        slotDrawDelayedShadow();
1921
}
1977
}
1922
1978
1923
1979
Lines 2161-2177 Link Here
2161
 */
2217
 */
2162
bool Client::eventFilter( QObject *o, QEvent * e)
2218
bool Client::eventFilter( QObject *o, QEvent * e)
2163
{
2219
{
2164
    if ( o != wwrap )
2220
    if ( o == wwrap ) {
2165
        return FALSE;
2221
        switch ( e->type() ) {
2166
    switch ( e->type() ) {
2222
        case QEvent::Show:
2167
    case QEvent::Show:
2223
            windowWrapperShowEvent( (QShowEvent*)e );
2168
        windowWrapperShowEvent( (QShowEvent*)e );
2224
            break;
2169
        break;
2225
        case QEvent::Hide:
2170
    case QEvent::Hide:
2226
            windowWrapperHideEvent( (QHideEvent*)e );
2171
        windowWrapperHideEvent( (QHideEvent*)e );
2227
            break;
2172
        break;
2228
        default:
2173
    default:
2229
            break;
2174
        break;
2230
        }
2231
    }
2232
    else if (o == d->shadowWidget) {
2233
        if (e->type() == QEvent::MouseButtonRelease) {
2234
            int buttonMask, buttonPressed, x, y, x_root, y_root;
2235
            unsigned int mask;
2236
            QMouseEvent *qe = (QMouseEvent *)e;
2237
            Window inner_window, parent_window, pointer_window, root_window;
2238
            XButtonEvent xe;
2239
2240
            slotRemoveShadow();
2241
            switch (qe->button()) {
2242
            case Qt::MidButton:
2243
                buttonMask = Button2Mask;
2244
                buttonPressed = Button2;
2245
                break;
2246
            case Qt::RightButton:
2247
                buttonMask = Button3Mask;
2248
                buttonPressed = Button3;
2249
                break;
2250
            default:
2251
                buttonMask = Button1Mask;
2252
                buttonPressed = Button1;
2253
                break;
2254
            }
2255
2256
            // find the window under the cursor that should receive the
2257
            // simulated events
2258
            root_window = qt_xrootwin();
2259
            XQueryPointer(qt_xdisplay(), root_window, &root_window,
2260
                    &pointer_window, &x_root, &y_root, &x, &y, &mask);
2261
2262
            if (pointer_window != None) {
2263
                // Save the child window immediately under the window
2264
                // decoration, if any. This is so that we can send an event to
2265
                // the immediate descendant of a window's window decoration,
2266
                // which causes KWin to refocus windows properly
2267
                parent_window = pointer_window;
2268
                XQueryPointer(qt_xdisplay(), parent_window, &root_window,
2269
                        &pointer_window, &x_root, &y_root, &x, &y, &mask);
2270
                inner_window = pointer_window;
2271
2272
                while (pointer_window != None) {
2273
                    // Recursively query for the child window under the pointer,
2274
                    // using the returned child window as the parent window for
2275
                    // the subsequent query. When no child window is left, we've
2276
                    // found the child that will receive the simulated event
2277
                    parent_window = pointer_window;
2278
                    XQueryPointer(qt_xdisplay(), parent_window, &root_window,
2279
                            &pointer_window, &x_root, &y_root, &x, &y, &mask);
2280
                }
2281
                pointer_window = parent_window;
2282
            }
2283
            else
2284
                inner_window = None;
2285
2286
            // simulate a mouse button press
2287
            xe.type = ButtonPress;
2288
            xe.display = qt_xdisplay();
2289
            xe.root = qt_xrootwin();
2290
            xe.subwindow = None;
2291
            xe.time = CurrentTime;
2292
            xe.x = x;
2293
            xe.y = y;
2294
            xe.x_root = x_root;
2295
            xe.y_root = y_root;
2296
            xe.state = 0;
2297
            xe.button = buttonPressed;
2298
            xe.same_screen = True;
2299
            if (inner_window != None && inner_window != pointer_window) {
2300
                xe.window = inner_window;
2301
                XSendEvent(qt_xdisplay(), inner_window, True, ButtonPressMask,
2302
                        (XEvent *)&xe);
2303
            }
2304
            xe.window = pointer_window;
2305
            XSendEvent(qt_xdisplay(), pointer_window, True, ButtonPressMask,
2306
                    (XEvent *)&xe);
2307
2308
            // simulate a mouse button release
2309
            xe.type = ButtonRelease;
2310
            xe.display = qt_xdisplay();
2311
            xe.root = qt_xrootwin();
2312
            xe.subwindow = None;
2313
            xe.time = CurrentTime;
2314
            xe.x = x;
2315
            xe.y = y;
2316
            xe.x_root = x_root;
2317
            xe.y_root = y_root;
2318
            xe.state = buttonMask;
2319
            xe.button = buttonPressed;
2320
            xe.same_screen = True;
2321
            if (inner_window != None && inner_window != pointer_window) {
2322
                xe.window = inner_window;
2323
                XSendEvent(qt_xdisplay(), inner_window, True, ButtonReleaseMask,
2324
                        (XEvent *)&xe);
2325
            }
2326
            xe.window = pointer_window;
2327
            XSendEvent(qt_xdisplay(), pointer_window, True, ButtonReleaseMask,
2328
                    (XEvent *)&xe);
2329
2330
            slotDrawDelayedShadow();
2331
2332
            return TRUE;
2333
        }
2334
        else if (e->type() == QEvent::Wheel) {
2335
            int x, y, x_root, y_root;
2336
            unsigned int buttonMask, buttonPressed, mask;
2337
            QWheelEvent *wheelEvent = (QWheelEvent *)e;
2338
            Window inner_window, parent_window, pointer_window,
2339
                root_window;
2340
            XButtonEvent xe;
2341
2342
            slotRemoveShadow();
2343
2344
            // state and button parameters passed to XSendEvent depend on the
2345
            // direction in which the mouse wheel was rolled
2346
            buttonMask = wheelEvent->delta() > 0 ? Button4Mask : Button5Mask;
2347
            buttonPressed = wheelEvent->delta() > 0 ? Button4 : Button5;
2348
2349
            // find the window under the cursor that should receive the
2350
            // simulated events
2351
            root_window = qt_xrootwin();
2352
            XQueryPointer(qt_xdisplay(), root_window, &root_window,
2353
                    &pointer_window, &x_root, &y_root, &x, &y, &mask);
2354
2355
            if (pointer_window != None) {
2356
                // Save the child window immediately under the window
2357
                // decoration, if any. This is so that we can send an event to
2358
                // the immediate descendant of a window's window decoration,
2359
                // which causes KWin to refocus windows properly
2360
                parent_window = pointer_window;
2361
                XQueryPointer(qt_xdisplay(), parent_window, &root_window,
2362
                        &pointer_window, &x_root, &y_root, &x, &y, &mask);
2363
                inner_window = pointer_window;
2364
2365
                while (pointer_window != None) {
2366
                    // Recursively query for the child window under the pointer,
2367
                    // using the returned child window as the parent window for
2368
                    // the subsequent query. When no child window is left, we've
2369
                    // found the child that will receive the simulated event
2370
                    parent_window = pointer_window;
2371
                    XQueryPointer(qt_xdisplay(), parent_window, &root_window,
2372
                            &pointer_window, &x_root, &y_root, &x, &y, &mask);
2373
                }
2374
                pointer_window = parent_window;
2375
            }
2376
            else
2377
                inner_window = None;
2378
2379
            // simulate a mouse button press
2380
            xe.type = ButtonPress;
2381
            xe.display = qt_xdisplay();
2382
            xe.root = qt_xrootwin();
2383
            xe.subwindow = None;
2384
            xe.time = CurrentTime;
2385
            xe.x = x;
2386
            xe.y = y;
2387
            xe.x_root = x_root;
2388
            xe.y_root = y_root;
2389
            xe.state = 0;
2390
            xe.same_screen = True;
2391
            if (inner_window != None && inner_window != pointer_window) {
2392
                xe.button = buttonPressed;
2393
                xe.window = inner_window;
2394
                XSendEvent(qt_xdisplay(), inner_window, True, ButtonPressMask,
2395
                        (XEvent *)&xe);
2396
            }
2397
            xe.button = buttonPressed;
2398
            xe.window = pointer_window;
2399
            XSendEvent(qt_xdisplay(), pointer_window, True, ButtonPressMask,
2400
                    (XEvent *)&xe);
2401
2402
            // simulate a mouse button release
2403
            xe.type = ButtonRelease;
2404
            xe.display = qt_xdisplay();
2405
            xe.root = qt_xrootwin();
2406
            xe.subwindow = None;
2407
            xe.time = CurrentTime;
2408
            xe.x = x;
2409
            xe.y = y;
2410
            xe.x_root = x_root;
2411
            xe.y_root = y_root;
2412
            xe.same_screen = True;
2413
            if (inner_window != None && inner_window != pointer_window) {
2414
                xe.window = inner_window;
2415
                xe.state = buttonMask;
2416
                xe.button = buttonPressed;
2417
                XSendEvent(qt_xdisplay(), inner_window, True, ButtonReleaseMask,
2418
                        (XEvent *)&xe);
2419
            }
2420
            xe.state = buttonMask;
2421
            xe.button = buttonPressed;
2422
            xe.window = pointer_window;
2423
            XSendEvent(qt_xdisplay(), pointer_window, True, ButtonReleaseMask,
2424
                    (XEvent *)&xe);
2425
2426
            slotDrawDelayedShadow();
2427
2428
            return TRUE;
2429
        }
2175
    }
2430
    }
2176
2431
2177
    return FALSE;
2432
    return FALSE;
Lines 2485-2492 Link Here
2485
    if ( active == act )
2740
    if ( active == act )
2486
        return;
2741
        return;
2487
    active = act;
2742
    active = act;
2488
    if ( active )
2743
    if ( active ) {
2744
        if (options->shadowEnabled(true)) {
2745
            if (options->shadowEnabled(false)) {
2746
                // Wait for inactive shadow to expose occluded windows and give
2747
                // them a chance to redraw before painting the active shadow
2748
                slotRemoveShadow();
2749
                slotDrawDelayedShadow();
2750
            }
2751
            else
2752
                slotDrawShadow();
2753
        }
2754
2489
        Events::raise( Events::Activate );
2755
        Events::raise( Events::Activate );
2756
    }
2757
    else {
2758
        slotRemoveShadow();
2759
2760
        if (options->shadowEnabled(false))
2761
            slotDrawDelayedShadow();
2762
    }
2490
2763
2491
    if ( !active && autoRaiseTimer ) {
2764
    if ( !active && autoRaiseTimer ) {
2492
        delete autoRaiseTimer;
2765
        delete autoRaiseTimer;
Lines 2496-2501 Link Here
2496
    activeChange( active );
2769
    activeChange( active );
2497
}
2770
}
2498
2771
2772
void Client::slotUpdateOpacityCache()
2773
{
2774
    if (!options->shadowEnabled(isActive()))
2775
        return;
2776
2777
    if (!d->activeOpacityCache.isNull())
2778
        d->activeOpacityCache.resize(0);
2779
    if (!d->inactiveOpacityCache.isNull())
2780
        d->inactiveOpacityCache.resize(0);
2781
2782
    if (!moveResizeMode) {
2783
        // If the user is manually resizing, let Client::stopMoveResize()
2784
        // decide when to redraw the shadow
2785
        slotRemoveShadow();
2786
        drawIntersectingShadows();
2787
        if (options->shadowEnabled(isActive()))
2788
            slotDrawDelayedShadow();
2789
    }
2790
}
2791
2792
/*!
2793
   Redraw shadows that were previously occluding or occluded by this window,
2794
   to avoid visual glitches.
2795
 */
2796
void Client::drawIntersectingShadows() {
2797
    QRegion region;
2798
    QValueList<ShadowRegion>::Iterator it;
2799
    QPtrList<Client> reshadowClients;
2800
2801
    if (!options->shadowEnabled(false))
2802
        // No point in redrawing overlapping/overpalled shadows if only the
2803
        // active window has a shadow.
2804
        return;
2805
2806
    region = d->shapeBoundingRegion;
2807
2808
    // Generate list of Clients whose shadows that need to be redrawn. That is,
2809
    // those that are currently overlapping or overlapped by other windows or
2810
    // shadows.
2811
    for (it = shadowRegions.begin(); it != shadowRegions.end(); ++it)
2812
        if ((*it).client->isOnDesktop(desktop()) &&
2813
                !(*it).region.intersect(region).isEmpty())
2814
            reshadowClients.append((*it).client);
2815
2816
    // Redraw shadows for each of the Clients in the list generated above
2817
    QPtrListIterator<Client> it2(reshadowClients);
2818
    while (it2.current() != 0) {
2819
        it2.current()->slotRemoveShadow();
2820
        it2.current()->slotDrawDelayedShadow();
2821
        ++it2;
2822
    }
2823
}
2824
2825
/*!
2826
   Draw shadow after some time has elapsed, to give recently exposed windows a
2827
   chance to repaint before a shadow gradient is drawn over them.
2828
 */
2829
void Client::slotDrawDelayedShadow() {
2830
    d->shadowDelayTimer->start(SHADOW_DELAY, true);
2831
}
2832
2833
/*!
2834
   Draw a shadow under this window and XShape the shadow accordingly.
2835
 */
2836
void Client::slotDrawShadow()
2837
{
2838
    XRectangle *shapes;
2839
    int i, count, ordering;
2840
2841
    /* Store this window's ShapeBoundingRegion even if shadows aren't drawn for
2842
     * this type of window. Otherwise, drawIntersectingShadows() won't update
2843
     * properly when this window is moved/resized/hidden/closed.
2844
     */
2845
    shapes = XShapeGetRectangles(qt_xdisplay(), winId(), ShapeBounding,
2846
            &count, &ordering);
2847
    if (!shapes)
2848
        // XShape extension not supported
2849
        d->shapeBoundingRegion = QRegion(x(), y(), width(), height());
2850
    else {
2851
        d->shapeBoundingRegion = QRegion();
2852
        for (i = 0; i < count; i++) {
2853
            // Translate XShaped window into a QRegion
2854
            QRegion shapeRectangle(shapes[i].x, shapes[i].y, shapes[i].width,
2855
                    shapes[i].height);
2856
            d->shapeBoundingRegion += shapeRectangle;
2857
        }
2858
        d->shapeBoundingRegion.translate(x(), y());
2859
    }
2860
2861
    if (isHidden() || isMaximized() ||
2862
            !options->shadowWindowType(windowType())) {
2863
        XFree(shapes);
2864
        return;
2865
    }
2866
2867
    slotRemoveShadow();
2868
2869
    QMemArray<QRgb> pixelData;
2870
    QPixmap shadowPixmap;
2871
    QRect shadow;
2872
    QRegion exposedRegion;
2873
    ShadowRegion shadowRegion;
2874
    int thickness, xOffset, yOffset;
2875
2876
    thickness = options->shadowThickness(isActive());
2877
    xOffset = options->shadowXOffset(isActive());
2878
    yOffset = options->shadowYOffset(isActive());
2879
    d->opacityCache = active? &d->activeOpacityCache : &d->inactiveOpacityCache;
2880
2881
    shadow.setRect(x() - thickness + xOffset, y() - thickness + yOffset,
2882
            width() + thickness * 2, height() + thickness * 2);
2883
    shadowPixmap.resize(shadow.size());
2884
2885
    // Create a fake drop-down shadow effect via blended Xwindows
2886
    d->shadowWidget = new QWidget(0, 0, WStyle_Customize | WX11BypassWM);
2887
    d->shadowWidget->setGeometry(shadow);
2888
    XSelectInput(qt_xdisplay(), d->shadowWidget->winId(),
2889
            ButtonPressMask | ButtonReleaseMask | StructureNotifyMask);
2890
    d->shadowWidget->installEventFilter(this);
2891
2892
    shapes = XShapeGetRectangles(qt_xdisplay(), winId(), ShapeBounding,
2893
            &count, &ordering);
2894
2895
    if (!shapes) {
2896
        // XShape extension not supported
2897
        exposedRegion = getExposedRegion(d->shapeBoundingRegion, shadow.x(),
2898
                shadow.y(), shadow.width(), shadow.height(), thickness,
2899
                xOffset, yOffset);
2900
        shadowRegion.region = exposedRegion;
2901
        shadowRegion.client = this;
2902
        shadowRegions.append(shadowRegion);
2903
2904
        if (d->opacityCache->isNull())
2905
            imposeRegionShadow(shadowPixmap, d->shapeBoundingRegion,
2906
                    exposedRegion, thickness,
2907
                    options->shadowOpacity(isActive()));
2908
        else
2909
            imposeCachedShadow(shadowPixmap, exposedRegion);
2910
    }
2911
    else {
2912
        QMemArray<QRect> exposedRects;
2913
        QMemArray<QRect>::Iterator it, itEnd;
2914
        XRectangle *shadowShapes;
2915
2916
        exposedRegion = getExposedRegion(d->shapeBoundingRegion, shadow.x(),
2917
                shadow.y(), shadow.width(), shadow.height(), thickness,
2918
                xOffset, yOffset);
2919
        shadowRegion.region = exposedRegion;
2920
        shadowRegion.client = this;
2921
        shadowRegions.append(shadowRegion);
2922
2923
        // XShape the shadow
2924
        exposedRects = exposedRegion.rects();
2925
        i = 0;
2926
        itEnd = exposedRects.end();
2927
        shadowShapes = new XRectangle[exposedRects.count()];
2928
        for (it = exposedRects.begin(); it != itEnd; ++it) {
2929
            shadowShapes[i].x = (*it).x();
2930
            shadowShapes[i].y = (*it).y();
2931
            shadowShapes[i].width = (*it).width();
2932
            shadowShapes[i].height = (*it).height();
2933
            i++;
2934
        }
2935
        XShapeCombineRectangles(qt_xdisplay(), d->shadowWidget->winId(),
2936
                ShapeBounding, -x() + thickness - xOffset,
2937
                -y() + thickness - yOffset, shadowShapes, i, ShapeSet,
2938
                Unsorted);
2939
        delete [] shadowShapes;
2940
2941
        if (d->opacityCache->isNull())
2942
            imposeRegionShadow(shadowPixmap, d->shapeBoundingRegion,
2943
                    exposedRegion, thickness,
2944
                    options->shadowOpacity(isActive()));
2945
        else
2946
            imposeCachedShadow(shadowPixmap, exposedRegion);
2947
    }
2948
2949
    XFree(shapes);
2950
2951
    // Set the background pixmap
2952
    //shadowPixmap.convertFromImage(shadowImage);
2953
    d->shadowWidget->setErasePixmap(shadowPixmap);
2954
2955
    // Restack shadows under this window so that shadows drawn for a newly
2956
    // focused (but not raised) window don't overlap any windows above it.
2957
    restackShadows();
2958
2959
    // Don't use QWidget::show() so we don't confuse QEffects, thus causing
2960
    // broken focus.
2961
    XMapWindow(qt_xdisplay(), d->shadowWidget->winId());
2962
}
2963
2964
/*!
2965
   Remove shadow under this window.
2966
 */
2967
void Client::slotRemoveShadow()
2968
{
2969
    QValueList<ShadowRegion>::Iterator it;
2970
2971
    d->shadowDelayTimer->stop();
2972
2973
    if (d->shadowWidget != NULL) {
2974
        for (it = shadowRegions.begin(); it != shadowRegions.end(); ++it)
2975
            if ((*it).client == this) {
2976
                shadowRegions.remove(it);
2977
                break;
2978
        }
2979
        delete d->shadowWidget;
2980
        d->shadowWidget = NULL;
2981
    }
2982
}
2983
2984
/*!
2985
   Calculate regions in which the shadow will be visible given the window's
2986
   origin, height and width and the shadow's thickness, and X- and Y-offsets.
2987
 */
2988
QRegion Client::getExposedRegion(QRegion occludedRegion, int x, int y, int w,
2989
        int h, int thickness, int xOffset, int yOffset)
2990
{
2991
    QRegion exposedRegion;
2992
2993
    exposedRegion = QRegion(x, y, w, h);
2994
    exposedRegion -= occludedRegion;
2995
2996
    if (thickness > 0) {
2997
        // Limit exposedRegion to include only where a shadow of the specified
2998
        // thickness will be drawn
2999
        QMemArray<QRect> occludedRects;
3000
        QMemArray<QRect>::Iterator it, itEnd;
3001
        QRegion shadowRegion;
3002
3003
        occludedRects = occludedRegion.rects();
3004
        itEnd = occludedRects.end();
3005
        for (it = occludedRects.begin(); it != itEnd; ++it) {
3006
            // Expand each of the occluded region's shape rectangles to contain
3007
            // where a shadow of the specified thickness will be drawn. Create
3008
            // a new QRegion that contains the expanded occluded region
3009
            it->setTop(it->top() - thickness + yOffset);
3010
            it->setLeft(it->left() - thickness + xOffset);
3011
            it->setRight(it->right() + thickness + xOffset);
3012
            it->setBottom(it->bottom() + thickness + yOffset);
3013
            shadowRegion += QRegion(*it);
3014
        }
3015
        exposedRegion -= exposedRegion - shadowRegion;
3016
    }
3017
3018
    return exposedRegion;
3019
}
3020
3021
/*!
3022
   Draw shadow gradient around this window using cached opacity values.
3023
 */
3024
void Client::imposeCachedShadow(QPixmap &pixmap, QRegion exposed)
3025
{
3026
    QPainter painter;
3027
    QRgb pixel;
3028
    double opacity;
3029
    int red, green, blue, pixelRed, pixelGreen, pixelBlue;
3030
    int subW, subH, w, h, x, y, zeroX, zeroY;
3031
    QImage image;
3032
    QMemArray<QRect>::Iterator it, itEnd;
3033
    QMemArray<QRect> rectangles;
3034
    QPixmap subPixmap;
3035
    Window rootWindow;
3036
    int thickness, windowX, windowY, xOffset, yOffset;
3037
3038
    rectangles = exposed.rects();
3039
    rootWindow = qt_xrootwin();
3040
    thickness = options->shadowThickness(isActive());
3041
    windowX = this->x();
3042
    windowY = this->y();
3043
    xOffset = options->shadowXOffset(isActive());
3044
    yOffset = options->shadowYOffset(isActive());
3045
    options->shadowColour(isActive()).rgb(&red, &green, &blue);
3046
    w = pixmap.width();
3047
    h = pixmap.height();
3048
3049
    painter.begin(&pixmap);
3050
3051
    itEnd = rectangles.end();
3052
    for (it = rectangles.begin(); it != itEnd; ++it) {
3053
        subW = (*it).width();
3054
        subH = (*it).height();
3055
        subPixmap = QPixmap::grabWindow(rootWindow, (*it).x(), (*it).y(),
3056
                subW, subH);
3057
        zeroX = (*it).x() - windowX + thickness - xOffset;
3058
        zeroY = (*it).y() - windowY + thickness - yOffset;
3059
        image = subPixmap.convertToImage();
3060
3061
        for (x = 0; x < subW; x++) {
3062
            for (y = 0; y < subH; y++) {
3063
                opacity = (*(d->opacityCache))[(zeroY + y) * w + zeroX + x];
3064
                pixel = image.pixel(x, y);
3065
                pixelRed = qRed(pixel);
3066
                pixelGreen = qGreen(pixel);
3067
                pixelBlue = qBlue(pixel);
3068
                image.setPixel(x, y,
3069
                        qRgb((int)(pixelRed + (red - pixelRed) * opacity),
3070
                            (int)(pixelGreen + (green - pixelGreen) * opacity),
3071
                            (int)(pixelBlue + (blue - pixelBlue) * opacity)));
3072
            }
3073
        }
3074
3075
        subPixmap.convertFromImage(image);
3076
        painter.drawPixmap(zeroX, zeroY, subPixmap);
3077
    }
3078
3079
    painter.end();
3080
}
3081
3082
/*!
3083
   Draw shadow around this window using calculated opacity values.
3084
 */
3085
void Client::imposeRegionShadow(QPixmap &pixmap, QRegion occluded,
3086
        QRegion exposed, int thickness, double maxOpacity)
3087
{
3088
    register int distance, intersectCount, i, j, x, y;
3089
    QPainter painter;
3090
    QRgb pixel;
3091
    double decay, factor, opacity;
3092
    int red, green, blue, pixelRed, pixelGreen, pixelBlue;
3093
    int halfMaxIntersects, lineIntersects, maxIntersects, maxY;
3094
    int irBottom, irLeft, irRight, irTop, yIncrement;
3095
    int subW, subH, w, h, zeroX, zeroY;
3096
    QImage image;
3097
    QMemArray<QRect>::Iterator it, itEnd;
3098
    QMemArray<QRect> rectangles;
3099
    QPixmap subPixmap;
3100
    Window rootWindow;
3101
    int windowX, windowY, xOffset, yOffset;
3102
3103
    rectangles = exposed.rects();
3104
    rootWindow = qt_xrootwin();
3105
    windowX = this->x();
3106
    windowY = this->y();
3107
    xOffset = options->shadowXOffset(isActive());
3108
    yOffset = options->shadowYOffset(isActive());
3109
    options->shadowColour(isActive()).rgb(&red, &green, &blue);
3110
    maxIntersects = thickness * thickness * 4 + (thickness * 4) + 1;
3111
    halfMaxIntersects = maxIntersects / 2;
3112
    lineIntersects = thickness * 2 + 1;
3113
    factor = maxIntersects / maxOpacity;
3114
    decay = (lineIntersects / 0.01 - factor) / pow((double)maxIntersects, 3.5);
3115
    w = pixmap.width();
3116
    h = pixmap.height();
3117
    xOffset = options->shadowXOffset(isActive());
3118
    yOffset = options->shadowYOffset(isActive());
3119
3120
    d->opacityCache->resize(0);
3121
    d->opacityCache->resize(w * h);
3122
    occluded.translate(-windowX + thickness, -windowY + thickness);
3123
3124
    painter.begin(&pixmap);
3125
3126
    itEnd = rectangles.end();
3127
    for (it = rectangles.begin(); it != itEnd; ++it) {
3128
        subW = (*it).width();
3129
        subH = (*it).height();
3130
        subPixmap = QPixmap::grabWindow(rootWindow, (*it).x(), (*it).y(),
3131
                subW, subH);
3132
        maxY = subH;
3133
        zeroX = (*it).x() - windowX + thickness - xOffset;
3134
        zeroY = (*it).y() - windowY + thickness - yOffset;
3135
        image = subPixmap.convertToImage();
3136
3137
        intersectCount = 0;
3138
        opacity = -1;
3139
        y = 0;
3140
        yIncrement = 1;
3141
        for (x = 0; x < subW; x++) {
3142
            irLeft = zeroX + x - thickness;
3143
            irRight = zeroX + x + thickness;
3144
3145
            while (y != maxY) {
3146
                // horizontal row about to leave the intersect region, not
3147
                // necessarily the top row
3148
                irTop = zeroY + y - thickness * yIncrement;
3149
                // horizontal row that just came into the intersect region,
3150
                // not necessarily the bottom row
3151
                irBottom = zeroY + y + thickness * yIncrement;
3152
3153
                if (opacity == -1) {
3154
                    // If occluded pixels caused an intersect count to be
3155
                    // skipped, recount it
3156
                    intersectCount = 0;
3157
3158
                    for (j = irTop; j != irBottom; j += yIncrement) {
3159
                        // irTop is not necessarily larger than irBottom and
3160
                        // yIncrement isn't necessarily positive
3161
                        for (i = irLeft; i <= irRight; i++) {
3162
                            if (occluded.contains(QPoint(i, j)))
3163
                                intersectCount++;
3164
                        }
3165
                    }
3166
                }
3167
                else {
3168
                    if (intersectCount < 0)
3169
                        intersectCount = 0;
3170
3171
                    for (i = irLeft; i <= irRight; i++) {
3172
                        if (occluded.contains(QPoint(i, irBottom)))
3173
                            intersectCount++;
3174
                    }
3175
                }
3176
3177
                distance = maxIntersects - intersectCount;
3178
                opacity = intersectCount / (factor + pow((double)distance, 3.5) * decay);
3179
3180
                (*(d->opacityCache))[(zeroY + y) * w + zeroX + x] = opacity;
3181
                pixel = image.pixel(x, y);
3182
                pixelRed = qRed(pixel);
3183
                pixelGreen = qGreen(pixel);
3184
                pixelBlue = qBlue(pixel);
3185
                image.setPixel(x, y,
3186
                        qRgb((int)(pixelRed + (red - pixelRed) * opacity),
3187
                            (int)(pixelGreen + (green - pixelGreen) * opacity),
3188
                            (int)(pixelBlue + (blue - pixelBlue) * opacity)));
3189
3190
                for (i = irLeft; i <= irRight; i++) {
3191
                    if (occluded.contains(QPoint(i, irTop)))
3192
                        intersectCount--;
3193
                }
3194
3195
                y += yIncrement;
3196
            }
3197
            y -= yIncrement;
3198
3199
            irTop += yIncrement;
3200
            for (j = irTop; j != irBottom; j += yIncrement) {
3201
                if (occluded.contains(QPoint(irLeft, j)))
3202
                    intersectCount--;
3203
            }
3204
            irRight++;
3205
            for (j = irTop; j != irBottom; j += yIncrement) {
3206
                if (occluded.contains(QPoint(irRight, j)))
3207
                    intersectCount++;
3208
            }
3209
3210
            yIncrement *= -1;
3211
            if (yIncrement < 0)
3212
                // Scan Y-axis bottom-up for next X-coordinate iteration
3213
                maxY = -1;
3214
            else
3215
                // Scan Y-axis top-down for next X-coordinate iteration
3216
                maxY = subH;
3217
        }
3218
3219
        subPixmap.convertFromImage(image);
3220
        painter.drawPixmap(zeroX, zeroY, subPixmap);
3221
    }
3222
3223
    painter.end();
3224
}
3225
3226
/*!
3227
   Returns X window ID of the shadow widget.
3228
 */
3229
Window Client::shadowId() const
3230
{
3231
    return d->shadowWidget != NULL ? d->shadowWidget->winId() : None;
3232
}
3233
3234
/*
3235
 * Restack shadow windows so that they are immediately under the window they
3236
 * belong to.
3237
 */
3238
void Client::restackShadows()
3239
{
3240
    Window shadows[2];
3241
3242
    if (isDock()) {
3243
        shadows[0] = workspace()->stackingOrder().first()->winId();
3244
        shadows[1] = d->shadowWidget->winId();
3245
    }
3246
    else {
3247
        shadows[0] = winId();
3248
        if (d->shadowWidget != NULL)
3249
            shadows[1] = d->shadowWidget->winId();
3250
    }
3251
3252
    XRestackWindows(qt_xdisplay(), shadows, 2);
3253
}
2499
3254
2500
/*!
3255
/*!
2501
  Sets the window's sticky property to b
3256
  Sets the window's sticky property to b
(-)client.h.orig (-1 / +18 lines)
Lines 222-230 Link Here
222
    void updateUserTime();
222
    void updateUserTime();
223
223
224
    const QPoint gravitate( bool invert ) const;
224
    const QPoint gravitate( bool invert ) const;
225
    
225
226
    void NETMoveResize( int x_root, int y_root, NET::Direction direction );
226
    void NETMoveResize( int x_root, int y_root, NET::Direction direction );
227
227
228
    void restackShadows();
229
    Window shadowId() const;
230
    void drawIntersectingShadows();
231
228
public slots:
232
public slots:
229
    void iconify();
233
    void iconify();
230
    void closeWindow();
234
    void closeWindow();
Lines 242-247 Link Here
242
    void mousePressEvent( QMouseEvent * );
246
    void mousePressEvent( QMouseEvent * );
243
    void mouseReleaseEvent( QMouseEvent * );
247
    void mouseReleaseEvent( QMouseEvent * );
244
    void mouseMoveEvent( QMouseEvent * );
248
    void mouseMoveEvent( QMouseEvent * );
249
    void moveEvent( QMoveEvent * );
245
    void resizeEvent( QResizeEvent * );
250
    void resizeEvent( QResizeEvent * );
246
    virtual void windowWrapperShowEvent( QShowEvent* ){}
251
    virtual void windowWrapperShowEvent( QShowEvent* ){}
247
    virtual void windowWrapperHideEvent( QHideEvent* ){}
252
    virtual void windowWrapperHideEvent( QHideEvent* ){}
Lines 275-280 Link Here
275
    virtual QPixmap animationPixmap( int w );
280
    virtual QPixmap animationPixmap( int w );
276
281
277
282
283
    QRegion getExposedRegion(QRegion occludedRegion, int x, int y,
284
            int w, int h, int thickness, int xOffset, int yOffset);
285
    void imposeRegionShadow(QPixmap &pixmap, QRegion occluded,
286
            QRegion exposed, int thickness, double maxOpacity = 0.75);
287
278
    // handlers for X11 events
288
    // handlers for X11 events
279
    bool mapRequest( XMapRequestEvent& e );
289
    bool mapRequest( XMapRequestEvent& e );
280
    bool unmapNotify( XUnmapEvent& e );
290
    bool unmapNotify( XUnmapEvent& e );
Lines 284-291 Link Here
284
294
285
    NETWinInfo * netWinInfo();
295
    NETWinInfo * netWinInfo();
286
296
297
protected slots:
298
    void slotDrawShadow();
299
    void slotDrawDelayedShadow();
300
    void slotRemoveShadow();
301
287
private slots:
302
private slots:
288
    void destroyClient();
303
    void destroyClient();
304
    void slotUpdateOpacityCache();
289
305
290
private:
306
private:
291
    QSize sizeForWindowSize( const QSize&, bool ignore_height = FALSE ) const;
307
    QSize sizeForWindowSize( const QSize&, bool ignore_height = FALSE ) const;
Lines 358-363 Link Here
358
    QString cap;
374
    QString cap;
359
    WId wmClientLeaderWin;
375
    WId wmClientLeaderWin;
360
    void getWmClientLeader();
376
    void getWmClientLeader();
377
    void imposeCachedShadow(QPixmap &pixmap, QRegion exposed);
361
378
362
 public:
379
 public:
363
    static QCString staticWindowRole(WId);
380
    static QCString staticWindowRole(WId);
(-)options.cpp.orig (+94 lines)
Lines 10-15 Link Here
10
#include <kconfig.h>
10
#include <kconfig.h>
11
#include <kglobal.h>
11
#include <kglobal.h>
12
#include <kglobalsettings.h>
12
#include <kglobalsettings.h>
13
#include <netwm.h>
13
14
14
using namespace KWinInternal;
15
using namespace KWinInternal;
15
16
Lines 31-36 Link Here
31
    bool animate_tooltips;
32
    bool animate_tooltips;
32
    int electric_borders;
33
    int electric_borders;
33
    int electric_border_delay;
34
    int electric_border_delay;
35
    QColor shadow_colour;
36
    QColor shadow_inactive_colour;
37
    bool shadow_docks;
38
    bool shadow_overrides;
39
    bool shadow_topMenus;
40
    bool shadow_inactive_enabled;
41
    bool shadow_enabled;
42
    double shadow_inactive_opacity;
43
    double shadow_opacity;
44
    int shadow_inactive_thickness;
45
    int shadow_thickness;
46
    int shadow_inactive_x_offset;
47
    int shadow_x_offset;
48
    int shadow_inactive_y_offset;
49
    int shadow_y_offset;
34
};
50
};
35
};
51
};
36
52
Lines 264-269 Link Here
264
    d->fade_tooltips = globalConfig.readBoolEntry("EffectFadeTooltip", false);
280
    d->fade_tooltips = globalConfig.readBoolEntry("EffectFadeTooltip", false);
265
    d->animate_tooltips = globalConfig.readBoolEntry("EffectAnimateTooltip", false);
281
    d->animate_tooltips = globalConfig.readBoolEntry("EffectAnimateTooltip", false);
266
282
283
    // window drop shadows
284
    d->shadow_colour = config->readColorEntry("ShadowColour", &Qt::black);
285
    d->shadow_docks = config->readBoolEntry("ShadowDocks", false);
286
    d->shadow_overrides = config->readBoolEntry("ShadowOverrides", false);
287
    d->shadow_topMenus = config->readBoolEntry("ShadowTopMenus", false);
288
    d->shadow_inactive_colour = config->readColorEntry("InactiveShadowColour", &Qt::black);
289
    d->shadow_inactive_enabled = config->readBoolEntry("InactiveShadowEnabled", false);
290
    d->shadow_inactive_opacity = config->readDoubleNumEntry("InactiveShadowOpacity", 0.75);
291
    d->shadow_inactive_thickness = config->readNumEntry("InactiveShadowThickness", 5);
292
    d->shadow_inactive_x_offset = config->readNumEntry("InactiveShadowXOffset", 0);
293
    d->shadow_inactive_y_offset = config->readNumEntry("InactiveShadowYOffset", 5);
294
    d->shadow_enabled = config->readBoolEntry("ShadowEnabled", false);
295
    d->shadow_opacity = config->readDoubleNumEntry("ShadowOpacity", 0.75);
296
    d->shadow_thickness = config->readNumEntry("ShadowThickness", 10);
297
    d->shadow_x_offset = config->readNumEntry("ShadowXOffset", 0);
298
    d->shadow_y_offset = config->readNumEntry("ShadowYOffset", 10);
299
267
    emit resetClients();
300
    emit resetClients();
268
}
301
}
269
302
Lines 313-318 Link Here
313
    return MouseNothing;
346
    return MouseNothing;
314
}
347
}
315
348
349
QColor &Options::shadowColour(bool active)
350
{
351
    return active ? d->shadow_colour : d->shadow_inactive_colour;
352
}
353
354
bool Options::shadowWindowType(NET::WindowType t)
355
{
356
    bool retval;
357
358
    switch (t) {
359
        case NET::Dialog:
360
        case NET::Normal:
361
            retval = true;
362
            break;
363
        case NET::Desktop:
364
        case NET::Menu:
365
        case NET::Toolbar:
366
            retval = false;
367
            break;
368
        case NET::Dock:
369
            retval = d->shadow_docks;
370
            break;
371
        case NET::Override:
372
            retval = d->shadow_overrides;
373
            break;
374
        case NET::TopMenu:
375
            retval = d->shadow_topMenus;
376
            break;
377
        default:
378
            retval = false;
379
            break;
380
    }
381
382
    return retval;
383
}
384
385
bool Options::shadowEnabled(bool active)
386
{
387
    return active ? d->shadow_enabled : d->shadow_inactive_enabled;
388
}
389
390
double Options::shadowOpacity(bool active)
391
{
392
    return active ? d->shadow_opacity : d->shadow_inactive_opacity;
393
}
394
395
int Options::shadowThickness(bool active)
396
{
397
    return active ? d->shadow_thickness : d->shadow_inactive_thickness;
398
}
399
400
int Options::shadowXOffset(bool active)
401
{
402
    return active ? d->shadow_x_offset : d->shadow_inactive_x_offset;
403
}
404
405
int Options::shadowYOffset(bool active)
406
{
407
    return active ? d->shadow_y_offset : d->shadow_inactive_y_offset;
408
}
409
316
QString Options::titleButtonsLeft()
410
QString Options::titleButtonsLeft()
317
{
411
{
318
    return d->title_buttons_left;
412
    return d->title_buttons_left;
(-)options.h.orig (+40 lines)
Lines 10-15 Link Here
10
#include <qfont.h>
10
#include <qfont.h>
11
#include <qpalette.h>
11
#include <qpalette.h>
12
#include <qstringlist.h>
12
#include <qstringlist.h>
13
#include <netwm_def.h>
13
14
14
// increment this when you add a color type (mosfet)
15
// increment this when you add a color type (mosfet)
15
#define KWINCOLORS 6
16
#define KWINCOLORS 6
Lines 254-259 Link Here
254
    static MouseCommand mouseCommand(const QString &name);
255
    static MouseCommand mouseCommand(const QString &name);
255
256
256
    /**
257
    /**
258
    * @returns A QColor representing the colour that window drop shadows should
259
    *          be.
260
    */
261
    QColor &shadowColour(bool active=true);
262
263
    /**
264
     * @returns true if shadows should be drawn around windows of the
265
     *          specified type
266
     */
267
    bool shadowWindowType(NET::WindowType t);
268
269
    /**
270
    * @returns true if window shadows should be drawn
271
    */
272
    bool shadowEnabled(bool active=true);
273
274
    /**
275
    * @returns Window shadow's opacity between 0.01 and 1.00.
276
    */
277
    double shadowOpacity(bool active=true);
278
279
    /**
280
    * @returns How thick a shadow should be to either side of of a window.
281
    */
282
    int shadowThickness(bool active=true);
283
284
    /**
285
    * @returns Number of pixels along the X-axis by which to offset window
286
    *          shadows.
287
    */
288
    int shadowXOffset(bool active=true);
289
290
    /**
291
    * @returns Number of pixels along the Y-axis by which to offset window
292
    *          shadows.
293
    */
294
    int shadowYOffset(bool active=true);
295
296
    /**
257
    * @returns true if the style should use custom button positions
297
    * @returns true if the style should use custom button positions
258
    * @see #titleButtonsLeft
298
    * @see #titleButtonsLeft
259
    * @see #titleButtonsRight
299
    * @see #titleButtonsRight
(-)workspace.cpp.orig (-24 / +119 lines)
Lines 1265-1276 Link Here
1265
    Client* first = desktops.first();
1265
    Client* first = desktops.first();
1266
    desktops.remove( first );
1266
    desktops.remove( first );
1267
    desktops.append( first );
1267
    desktops.append( first );
1268
    Window* new_stack = new Window[ desktops.count() + 1 ];
1268
    int i, j, numDocks;
1269
    int i = 0;
1269
    Window shadow;
1270
    for ( ClientList::ConstIterator it = desktops.fromLast(); it != desktops.end(); --it)
1270
    Window *dock_shadow_stack, *window_stack;
1271
        new_stack[i++] = (*it)->winId();
1271
1272
    XRestackWindows(qt_xdisplay(), new_stack, i);
1272
    dock_shadow_stack = new Window[stacking_order.count() * 2];
1273
    delete [] new_stack;
1273
    window_stack = new Window[stacking_order.count() * 2];
1274
    i = 0;
1275
    j = 0;
1276
    for ( ClientList::ConstIterator it = stacking_order.fromLast();
1277
            it != stacking_order.end(); --it) {
1278
        window_stack[i++] = (*it)->winId();
1279
        if ((*it)->isDock()) {
1280
            if ((shadow = (*it)->shadowId()) != None)
1281
                dock_shadow_stack[j++] = shadow;
1282
            }
1283
            else {
1284
                if ((shadow = (*it)->shadowId()) != None)
1285
                    // If the current window also has a shadow, place it
1286
                    // immediately under the current window
1287
                    window_stack[i++] = shadow;
1288
            }
1289
    }
1290
    numDocks = j;
1291
    for (j = 0; j < numDocks; j++)
1292
        // Shadows for dock windows go at the bottom of the stack
1293
        window_stack[i++] = dock_shadow_stack[j++];
1294
1295
    XRestackWindows(qt_xdisplay(), window_stack, i);
1296
    delete [] dock_shadow_stack;
1297
    delete [] window_stack;
1274
}
1298
}
1275
1299
1276
void Workspace::addClient( Client* c )
1300
void Workspace::addClient( Client* c )
Lines 1874-1879 Link Here
1874
    else
1898
    else
1875
       destroyBorderWindows();
1899
       destroyBorderWindows();
1876
1900
1901
    emit reconfigured();
1877
}
1902
}
1878
1903
1879
/*!
1904
/*!
Lines 1939-1950 Link Here
1939
    stacking_order.prepend(c);
1964
    stacking_order.prepend(c);
1940
1965
1941
    stacking_order = constrainedStackingOrder( stacking_order );
1966
    stacking_order = constrainedStackingOrder( stacking_order );
1942
    Window* new_stack = new Window[ stacking_order.count() + 1 ];
1967
    int i, j, numDocks;
1943
    int i = 0;
1968
    Window shadow;
1944
    for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
1969
    Window *dock_shadow_stack, *window_stack;
1945
        new_stack[i++] = (*it)->winId();
1970
1946
    XRestackWindows(qt_xdisplay(), new_stack, i);
1971
    dock_shadow_stack = new Window[stacking_order.count() * 2];
1947
    delete [] new_stack;
1972
    window_stack = new Window[stacking_order.count() * 2];
1973
    i = 0;
1974
    j = 0;
1975
    for ( ClientList::ConstIterator it = stacking_order.fromLast();
1976
            it != stacking_order.end(); --it) {
1977
        window_stack[i++] = (*it)->winId();
1978
        if ((*it)->isDock()) {
1979
            if ((shadow = (*it)->shadowId()) != None)
1980
                dock_shadow_stack[j++] = shadow;
1981
            }
1982
            else {
1983
                if ((shadow = (*it)->shadowId()) != None)
1984
                    // If the current window also has a shadow, place it
1985
                    // immediately under the current window
1986
                    window_stack[i++] = shadow;
1987
            }
1988
    }
1989
    numDocks = j;
1990
    for (j = 0; j < numDocks; j++)
1991
        // Shadows for dock windows go at the bottom of the stack
1992
        window_stack[i++] = dock_shadow_stack[j++];
1993
1994
    XRestackWindows(qt_xdisplay(), window_stack, i);
1995
    delete [] dock_shadow_stack;
1996
    delete [] window_stack;
1948
1997
1949
    propagateClients( TRUE );
1998
    propagateClients( TRUE );
1950
1999
Lines 2024-2036 Link Here
2024
    }
2073
    }
2025
    /* end workaround */
2074
    /* end workaround */
2026
2075
2027
    Window* new_stack = new Window[ stacking_order.count() + 1 ];
2076
    int i, j, numDocks;
2028
    int i = 0;
2077
    Window shadow;
2029
    for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
2078
    Window *dock_shadow_stack, *window_stack;
2030
        new_stack[i++] = (*it)->winId();
2031
    XRestackWindows(qt_xdisplay(), new_stack, i);
2032
    delete [] new_stack;
2033
2079
2080
    dock_shadow_stack = new Window[stacking_order.count() * 2];
2081
    window_stack = new Window[stacking_order.count() * 2];
2082
    i = 0;
2083
    j = 0;
2084
    for ( ClientList::ConstIterator it = stacking_order.fromLast();
2085
            it != stacking_order.end(); --it) {
2086
        window_stack[i++] = (*it)->winId();
2087
        if ((*it)->isDock()) {
2088
            if ((shadow = (*it)->shadowId()) != None)
2089
                dock_shadow_stack[j++] = shadow;
2090
            }
2091
            else {
2092
                if ((shadow = (*it)->shadowId()) != None)
2093
                    // If the current window also has a shadow, place it
2094
                    // immediately under the current window
2095
                    window_stack[i++] = shadow;
2096
            }
2097
    }
2098
    numDocks = j;
2099
    for (j = 0; j < numDocks; j++)
2100
        // Shadows for dock windows go at the bottom of the stack
2101
        window_stack[i++] = dock_shadow_stack[j++];
2102
2103
    XRestackWindows(qt_xdisplay(), window_stack, i);
2104
    delete [] dock_shadow_stack;
2105
    delete [] window_stack;
2034
2106
2035
    propagateClients( TRUE );
2107
    propagateClients( TRUE );
2036
2108
Lines 2054-2066 Link Here
2054
    stacking_order.remove( c );
2126
    stacking_order.remove( c );
2055
    stacking_order.insert( it, c );
2127
    stacking_order.insert( it, c );
2056
    stacking_order = constrainedStackingOrder( stacking_order );
2128
    stacking_order = constrainedStackingOrder( stacking_order );
2057
    Window* new_stack = new Window[ stacking_order.count() + 1 ];
2129
    int i, j, numDocks;
2058
    int i = 0;
2130
    Window shadow;
2059
    for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
2131
    Window *dock_shadow_stack, *window_stack;
2060
        new_stack[i++] = (*it)->winId();
2132
2133
    dock_shadow_stack = new Window[stacking_order.count() * 2];
2134
    window_stack = new Window[stacking_order.count() * 2];
2135
    i = 0;
2136
    j = 0;
2137
    for ( ClientList::ConstIterator it = stacking_order.fromLast();
2138
            it != stacking_order.end(); --it) {
2139
        window_stack[i++] = (*it)->winId();
2140
        if ((*it)->isDock()) {
2141
            if ((shadow = (*it)->shadowId()) != None)
2142
                dock_shadow_stack[j++] = shadow;
2143
            }
2144
            else {
2145
                if ((shadow = (*it)->shadowId()) != None)
2146
                    // If the current window also has a shadow, place it
2147
                    // immediately under the current window
2148
                    window_stack[i++] = shadow;
2149
            }
2061
    }
2150
    }
2062
    XRestackWindows(qt_xdisplay(), new_stack, i);
2151
    numDocks = j;
2063
    delete [] new_stack;
2152
    for (j = 0; j < numDocks; j++)
2153
        // Shadows for dock windows go at the bottom of the stack
2154
        window_stack[i++] = dock_shadow_stack[j++];
2155
2156
    XRestackWindows(qt_xdisplay(), window_stack, i);
2157
    delete [] dock_shadow_stack;
2158
    delete [] window_stack;
2064
2159
2065
    propagateClients( TRUE );
2160
    propagateClients( TRUE );
2066
}
2161
}
(-)workspace.h.orig (+3 lines)
Lines 268-273 Link Here
268
268
269
    bool isNotManaged( const QString& title );
269
    bool isNotManaged( const QString& title );
270
270
271
signals:
272
    void reconfigured();
273
271
public slots:
274
public slots:
272
    void refresh();
275
    void refresh();
273
    // keybindings
276
    // keybindings
(-)kcmkwin/kwindecoration/kwindecoration.cpp.orig (-23 / +261 lines)
Lines 10-16 Link Here
10
	Supports new kwin configuration plugins, and titlebar button position
10
	Supports new kwin configuration plugins, and titlebar button position
11
	modification via dnd interface.
11
	modification via dnd interface.
12
12
13
	Based on original "kwintheme" (Window Borders) 
13
	Based on original "kwintheme" (Window Borders)
14
	Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
14
	Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
15
*/
15
*/
16
16
Lines 25-32 Link Here
25
#include <qvbox.h>
25
#include <qvbox.h>
26
#include <qlabel.h>
26
#include <qlabel.h>
27
#include <qfile.h>
27
#include <qfile.h>
28
#include <qslider.h>
29
#include <qspinbox.h>
28
30
29
#include <kapplication.h>
31
#include <kapplication.h>
32
#include <kcolorbutton.h>
30
#include <kdebug.h>
33
#include <kdebug.h>
31
#include <kdesktopfile.h>
34
#include <kdesktopfile.h>
32
#include <kstandarddirs.h>
35
#include <kstandarddirs.h>
Lines 61-74 Link Here
61
	page1->setMargin( KDialog::marginHint() );
64
	page1->setMargin( KDialog::marginHint() );
62
65
63
	QGroupBox* btnGroup = new QGroupBox( 1, Qt::Horizontal, i18n("Window Decoration"), page1 );
66
	QGroupBox* btnGroup = new QGroupBox( 1, Qt::Horizontal, i18n("Window Decoration"), page1 );
64
	QWhatsThis::add( btnGroup, 
67
	QWhatsThis::add( btnGroup,
65
			i18n("Select the window decoration. This is the look and feel of both "
68
			i18n("Select the window decoration. This is the look and feel of both "
66
			"the window borders and the window handle.") );
69
			"the window borders and the window handle.") );
67
	decorationListBox = new QListBox( btnGroup );
70
	decorationListBox = new QListBox( btnGroup );
68
71
69
	QGroupBox* checkGroup = new QGroupBox( 1, Qt::Horizontal, 
72
	QGroupBox* checkGroup = new QGroupBox( 1, Qt::Horizontal,
70
			i18n("General Options (if available)"), page1 );
73
			i18n("General Options (if available)"), page1 );
71
			
74
72
75
73
	cbUseCustomButtonPositions = new QCheckBox(
76
	cbUseCustomButtonPositions = new QCheckBox(
74
			i18n("Use custom titlebar button &positions"), checkGroup );
77
			i18n("Use custom titlebar button &positions"), checkGroup );
Lines 76-87 Link Here
76
			i18n(  "The appropriate settings can be found in the \"Buttons\" Tab. "
79
			i18n(  "The appropriate settings can be found in the \"Buttons\" Tab. "
77
				   "Please note that this option is not available on all styles yet!" ) );
80
				   "Please note that this option is not available on all styles yet!" ) );
78
81
79
	cbShowToolTips = new QCheckBox( 
82
	cbShowToolTips = new QCheckBox(
80
			i18n("&Show window button tooltips"), checkGroup );
83
			i18n("&Show window button tooltips"), checkGroup );
81
	QWhatsThis::add( cbShowToolTips, 
84
	QWhatsThis::add( cbShowToolTips,
82
			i18n(  "Enabling this checkbox will show window button tooltips. "
85
			i18n(  "Enabling this checkbox will show window button tooltips. "
83
				   "If this checkbox is off, no window button tooltips will be shown."));
86
				   "If this checkbox is off, no window button tooltips will be shown."));
84
87
88
	cbWindowShadow = new QCheckBox(
89
			i18n("&Draw a drop shadow under windows"), checkGroup);
90
	QWhatsThis::add(cbWindowShadow,
91
			i18n("Enabling this checkbox will allow you to choose a kind of "
92
				 "drop shadow to draw under each window."));
93
85
// Save this for later...
94
// Save this for later...
86
//	cbUseMiniWindows = new QCheckBox( i18n( "Render mini &titlebars for all windows"), checkGroup );
95
//	cbUseMiniWindows = new QCheckBox( i18n( "Render mini &titlebars for all windows"), checkGroup );
87
//	QWhatsThis::add( cbUseMiniWindows, i18n( "Note that this option is not available on all styles yet!" ) );
96
//	QWhatsThis::add( cbUseMiniWindows, i18n( "Note that this option is not available on all styles yet!" ) );
Lines 91-100 Link Here
91
	buttonPage->setSpacing( KDialog::spacingHint() );
100
	buttonPage->setSpacing( KDialog::spacingHint() );
92
	buttonPage->setMargin( KDialog::marginHint() );
101
	buttonPage->setMargin( KDialog::marginHint() );
93
102
94
	QGroupBox* buttonBox = new QGroupBox( 1, Qt::Horizontal, 
103
	QGroupBox* buttonBox = new QGroupBox( 1, Qt::Horizontal,
95
			i18n("Titlebar Button Position"), buttonPage );
104
			i18n("Titlebar Button Position"), buttonPage );
96
105
97
	// Add nifty dnd button modification widgets    
106
	// Add nifty dnd button modification widgets
98
	QLabel* label = new QLabel( buttonBox );
107
	QLabel* label = new QLabel( buttonBox );
99
	dropSite = new ButtonDropSite( buttonBox );
108
	dropSite = new ButtonDropSite( buttonBox );
100
	label->setText( i18n( "To add or remove titlebar buttons, simply <i>drag</i> items "
109
	label->setText( i18n( "To add or remove titlebar buttons, simply <i>drag</i> items "
Lines 102-108 Link Here
102
		"drag items within the titlebar preview to re-position them.") );
111
		"drag items within the titlebar preview to re-position them.") );
103
	buttonSource = new ButtonSource( buttonBox );
112
	buttonSource = new ButtonSource( buttonBox );
104
113
105
	// Page 3 (Configure decoration via client plugin page)
114
	// Page 3 (Window Shadows)
115
	QGroupBox *activeShadowSettings, *inactiveShadowSettings;
116
	QGroupBox *whichShadowSettings;
117
	QHBox *inactiveShadowColourHBox, *shadowColourHBox;
118
	QHBox *inactiveShadowOpacityHBox, *shadowOpacityHBox;
119
	QHBox *inactiveShadowXOffsetHBox, *shadowXOffsetHBox;
120
	QHBox *inactiveShadowYOffsetHBox, *shadowYOffsetHBox;
121
	QHBox *inactiveShadowThicknessHBox, *shadowThicknessHBox;
122
	QLabel *inactiveShadowColourLabel, *shadowColourLabel;
123
	QLabel *inactiveShadowOpacityLabel, *shadowOpacityLabel;
124
	QLabel *inactiveShadowXOffsetLabel, *shadowXOffsetLabel;
125
	QLabel *inactiveShadowYOffsetLabel, *shadowYOffsetLabel;
126
	QLabel *inactiveShadowThicknessLabel, *shadowThicknessLabel;
127
128
	shadowPage = new QVBox(tabWidget);
129
	shadowPage->setSpacing(KDialog::spacingHint());
130
	shadowPage->setMargin(KDialog::marginHint());
131
132
	activeShadowSettings = new QGroupBox(1, Qt::Horizontal,
133
			i18n("Active Window Shadow"), shadowPage);
134
	inactiveShadowSettings = new QGroupBox(1, Qt::Horizontal,
135
			i18n("Inactive Window Shadows"), shadowPage);
136
	whichShadowSettings = new QGroupBox(3, Qt::Horizontal,
137
			i18n("Draw Shadow Under Normal Windows And..."), shadowPage);
138
139
	cbShadowDocks = new QCheckBox(i18n("Docks and &panels"),
140
			whichShadowSettings);
141
	connect(cbShadowDocks, SIGNAL(toggled(bool)),
142
			SLOT(slotSelectionChanged()));
143
	cbShadowOverrides = new QCheckBox(i18n("O&verride windows"),
144
			whichShadowSettings);
145
	connect(cbShadowOverrides, SIGNAL(toggled(bool)),
146
			SLOT(slotSelectionChanged()));
147
	cbShadowTopMenus = new QCheckBox(i18n("&Top menu"),
148
			whichShadowSettings);
149
	connect(cbShadowTopMenus, SIGNAL(toggled(bool)),
150
			SLOT(slotSelectionChanged()));
151
	cbInactiveShadow = new QCheckBox(
152
			i18n("Draw shadow under &inactive windows"), inactiveShadowSettings);
153
	connect(cbInactiveShadow, SIGNAL(toggled(bool)),
154
			SLOT(slotSelectionChanged()));
155
156
	shadowColourHBox = new QHBox(activeShadowSettings);
157
	shadowColourHBox->setSpacing(KDialog::spacingHint());
158
	shadowColourLabel = new QLabel(i18n("Colour:"), shadowColourHBox);
159
	shadowColourButton = new KColorButton(shadowColourHBox);
160
	connect(shadowColourButton, SIGNAL(changed(const QColor &)), SLOT(slotSelectionChanged()));
161
162
	inactiveShadowColourHBox = new QHBox(inactiveShadowSettings);
163
	inactiveShadowColourHBox->setSpacing(KDialog::spacingHint());
164
	inactiveShadowColourLabel = new QLabel(i18n("Colour:"), inactiveShadowColourHBox);
165
	inactiveShadowColourButton = new KColorButton(inactiveShadowColourHBox);
166
	connect(inactiveShadowColourButton, SIGNAL(changed(const QColor &)), SLOT(slotSelectionChanged()));
167
168
	shadowOpacityHBox = new QHBox(activeShadowSettings);
169
	shadowOpacityHBox->setSpacing(KDialog::spacingHint());
170
	shadowOpacityLabel = new QLabel(i18n("Maximum opacity:"), shadowOpacityHBox);
171
	shadowOpacitySlider = new QSlider(1, 100, 10, 50, Qt::Horizontal,
172
			shadowOpacityHBox);
173
	shadowOpacitySlider->setTickmarks(QSlider::Below);
174
	shadowOpacitySlider->setTickInterval(10);
175
	shadowOpacitySpinBox = new QSpinBox(1, 100, 1, shadowOpacityHBox);
176
	shadowOpacitySpinBox->setSuffix(" %");
177
	connect(shadowOpacitySlider, SIGNAL(valueChanged(int)), shadowOpacitySpinBox,
178
			SLOT(setValue(int)));
179
	connect(shadowOpacitySpinBox, SIGNAL(valueChanged(int)), shadowOpacitySlider,
180
			SLOT(setValue(int)));
181
	connect(shadowOpacitySlider, SIGNAL(valueChanged(int)),
182
			SLOT(slotSelectionChanged()));
183
184
	inactiveShadowOpacityHBox = new QHBox(inactiveShadowSettings);
185
	inactiveShadowOpacityHBox->setSpacing(KDialog::spacingHint());
186
	inactiveShadowOpacityLabel = new QLabel(i18n("Maximum opacity:"),
187
			inactiveShadowOpacityHBox);
188
	inactiveShadowOpacitySlider = new QSlider(1, 100, 10, 50, Qt::Horizontal,
189
			inactiveShadowOpacityHBox);
190
	inactiveShadowOpacitySlider->setTickmarks(QSlider::Below);
191
	inactiveShadowOpacitySlider->setTickInterval(10);
192
	inactiveShadowOpacitySpinBox = new QSpinBox(1, 100, 1,
193
			inactiveShadowOpacityHBox);
194
	inactiveShadowOpacitySpinBox->setSuffix(" %");
195
	connect(inactiveShadowOpacitySlider, SIGNAL(valueChanged(int)),
196
			inactiveShadowOpacitySpinBox,
197
			SLOT(setValue(int)));
198
	connect(inactiveShadowOpacitySpinBox, SIGNAL(valueChanged(int)),
199
			inactiveShadowOpacitySlider,
200
			SLOT(setValue(int)));
201
	connect(inactiveShadowOpacitySlider, SIGNAL(valueChanged(int)),
202
			SLOT(slotSelectionChanged()));
203
204
	shadowXOffsetHBox = new QHBox(activeShadowSettings);
205
	shadowXOffsetHBox->setSpacing(KDialog::spacingHint());
206
	shadowXOffsetLabel = new QLabel(
207
			i18n("Offset rightward (may be negative):"),
208
			shadowXOffsetHBox);
209
	shadowXOffsetSpinBox = new QSpinBox(-1024, 1024, 1, shadowXOffsetHBox);
210
	shadowXOffsetSpinBox->setSuffix(i18n(" pixels"));
211
	connect(shadowXOffsetSpinBox, SIGNAL(valueChanged(int)),
212
			SLOT(slotSelectionChanged()));
213
214
	inactiveShadowXOffsetHBox = new QHBox(inactiveShadowSettings);
215
	inactiveShadowXOffsetHBox->setSpacing(KDialog::spacingHint());
216
	inactiveShadowXOffsetLabel = new QLabel(
217
			i18n("Offset rightward (may be negative):"),
218
			inactiveShadowXOffsetHBox);
219
	inactiveShadowXOffsetSpinBox = new QSpinBox(-1024, 1024, 1,
220
			inactiveShadowXOffsetHBox);
221
	inactiveShadowXOffsetSpinBox->setSuffix(i18n(" pixels"));
222
	connect(inactiveShadowXOffsetSpinBox, SIGNAL(valueChanged(int)),
223
			SLOT(slotSelectionChanged()));
224
225
	shadowYOffsetHBox = new QHBox(activeShadowSettings);
226
	shadowYOffsetHBox->setSpacing(KDialog::spacingHint());
227
	shadowYOffsetLabel = new QLabel(
228
			i18n("Offset downward (may be negative):"),
229
			shadowYOffsetHBox);
230
	shadowYOffsetSpinBox = new QSpinBox(-1024, 1024, 1, shadowYOffsetHBox);
231
	shadowYOffsetSpinBox->setSuffix(i18n(" pixels"));
232
	connect(shadowYOffsetSpinBox, SIGNAL(valueChanged(int)),
233
			SLOT(slotSelectionChanged()));
234
235
	inactiveShadowYOffsetHBox = new QHBox(inactiveShadowSettings);
236
	inactiveShadowYOffsetHBox->setSpacing(KDialog::spacingHint());
237
	inactiveShadowYOffsetLabel = new QLabel(
238
			i18n("Offset downward (may be negative):"),
239
			inactiveShadowYOffsetHBox);
240
	inactiveShadowYOffsetSpinBox = new QSpinBox(-1024, 1024, 1,
241
			inactiveShadowYOffsetHBox);
242
	inactiveShadowYOffsetSpinBox->setSuffix(i18n(" pixels"));
243
	connect(inactiveShadowYOffsetSpinBox, SIGNAL(valueChanged(int)),
244
			SLOT(slotSelectionChanged()));
245
246
	shadowThicknessHBox = new QHBox(activeShadowSettings);
247
	shadowThicknessHBox->setSpacing(KDialog::spacingHint());
248
	shadowThicknessLabel = new QLabel(
249
			i18n("Thickness to either side of window:"),
250
			shadowThicknessHBox);
251
	shadowThicknessSpinBox = new QSpinBox(1, 100, 1,
252
			shadowThicknessHBox);
253
	shadowThicknessSpinBox->setSuffix(i18n(" pixels"));
254
	connect(shadowThicknessSpinBox, SIGNAL(valueChanged(int)),
255
			SLOT(slotSelectionChanged()));
256
257
	inactiveShadowThicknessHBox = new QHBox(inactiveShadowSettings);
258
	inactiveShadowThicknessHBox->setSpacing(KDialog::spacingHint());
259
	inactiveShadowThicknessLabel = new QLabel(
260
			i18n("Thickness to either side of window:"),
261
			inactiveShadowThicknessHBox);
262
	inactiveShadowThicknessSpinBox = new QSpinBox(1, 100, 1,
263
			inactiveShadowThicknessHBox);
264
	inactiveShadowThicknessSpinBox->setSuffix(i18n(" pixels"));
265
	connect(inactiveShadowThicknessSpinBox, SIGNAL(valueChanged(int)),
266
			SLOT(slotSelectionChanged()));
267
268
	// Page 4 (Configure decoration via client plugin page)
106
	pluginPage = new QVBox( tabWidget );
269
	pluginPage = new QVBox( tabWidget );
107
	pluginPage->setSpacing( KDialog::spacingHint() );
270
	pluginPage->setSpacing( KDialog::spacingHint() );
108
	pluginPage->setMargin( KDialog::marginHint() );
271
	pluginPage->setMargin( KDialog::marginHint() );
Lines 117-126 Link Here
117
280
118
	tabWidget->insertTab( page1, i18n("&General") );
281
	tabWidget->insertTab( page1, i18n("&General") );
119
	tabWidget->insertTab( buttonPage, i18n("&Buttons") );
282
	tabWidget->insertTab( buttonPage, i18n("&Buttons") );
120
	tabWidget->insertTab( pluginPage, i18n("&Configure [") + 
283
	tabWidget->insertTab( shadowPage, i18n("S&hadows") );
284
	tabWidget->insertTab( pluginPage, i18n("&Configure [") +
121
						  decorationListBox->currentText() + i18n("]") );
285
						  decorationListBox->currentText() + i18n("]") );
122
286
123
	tabWidget->setTabEnabled( buttonPage, cbUseCustomButtonPositions->isChecked() );
287
	tabWidget->setTabEnabled( buttonPage, cbUseCustomButtonPositions->isChecked() );
288
	tabWidget->setTabEnabled(shadowPage, cbWindowShadow->isChecked());
124
	tabWidget->setTabEnabled( pluginPage, pluginObject ? true : false );
289
	tabWidget->setTabEnabled( pluginPage, pluginObject ? true : false );
125
290
126
	connect( dropSite, SIGNAL(buttonAdded(char)), buttonSource, SLOT(hideButton(char)) );
291
	connect( dropSite, SIGNAL(buttonAdded(char)), buttonSource, SLOT(hideButton(char)) );
Lines 129-139 Link Here
129
	connect( dropSite, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );
294
	connect( dropSite, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );
130
	connect( buttonSource, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
295
	connect( buttonSource, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
131
	connect( decorationListBox, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()) );
296
	connect( decorationListBox, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()) );
132
	connect( decorationListBox, SIGNAL(highlighted(const QString&)), 
297
	connect( decorationListBox, SIGNAL(highlighted(const QString&)),
133
								SLOT(slotDecorationHighlighted(const QString&)) );
298
								SLOT(slotDecorationHighlighted(const QString&)) );
134
	connect( cbUseCustomButtonPositions, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
299
	connect( cbUseCustomButtonPositions, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
135
	connect( cbUseCustomButtonPositions, SIGNAL(toggled(bool)), SLOT(slotEnableButtonTab(bool)) );
300
	connect( cbUseCustomButtonPositions, SIGNAL(toggled(bool)), SLOT(slotEnableButtonTab(bool)) );
136
	connect( cbShowToolTips, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
301
	connect( cbShowToolTips, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
302
	connect( cbWindowShadow, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
303
	connect( cbWindowShadow, SIGNAL(toggled(bool)), SLOT(slotEnableShadowTab(bool)) );
137
//	connect( cbUseMiniWindows, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
304
//	connect( cbUseMiniWindows, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
138
305
139
	// Allow kwin dcop signal to update our selection list
306
	// Allow kwin dcop signal to update our selection list
Lines 184-190 Link Here
184
	QValueList<DecorationInfo>::ConstIterator it;
351
	QValueList<DecorationInfo>::ConstIterator it;
185
352
186
	// Sync with kwin hardcoded KDE2 style which has no desktop item
353
	// Sync with kwin hardcoded KDE2 style which has no desktop item
187
	decorationListBox->insertItem( i18n("KDE 2") ); 
354
	decorationListBox->insertItem( i18n("KDE 2") );
188
355
189
	for (it = decorations.begin(); it != decorations.end(); ++it)
356
	for (it = decorations.begin(); it != decorations.end(); ++it)
190
	{
357
	{
Lines 221-226 Link Here
221
	tabWidget->setTabEnabled( buttonPage, on );
388
	tabWidget->setTabEnabled( buttonPage, on );
222
}
389
}
223
390
391
void KWinDecorationModule::slotEnableShadowTab(bool on)
392
{
393
	tabWidget->setTabEnabled(shadowPage, on);
394
}
224
395
225
QString KWinDecorationModule::decorationName( QString& libName )
396
QString KWinDecorationModule::decorationName( QString& libName )
226
{
397
{
Lines 253-259 Link Here
253
		}
424
		}
254
425
255
	if (libName.isEmpty())
426
	if (libName.isEmpty())
256
		libName = "kwin_default";	// KDE 2 
427
		libName = "kwin_default";	// KDE 2
257
428
258
	return libName;
429
	return libName;
259
}
430
}
Lines 290-311 Link Here
290
461
291
	KLibrary* library = loader->library( QFile::encodeName(currentName) );
462
	KLibrary* library = loader->library( QFile::encodeName(currentName) );
292
	if (library != NULL)
463
	if (library != NULL)
293
	{		
464
	{
294
		void* alloc_ptr = library->symbol("allocate_config");
465
		void* alloc_ptr = library->symbol("allocate_config");
295
466
296
		if (alloc_ptr != NULL)
467
		if (alloc_ptr != NULL)
297
		{
468
		{
298
			allocatePlugin = (QObject* (*)(KConfig* conf, QWidget* parent))alloc_ptr;
469
			allocatePlugin = (QObject* (*)(KConfig* conf, QWidget* parent))alloc_ptr;
299
			pluginObject = allocatePlugin( conf, pluginPage );
470
			pluginObject = allocatePlugin( conf, pluginPage );
300
				
471
301
			// connect required signals and slots together...
472
			// connect required signals and slots together...
302
			connect( pluginObject, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );	
473
			connect( pluginObject, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );
303
			connect( this, SIGNAL(pluginLoad(KConfig*)), pluginObject, SLOT(load(KConfig*)) );
474
			connect( this, SIGNAL(pluginLoad(KConfig*)), pluginObject, SLOT(load(KConfig*)) );
304
			connect( this, SIGNAL(pluginSave(KConfig*)), pluginObject, SLOT(save(KConfig*)) );
475
			connect( this, SIGNAL(pluginSave(KConfig*)), pluginObject, SLOT(save(KConfig*)) );
305
			connect( this, SIGNAL(pluginDefaults()), pluginObject, SLOT(defaults()) );
476
			connect( this, SIGNAL(pluginDefaults()), pluginObject, SLOT(defaults()) );
306
477
307
			return;
478
			return;
308
		} 
479
		}
309
	}
480
	}
310
481
311
	pluginObject = NULL;
482
	pluginObject = NULL;
Lines 322-334 Link Here
322
	cbUseCustomButtonPositions->setChecked( conf->readBoolEntry("CustomButtonPositions", false));
493
	cbUseCustomButtonPositions->setChecked( conf->readBoolEntry("CustomButtonPositions", false));
323
	tabWidget->setTabEnabled( buttonPage, cbUseCustomButtonPositions->isChecked() );
494
	tabWidget->setTabEnabled( buttonPage, cbUseCustomButtonPositions->isChecked() );
324
	cbShowToolTips->setChecked( conf->readBoolEntry("ShowToolTips", true ));
495
	cbShowToolTips->setChecked( conf->readBoolEntry("ShowToolTips", true ));
496
	cbWindowShadow->setChecked( conf->readBoolEntry("ShadowEnabled", false) );
325
//	cbUseMiniWindows->setChecked( conf->readBoolEntry("MiniWindowBorders", false));
497
//	cbUseMiniWindows->setChecked( conf->readBoolEntry("MiniWindowBorders", false));
326
498
327
	// Find the corresponding decoration name to that of
499
	// Find the corresponding decoration name to that of
328
	// the current plugin library name
500
	// the current plugin library name
329
501
330
	oldLibraryName = currentLibraryName;
502
	oldLibraryName = currentLibraryName;
331
	currentLibraryName = conf->readEntry("PluginLib", 
503
	currentLibraryName = conf->readEntry("PluginLib",
332
					((QPixmap::defaultDepth() > 8) ? "kwin_keramik" : "kwin_quartz"));
504
					((QPixmap::defaultDepth() > 8) ? "kwin_keramik" : "kwin_quartz"));
333
	QString decoName = decorationName( currentLibraryName );
505
	QString decoName = decorationName( currentLibraryName );
334
506
Lines 349-354 Link Here
349
521
350
	buttonSource->showAllButtons();
522
	buttonSource->showAllButtons();
351
523
524
	// Shadows tab
525
	// ===========
526
	shadowColourButton->setColor(
527
			conf->readColorEntry("ShadowColour", &Qt::black));
528
	shadowOpacitySlider->setValue(
529
			(int)(conf->readDoubleNumEntry("ShadowOpacity", 0.75) * 100));
530
	shadowXOffsetSpinBox->setValue(conf->readNumEntry("ShadowXOffset", 0));
531
	shadowYOffsetSpinBox->setValue(conf->readNumEntry("ShadowYOffset", 8));
532
	cbShadowDocks->setChecked(
533
			conf->readBoolEntry("ShadowDocks", false));
534
	cbShadowOverrides->setChecked(
535
			conf->readBoolEntry("ShadowOverrides", false));
536
	cbShadowTopMenus->setChecked(
537
			conf->readBoolEntry("ShadowTopMenus", false));
538
	shadowThicknessSpinBox->setValue(
539
			conf->readNumEntry("ShadowThickness", 8));
540
	cbInactiveShadow->setChecked(
541
			conf->readBoolEntry("InactiveShadowEnabled", false));
542
	inactiveShadowColourButton->setColor(
543
			conf->readColorEntry("InactiveShadowColour", &Qt::black));
544
	inactiveShadowOpacitySlider->setValue(
545
			(int)(conf->readDoubleNumEntry("InactiveShadowOpacity", 0.75)*100));
546
	inactiveShadowXOffsetSpinBox->setValue(
547
			conf->readNumEntry("InactiveShadowXOffset", 0));
548
	inactiveShadowYOffsetSpinBox->setValue(
549
			conf->readNumEntry("InactiveShadowYOffset", 4));
550
	inactiveShadowThicknessSpinBox->setValue(
551
			conf->readNumEntry("InactiveShadowThickness", 4));
552
352
	// Step through the button lists, and hide the dnd button source items
553
	// Step through the button lists, and hide the dnd button source items
353
	unsigned int i;
554
	unsigned int i;
354
	for(i = 0; i < dropSite->buttonsLeft.length(); i++)
555
	for(i = 0; i < dropSite->buttonsLeft.length(); i++)
Lines 368-384 Link Here
368
569
369
	KConfig kwinConfig("kwinrc");
570
	KConfig kwinConfig("kwinrc");
370
	kwinConfig.setGroup("Style");
571
	kwinConfig.setGroup("Style");
371
    
572
372
	// General settings
573
	// General settings
373
	conf->writeEntry("PluginLib", libName);
574
	conf->writeEntry("PluginLib", libName);
374
	conf->writeEntry("CustomButtonPositions", cbUseCustomButtonPositions->isChecked());
575
	conf->writeEntry("CustomButtonPositions", cbUseCustomButtonPositions->isChecked());
375
	conf->writeEntry("ShowToolTips", cbShowToolTips->isChecked());
576
	conf->writeEntry("ShowToolTips", cbShowToolTips->isChecked());
577
	conf->writeEntry("ShadowEnabled", cbWindowShadow->isChecked());
376
//	conf->writeEntry("MiniWindowBorders", cbUseMiniWindows->isChecked());
578
//	conf->writeEntry("MiniWindowBorders", cbUseMiniWindows->isChecked());
377
579
378
	// Button settings
580
	// Button settings
379
	conf->writeEntry("ButtonsOnLeft", dropSite->buttonsLeft );
581
	conf->writeEntry("ButtonsOnLeft", dropSite->buttonsLeft );
380
	conf->writeEntry("ButtonsOnRight", dropSite->buttonsRight );
582
	conf->writeEntry("ButtonsOnRight", dropSite->buttonsRight );
381
583
584
	// Shadow settings
585
	conf->writeEntry("ShadowColour", shadowColourButton->color());
586
	conf->writeEntry("ShadowOpacity", shadowOpacitySlider->value() / 100.0);
587
	conf->writeEntry("ShadowXOffset", shadowXOffsetSpinBox->value());
588
	conf->writeEntry("ShadowYOffset", shadowYOffsetSpinBox->value());
589
	conf->writeEntry("ShadowThickness", shadowThicknessSpinBox->value());
590
	conf->writeEntry("ShadowDocks", cbShadowDocks->isChecked());
591
	conf->writeEntry("ShadowOverrides", cbShadowOverrides->isChecked());
592
	conf->writeEntry("ShadowTopMenus", cbShadowTopMenus->isChecked());
593
	conf->writeEntry("InactiveShadowEnabled", cbInactiveShadow->isChecked());
594
	conf->writeEntry("InactiveShadowColour", inactiveShadowColourButton->color());
595
	conf->writeEntry("InactiveShadowOpacity",
596
			inactiveShadowOpacitySlider->value() / 100.0);
597
	conf->writeEntry("InactiveShadowXOffset",
598
			inactiveShadowXOffsetSpinBox->value());
599
	conf->writeEntry("InactiveShadowYOffset",
600
			inactiveShadowYOffsetSpinBox->value());
601
	conf->writeEntry("InactiveShadowThickness",
602
			inactiveShadowThicknessSpinBox->value());
603
382
	oldLibraryName = currentLibraryName;
604
	oldLibraryName = currentLibraryName;
383
	currentLibraryName = libName;
605
	currentLibraryName = libName;
384
606
Lines 405-411 Link Here
405
	KConfig kwinConfig("kwinrc");
627
	KConfig kwinConfig("kwinrc");
406
	kwinConfig.setGroup("Style");
628
	kwinConfig.setGroup("Style");
407
629
408
	// Reset by re-reading the config 
630
	// Reset by re-reading the config
409
	// The plugin doesn't need changing, as we have not saved
631
	// The plugin doesn't need changing, as we have not saved
410
	readConfig( &kwinConfig );
632
	readConfig( &kwinConfig );
411
	emit pluginLoad( &kwinConfig );
633
	emit pluginLoad( &kwinConfig );
Lines 431-439 Link Here
431
	// Set the KDE defaults
653
	// Set the KDE defaults
432
	cbUseCustomButtonPositions->setChecked( false );
654
	cbUseCustomButtonPositions->setChecked( false );
433
	cbShowToolTips->setChecked( true );
655
	cbShowToolTips->setChecked( true );
656
	cbWindowShadow->setChecked( false );
434
//	cbUseMiniWindows->setChecked( false);
657
//	cbUseMiniWindows->setChecked( false);
435
// Don't set default for now
658
// Don't set default for now
436
//	decorationListBox->setSelected( 
659
//	decorationListBox->setSelected(
437
//		decorationListBox->findItem( i18n("KDE 2") ), true );  // KDE classic client
660
//		decorationListBox->findItem( i18n("KDE 2") ), true );  // KDE classic client
438
661
439
	dropSite->buttonsLeft = "MS";
662
	dropSite->buttonsLeft = "MS";
Lines 448-453 Link Here
448
	buttonSource->hideButton('A');
671
	buttonSource->hideButton('A');
449
	buttonSource->hideButton('X');
672
	buttonSource->hideButton('X');
450
673
674
	shadowColourButton->setColor(Qt::black);
675
	shadowOpacitySlider->setValue(75);
676
	shadowXOffsetSpinBox->setValue(0);
677
	shadowYOffsetSpinBox->setValue(10);
678
	shadowThicknessSpinBox->setValue(10);
679
	cbShadowDocks->setChecked(false);
680
	cbShadowOverrides->setChecked(false);
681
	cbShadowTopMenus->setChecked(false);
682
	cbInactiveShadow->setChecked(false);
683
	inactiveShadowColourButton->setColor(Qt::black);
684
	inactiveShadowOpacitySlider->setValue(75);
685
	inactiveShadowXOffsetSpinBox->setValue(0);
686
	inactiveShadowYOffsetSpinBox->setValue(5);
687
	inactiveShadowThicknessSpinBox->setValue(5);
688
451
	// Set plugin defaults
689
	// Set plugin defaults
452
	emit pluginDefaults();
690
	emit pluginDefaults();
453
}
691
}
Lines 463-469 Link Here
463
701
464
const KAboutData* KWinDecorationModule::aboutData() const
702
const KAboutData* KWinDecorationModule::aboutData() const
465
{
703
{
466
	KAboutData* about = 
704
	KAboutData* about =
467
		new KAboutData(I18N_NOOP("kcmkwindecoration"),
705
		new KAboutData(I18N_NOOP("kcmkwindecoration"),
468
				I18N_NOOP("Window Decoration Control Module"),
706
				I18N_NOOP("Window Decoration Control Module"),
469
				0, 0, KAboutData::License_GPL,
707
				0, 0, KAboutData::License_GPL,
Lines 477-483 Link Here
477
{
715
{
478
	bool ok = kapp->dcopClient()->send("kwin", "KWinInterface",
716
	bool ok = kapp->dcopClient()->send("kwin", "KWinInterface",
479
                        "reconfigure()", QByteArray());
717
                        "reconfigure()", QByteArray());
480
	if (!ok) 
718
	if (!ok)
481
		kdDebug() << "kcmkwindecoration: Could not reconfigure kwin" << endl;
719
		kdDebug() << "kcmkwindecoration: Could not reconfigure kwin" << endl;
482
}
720
}
483
721
(-)kcmkwin/kwindecoration/kwindecoration.h.orig (-3 / +20 lines)
Lines 10-16 Link Here
10
	Supports new kwin configuration plugins, and titlebar button position
10
	Supports new kwin configuration plugins, and titlebar button position
11
	modification via dnd interface.
11
	modification via dnd interface.
12
12
13
	Based on original "kwintheme" (Window Borders) 
13
	Based on original "kwintheme" (Window Borders)
14
	Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
14
	Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
15
*/
15
*/
16
16
Lines 25-32 Link Here
25
25
26
#include "kwindecorationIface.h"
26
#include "kwindecorationIface.h"
27
27
28
class QListBox;
28
class KColorButton;
29
class QCheckBox;
29
class QCheckBox;
30
class QHBox;
31
class QListBox;
32
class QSlider;
33
class QSpinBox;
30
class QTabWidget;
34
class QTabWidget;
31
class QVBox;
35
class QVBox;
32
36
Lines 64-69 Link Here
64
		// Allows us to turn "save" on
68
		// Allows us to turn "save" on
65
		void slotSelectionChanged();
69
		void slotSelectionChanged();
66
		void slotEnableButtonTab(bool on);
70
		void slotEnableButtonTab(bool on);
71
		void slotEnableShadowTab(bool on);
67
		void slotDecorationHighlighted( const QString& s );
72
		void slotDecorationHighlighted( const QString& s );
68
73
69
	private:
74
	private:
Lines 84-96 Link Here
84
		QValueList<DecorationInfo> decorations;
89
		QValueList<DecorationInfo> decorations;
85
		QCheckBox* cbUseCustomButtonPositions;
90
		QCheckBox* cbUseCustomButtonPositions;
86
	//	QCheckBox* cbUseMiniWindows;
91
	//	QCheckBox* cbUseMiniWindows;
87
		QCheckBox* cbShowToolTips;
92
		QCheckBox *cbShowToolTips;
93
		QCheckBox *cbWindowShadow;
88
94
89
		// Page 2
95
		// Page 2
90
		ButtonDropSite* dropSite;
96
		ButtonDropSite* dropSite;
91
		ButtonSource* buttonSource;
97
		ButtonSource* buttonSource;
92
98
93
		// Page 3
99
		// Page 3
100
		QVBox *shadowPage;
101
		KColorButton *inactiveShadowColourButton, *shadowColourButton;
102
		QCheckBox *cbShadowDocks, *cbShadowOverrides, *cbShadowTopMenus;
103
		QCheckBox *cbInactiveShadow;
104
		QSlider *inactiveShadowOpacitySlider, *shadowOpacitySlider;
105
		QSpinBox *inactiveShadowOpacitySpinBox, *shadowOpacitySpinBox;
106
		QSpinBox *inactiveShadowXOffsetSpinBox, *shadowXOffsetSpinBox;
107
		QSpinBox *inactiveShadowYOffsetSpinBox, *shadowYOffsetSpinBox;
108
		QSpinBox *inactiveShadowThicknessSpinBox, *shadowThicknessSpinBox;
109
110
		// Page 4
94
		QObject* pluginObject;
111
		QObject* pluginObject;
95
		QString  currentLibraryName;
112
		QString  currentLibraryName;
96
		QString  oldLibraryName;
113
		QString  oldLibraryName;

Return to bug 22710