Changeset 331 for trunk/src/gui/kernel


Ignore:
Timestamp:
Nov 20, 2009, 2:50:32 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui/kernel: QClipboard: Don't open clipboard in response to WM_RENDERFORMAT and WM_RENDERALLFMTS as it obviously causes a deadlock. Simplify the code by reducing the number of methods.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/kernel/qclipboard_pm.cpp

    r327 r331  
    5858#include "private/qpmobjectwindow_pm_p.h"
    5959
    60 #define QCLIPBOARD_DEBUG
     60#define QCLIPBOARD_DEBUG
    6161
    6262#ifdef QCLIPBOARD_DEBUG
    63 #include "qdebug.h"
     63#   include "qdebug.h"
     64#   define DEBUG(a) qDebug a
     65#else
     66#   define DEBUG(a) do {} while(0)
    6467#endif
    6568
     
    173176    void setAsClipboardViewer();
    174177    bool ownsClipboard();
    175     void renderAllFormats(bool isDelayed);
     178    void putAllMimeToClipboard(bool isDelayed);
     179    void flushClipboard();
    176180
    177181    static QClipboardData *instance()
     
    191195
    192196private:
    193     bool openClipboard();
    194     void closeClipboard();
    195197    bool setClipboard(QPMMime *converter, ULONG format, bool isDelayed);
    196     void renderFormat(ULONG format);
    197198
    198199    MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2);
     
    218219QClipboardData::~QClipboardData()
    219220{
    220     renderAllFormats(false);
    221221    setSource(0);
    222222
     
    237237    if (src)
    238238        matches = QPMMime::allConvertersFromMimeData(src);
     239
     240
     241
     242
     243
     244
     245
     246
     247
    239248}
    240249
    241250void QClipboardData::setAsClipboardViewer()
    242251{
     252
     253
    243254    HWND clipboardViewer = WinQueryClipbrdViewer(NULLHANDLE);
    244255    if (hwnd() != clipboardViewer) {
     
    259270}
    260271
    261 bool QClipboardData::openClipboard()
    262 {
    263     if (!WinOpenClipbrd(NULLHANDLE)) {
    264 #ifndef QT_NO_DEBUG
    265         qWarning("QClipboardData::openClipboard: WinOpenClipbrd "
    266                  "failed with 0x%lX", WinGetLastError(NULLHANDLE));
    267 #endif
    268         return false;
    269     }
    270     return true;
    271 }
    272 
    273 void QClipboardData::closeClipboard()
    274 {
    275     WinCloseClipbrd(NULLHANDLE);
    276 }
    277 
    278272bool QClipboardData::setClipboard(QPMMime *converter, ULONG format,
    279273                                  bool isDelayed)
     
    283277        return false;
    284278
    285     bool ok;
     279    bool ok;
    286280    ULONG flags = 0, data = 0;
    287281
     
    291285        if (ok) {
    292286            WinSetClipbrdOwner(NULLHANDLE, hwnd());
    293             WinSetClipbrdData(NULLHANDLE, 0, format, flags);
     287            WinSetClipbrdData(NULLHANDLE, 0, format, flags);
    294288        }
    295289    } else {
     
    297291        ok = converter->convertFromMimeData(src, format, flags, &data);
    298292        if (ok)
    299             WinSetClipbrdData(NULLHANDLE, data, format, flags);
    300     }
    301 #ifdef QCLIPBOARD_DEBUG
    302     qDebug("QClipboardData::setClipboard: convert to CF 0x%lX, flags 0x%lX,"
    303            "data 0x%lX, delayed %d, ok %d", format, flags, data, isDelayed, ok);
    304 #endif
    305 
    306     return ok;
    307 }
    308 
    309 void QClipboardData::renderFormat(ULONG format)
    310 {
    311 #ifdef QCLIPBOARD_DEBUG
    312     qDebug("QClipboardData::renderFormat: CF 0x%lX", format);
    313 #endif
    314 
    315     if (!src)
     293            ok2 = WinSetClipbrdData(NULLHANDLE, data, format, flags);
     294    }
     295    DEBUG(("QClipboardData::setClipboard: convert to CF 0x%lX flags 0x%lX "
     296           "data 0x%lX delayed %d ok %d", format, flags, data, isDelayed, ok));
     297#ifndef QT_NO_DEBUG
     298    if (!ok2) {
     299        qWarning("QClipboardData::setClipboard: WinSetClipbrdData "
     300                 "failed with 0x%lX", WinGetLastError(NULLHANDLE));
     301    }
     302#endif
     303
     304    return ok && ok2;
     305}
     306
     307void QClipboardData::putAllMimeToClipboard(bool isDelayed)
     308{
     309    DEBUG(() << "QClipboardData::putAllMimeToClipboard: isDelayed" << isDelayed);
     310
     311    if (!WinOpenClipbrd(NULLHANDLE)) {
     312#ifndef QT_NO_DEBUG
     313        qWarning("QClipboardData::putAllMimeToClipboard: WinOpenClipbrd "
     314                 "failed with 0x%lX", WinGetLastError(NULLHANDLE));
     315#endif
    316316        return;
    317 
    318     if (!openClipboard())
    319         return;
    320 
    321     foreach(QPMMime::Match match, matches) {
    322         if (match.format == format) {
    323             setClipboard(match.converter, match.format, false);
    324             break;
    325         }
    326     }
    327 
    328     closeClipboard();
    329 }
    330 
    331 void QClipboardData::renderAllFormats(bool isDelayed)
    332 {
    333 #ifdef QCLIPBOARD_DEBUG
    334     qDebug() << "QClipboardData::renderAllFormats: isDelayed" << isDelayed;
    335 #endif
    336 
    337     if (!openClipboard())
    338         return;
     317    }
    339318
    340319    // delete the clipboard contents before we render everything to make sure
     
    345324    if (!ok) {
    346325#ifndef QT_NO_DEBUG
    347         qWarning("QClipboardData::renderAllFormats: WinEmptyClipbrd "
     326        qWarning("QClipboardData::: WinEmptyClipbrd "
    348327                 "failed with 0x%lX", WinGetLastError(NULLHANDLE));
    349328#endif
     329
    350330        return;
    351331    }
    352332
    353333    if (src) {
    354 #ifdef QCLIPBOARD_DEBUG
    355         qDebug() << "QClipboardData::renderAllFormats: mimes" << src->formats();
    356 #endif
    357334        foreach(QPMMime::Match match, matches)
    358335            setClipboard(match.converter, match.format, isDelayed);
    359336    }
    360337
    361     closeClipboard();
     338    WinCloseClipbrd(NULLHANDLE);
     339}
     340
     341void QClipboardData::flushClipboard()
     342{
     343    if (ownsClipboard()) {
     344        putAllMimeToClipboard(false);
     345        // make sure we won't be doing this again if asked in WM_RENDERALLFMTS
     346        setSource(0);
     347    }
    362348}
    363349
    364350MRESULT QClipboardData::message(ULONG msg, MPARAM mp1, MPARAM mp2)
    365351{
    366 #ifdef QCLIPBOARD_DEBUG
    367     qDebug("QClipboardData::message: msg %08lX, mp1 %p, mp2 %p",
    368            msg, mp1, mp2);
    369 #endif
     352    DEBUG(("QClipboardData::message: msg %08lX, mp1 %p, mp2 %p",
     353           msg, mp1, mp2));
    370354
    371355    switch (msg) {
    372356
    373357        case WM_DRAWCLIPBOARD: {
     358
     359
    374360            // ask QClipboard to emit changed() signals
    375361            QClipboardEvent e(reinterpret_cast<QEventPrivate *>(1));
     
    391377                    prevClipboardViewer = NULLHANDLE;
    392378            }
    393             break;
    394         }
    395 
    396         case WM_DESTROYCLIPBOARD:
     379        }
     380        break;
     381
     382        case WM_DESTROYCLIPBOARD: {
     383            DEBUG(("QClipboardData::message: WM_DESTROYCLIPBOARD:"));
    397384            if (!ignore_WM_DESTROYCLIPBOARD)
    398385                setSource(0);
    399             break;
    400 
    401         case WM_RENDERFMT:
    402             renderFormat((ULONG)mp1);
    403             break;
    404 
    405         case WM_RENDERALLFMTS:
    406             renderAllFormats(false);
    407             break;
     386        }
     387        break;
     388
     389        case WM_RENDERFMT: {
     390            DEBUG(("QClipboardData::message: WM_RENDERFMT: CF 0x%lX", (ULONG)mp1));
     391            if (src) {
     392                foreach(QPMMime::Match match, matches) {
     393                    if (match.format == (ULONG)mp1) {
     394                        setClipboard(match.converter, match.format, false);
     395                        break;
     396                    }
     397                }
     398            }
     399        }
     400        break;
     401
     402        case WM_RENDERALLFMTS: {
     403            DEBUG(("QClipboardData::message: WM_RENDERALLFMTS:"));
     404            if (src) {
     405                foreach(QPMMime::Match match, matches)
     406                    setClipboard(match.converter, match.format, false);
     407            }
     408        }
     409        break;
    408410
    409411        default:
     
    411413    }
    412414
    413     return (MRESULT)TRUE;
     415    DEBUG(("QClipboardData::message: END"));
     416    return FALSE;
    414417}
    415418
     
    423426void QClipboard::setMimeData(QMimeData *src, Mode mode)
    424427{
    425 #ifdef QCLIPBOARD_DEBUG
    426     qDebug() << "QClipboard::setMimeData: src" << src << "mode" << mode;
    427 #endif
     428    DEBUG(() << "QClipboard::setMimeData: src" << src << "mode" << mode);
    428429
    429430    if (mode != Clipboard) {
     
    441442    bool runsEventLoop = d_func()->threadData->loopLevel != 0;
    442443
    443     d->renderAllFormats(runsEventLoop);
     444    d->(runsEventLoop);
    444445}
    445446
     
    456457    if (!((QClipboardEvent*)e)->data()) {
    457458        // this is sent by QApplication to render all formats at app shut down
    458         QClipboardData::instance()->renderAllFormats(false);
     459        QClipboardData::instance()->);
    459460    } else {
    460461        // this is sent by QClipboardData to notify about clipboard data change
Note: See TracChangeset for help on using the changeset viewer.