QString KCheckGmailTray::takeScreenshotOfTrayIcon() { // Process the events else the icon will not be there and the screenie will fail! kapp->processEvents(); // Taken from Akregator TrayIcon::takeScreenshot() const QRect rect = geometry(); const QPoint g = rect.topLeft(); int desktopWidth = kapp->desktop()->width(); int desktopHeight = kapp->desktop()->height(); int tw = rect.width(); int th = rect.height(); int w = desktopWidth / 4; int h = desktopHeight / 9; int x = g.x() + tw/2 - w/2; // Center the rectange in the systray icon int y = g.y() + th/2 - h/2; if (x < 0) x = 0; // Move the rectangle to stay in the desktop limits if (y < 0) y = 0; if (x + w > desktopWidth) x = desktopWidth - w; if (y + h > desktopHeight) y = desktopHeight - h; // Grab the desktop and draw a circle around the icon: QPixmap shot = QPixmap::grabWindow(QApplication::desktop()->winId(), x, y, w, h); QPainter painter(&shot); painter.setRenderHint( QPainter::Antialiasing ); const int MARGINS = 6; const int WIDTH = 3; int ax = g.x() - x - MARGINS -1; int ay = g.y() - y - MARGINS -1; painter.setPen( QPen(Qt::red/*KApplication::palette().active().highlight()*/, WIDTH) ); painter.drawArc(ax, ay, tw + 2*MARGINS, th + 2*MARGINS, 0, 16*360); painter.end(); // Paint the border const int BORDER = 1; QPixmap finalShot(w + 2*BORDER, h + 2*BORDER); finalShot.fill( KApplication::palette().color( QPalette::Foreground )); painter.begin(&finalShot); painter.drawPixmap(BORDER, BORDER, shot); painter.end(); // return shot; // not finalShot?? -fo // End of Taken from Akregator QString filename; KTemporaryFile* tmpfile = new KTemporaryFile; tmpfile->setAutoRemove(false); if (tmpfile->open()) { filename = tmpfile->fileName(); shot.save(tmpfile, "png"); tmpfile->close(); } return filename; }
void KSystemTray2::displayCloseMessage(QString fileMenu) { /* IDEAS OF IMPROVEMENTS: * - Use queuedMessageBox() but it need a dontAskAgainName parameter * and image in QMimeSourceFactory shouldn't be removed. * - Sometimes the systray icon is covered (a passive popup...) * Use XComposite extension, if available, to get the kicker pixmap. * - Perhapse desaturate the area around the proper SysTray icon, * helping bring it into sharper focus. Or draw the cicle with XOR * brush. * - Perhapse add the icon in the text (eg. "... in the * system tray ([icon])."). Add some clutter to the dialog. */ #if KDE_IS_VERSION( 3, 1, 90 ) // Don't do all the computations if they are unneeded: if ( ! KMessageBox::shouldBeShownContinue("hideOnCloseInfo") ) return; #endif // "Default parameter". Here, to avoid a i18n() call and dependancy in the .h if (fileMenu.isEmpty()) fileMenu = i18n("File"); // Some values we need: QPoint g = mapToGlobal(pos()); int desktopWidth = kapp->desktop()->width(); int desktopHeight = kapp->desktop()->height(); int tw = width(); int th = height(); // We are triying to make a live screenshot of the systray icon to circle it // and show it to the user. If no systray is used or if the icon is not visible, // we should not show that screenshot but only a text! // 1. Determine if the user use a system tray area or not: QByteArray screenstr; screenstr.setNum(qt_xscreen()); QByteArrray trayatom = "_NET_SYSTEM_TRAY_S" + screenstr; bool useSystray = (KSelectionWatcher(trayatom).owner() != 0L); // 2. And then if the icon is visible too (eg. this->show() has been called): useSystray = useSystray && isVisible(); // 3. Kicker (or another systray manager) can be visible but masked out of // the screen (ie. on right or on left of it). We check if the icon isn't // out of screen. if (useSystray) { QRect deskRect(0, 0, desktopWidth, desktopHeight); if ( !deskRect.contains(g.x(), g.y()) || !deskRect.contains(g.x() + tw, g.y() + th) ) useSystray = false; } // 4. We raise the window containing the systray icon (typically the kicker) to // have the most chances it is visible during the capture: /* if (useSystray) { // We are testing if one of the corners is hidden, and if yes, we would enter // a time consuming process (raise kicker and wait some time): // if (kapp->widgetAt(g) != this || // kapp->widgetAt(g + QPoint(tw-1, 0)) != this || // kapp->widgetAt(g + QPoint(0, th-1)) != this || // kapp->widgetAt(g + QPoint(tw-1, th-1)) != this) { int systrayManagerWinId = topLevelWidget()->winId(); KWindowSystem::forceActiveWindow(systrayManagerWinId); kapp->processEvents(); // Because without it the systrayManager is raised only after the messageBox is displayed // KWindowSystem::activateWindow(systrayManagerWinId); // kapp->processEvents(); // Because without it the systrayManager is raised only after the messageBox is displayed // KWindowSystem::raiseWindow(systrayManagerWinId); // kapp->processEvents(); // Because without it the systrayManager is raised only after the messageBox is displayed sleep(1); // TODO: Re-verify that at least one corner is now visible // } }*/ // KMessageBox::information(this, QString::number(g.x()) + ":" + QString::number(g.y()) + ":" + // QString::number((int)(kapp->widgetAt(g+QPoint(1,1))))); QString message = i18n( "<p>Closing the main window will keep %1 running in the system tray. " "Use <b>Quit</b> from the <b>Basket</b> menu to quit the application.</p>" ,KGlobal::instance()->aboutData()->programName()); // We are sure the systray icon is visible: ouf! if (useSystray) { // Compute size and position of the pixmap to be grabbed: int w = desktopWidth / 4; int h = desktopHeight / 9; int x = g.x() + tw/2 - w/2; // Center the rectange in the systray icon int y = g.y() + th/2 - h/2; if (x < 0) x = 0; // Move the rectangle to stay in the desktop limits if (y < 0) y = 0; if (x + w > desktopWidth) x = desktopWidth - w; if (y + h > desktopHeight) y = desktopHeight - h; // Grab the desktop and draw a circle arround the icon: QPixmap shot = QPixmap::grabWindow(QX11Info::appRootWindow(), x, y, w, h); QPainter painter(&shot); const int CIRCLE_MARGINS = 6; const int CIRCLE_WIDTH = 3; const int SHADOW_OFFSET = 1; const int IMAGE_BORDER = 1; int ax = g.x() - x - CIRCLE_MARGINS - 1; int ay = g.y() - y - CIRCLE_MARGINS - 1; painter.setPen( QPen(KApplication::palette().active().dark(), CIRCLE_WIDTH) ); painter.drawArc(ax + SHADOW_OFFSET, ay + SHADOW_OFFSET, tw + 2*CIRCLE_MARGINS, th + 2*CIRCLE_MARGINS, 0, 16*360); painter.setPen( QPen(Qt::red/*KApplication::palette().active().highlight()*/, CIRCLE_WIDTH) ); painter.drawArc(ax, ay, tw + 2*CIRCLE_MARGINS, th + 2*CIRCLE_MARGINS, 0, 16*360); #if 1 // Draw the pixmap over the screenshot in case a window hide the icon: painter.drawPixmap(g.x() - x, g.y() - y + 1, *pixmap()); #endif painter.end(); // Then, we add a border arround the image to make it more visible: QPixmap finalShot(w + 2*IMAGE_BORDER, h + 2*IMAGE_BORDER); finalShot.fill(KApplication::palette().active().foreground()); painter.begin(&finalShot); painter.drawPixmap(IMAGE_BORDER, IMAGE_BORDER, shot); painter.end(); // Associate source to image and show the dialog: QResource::registerResource(finalShot, "systray_shot"); KMessageBox::information(kapp->activeWindow(), message + "<p><center><img source=\":/systray_shot\"></center></p>", i18n("Docking in System Tray"), "hideOnCloseInfo"); QResource::unregisterResource(finalShot, "systray_shot"); } else { KMessageBox::information(kapp->activeWindow(), message, i18n("Docking in System Tray"), "hideOnCloseInfo"); } }