void WindowList::showMenu(bool onlyCurrentDesktop) { QList<WId> windows = KWindowSystem::windows(); QList<QAction*> actionList; QList< QList<QAction*> > windowList; int amount = 0; int number = 0; qDeleteAll(m_listMenu->actions()); //m_listMenu->clear(); if (!onlyCurrentDesktop) { m_listMenu->addTitle(i18n("Actions")); QAction *unclutterAction = m_listMenu->addAction(i18n("Unclutter Windows")); QAction *cascadeAction = m_listMenu->addAction(i18n("Cascade Windows")); connect(unclutterAction, SIGNAL(triggered()), m_listMenu, SLOT(slotUnclutterWindows())); connect(cascadeAction, SIGNAL(triggered()), m_listMenu, SLOT(slotCascadeWindows())); } for (int i = 0; i <= KWindowSystem::numberOfDesktops(); ++i) { windowList.append(QList<QAction*>()); } for (int i = 0; i < windows.count(); ++i) { KWindowInfo window = KWindowSystem::windowInfo(windows.at(i), (NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState | NET::WMVisibleName)); NET::WindowType type = window.windowType(NET::NormalMask | NET::DialogMask | NET::OverrideMask | NET::UtilityMask | NET::DesktopMask | NET::DockMask | NET::TopMenuMask | NET::SplashMask | NET::ToolbarMask | NET::MenuMask); if ((onlyCurrentDesktop && !window.isOnDesktop(KWindowSystem::currentDesktop())) || type == NET::Desktop || type == NET::Dock || type == NET::TopMenu || type == NET::Splash || type == NET::Menu || type == NET::Toolbar || window.hasState(NET::SkipPager)) { windows.removeAt(i); --i; continue; } ++amount; QAction *action = new QAction(QIcon(KWindowSystem::icon(windows.at(i))), window.visibleName(), this); action->setData((unsigned long long) windows.at(i)); QString window_title = QString(action->text()); window_title.truncate(55); action->setText(window_title); QFont font = QFont(action->font()); if (window.isMinimized()) { font.setItalic(true); } else if (KWindowSystem::activeWindow() == windows.at(i)) { font.setUnderline(true); font.setBold(true); } action->setFont(font); number = ((onlyCurrentDesktop || window.onAllDesktops()) ? 0 : window.desktop()); QList<QAction*> subList = windowList.value(number); subList.append(action); windowList.replace(number, subList); } const bool useSubMenus = (!onlyCurrentDesktop && KWindowSystem::numberOfDesktops() > 1 && (amount / KWindowSystem::numberOfDesktops()) > 5); if (amount && useSubMenus) { m_listMenu->addTitle(i18n("Desktops")); } for (int i = 0; i <= KWindowSystem::numberOfDesktops(); ++i) { if (windowList.value(i).isEmpty()) { continue; } KMenu *subMenu = NULL; QAction *subMenuAction = NULL; QString title = (i ? KWindowSystem::desktopName(i) : (onlyCurrentDesktop ? i18n("Current desktop") : i18n("On all desktops"))); if (useSubMenus) { subMenuAction = m_listMenu->addAction(title); subMenu = new KMenu(m_listMenu); subMenu->installEventFilter(this); } else { m_listMenu->addTitle(title); } for (int j = 0; j < windowList.value(i).count(); ++j) { if (useSubMenus) { subMenu->addAction(windowList.value(i).value(j)); } else { m_listMenu->addAction(windowList.value(i).value(j)); } } if (useSubMenus) { subMenuAction->setMenu(subMenu); } } if (!amount) { qDeleteAll(m_listMenu->actions()); m_listMenu->clear(); QAction *noWindows = m_listMenu->addAction(i18n("No windows")); noWindows->setEnabled(false); } if (formFactor() == Plasma::Vertical || formFactor() == Plasma::Horizontal) { m_listMenu->popup(popupPosition(m_listMenu->sizeHint())); } else { m_listMenu->popup(QCursor::pos()); } }
void KWindowListMenu::init() { int i, d; i = 0; int nd = twin_module->numberOfDesktops(); int cd = twin_module->currentDesktop(); WId active_window = twin_module->activeWindow(); // Make sure the popup is not too wide, otherwise clicking in the middle of kdesktop // wouldn't leave any place for the popup, and release would activate some menu entry. int maxwidth = kapp->desktop()->screenGeometry( this ).width() / 2 - 100; clear(); map.clear(); int unclutter = insertItem( i18n("Unclutter Windows"), this, TQT_SLOT( slotUnclutterWindows() ) ); int cascade = insertItem( i18n("Cascade Windows"), this, TQT_SLOT( slotCascadeWindows() ) ); // if we only have one desktop we won't be showing titles, so put a separator in if (nd == 1) { insertSeparator(); } TQValueList<KWin::WindowInfo> windows; for (TQValueList<WId>::ConstIterator it = twin_module->windows().begin(); it != twin_module->windows().end(); ++it) { windows.append( KWin::windowInfo( *it, NET::WMDesktop )); } bool show_all_desktops_group = ( nd > 1 ); for (d = 1; d <= nd + (show_all_desktops_group ? 1 : 0); d++) { bool on_all_desktops = ( d > nd ); int items = 0; if (!active_window && d == cd) setItemChecked(1000 + d, true); NameSortedInfoList list; list.setAutoDelete(true); for (TQValueList<KWin::WindowInfo>::ConstIterator it = windows.begin(); it != windows.end(); ++it) { if (((*it).desktop() == d) || (on_all_desktops && (*it).onAllDesktops()) || (!show_all_desktops_group && (*it).onAllDesktops())) { list.inSort(new KWin::WindowInfo( (*it).win(), NET::WMVisibleName | NET::WMState | NET::XAWMState | NET::WMWindowType, NET::WM2GroupLeader | NET::WM2TransientFor )); } } for (KWin::WindowInfo* info = list.first(); info; info = list.next(), ++i) { TQString itemText = KStringHandler::cPixelSqueeze(info->visibleNameWithState(), fontMetrics(), maxwidth); NET::WindowType windowType = info->windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask ); if ( (windowType == NET::Normal || windowType == NET::Unknown || (windowType == NET::Dialog && standaloneDialog( info, list ))) && !(info->state() & NET::SkipTaskbar) ) { TQPixmap pm = KWin::icon(info->win(), 16, 16, true ); items++; // ok, we have items on this desktop, let's show the title if ( items == 1 && nd > 1 ) { if( !on_all_desktops ) insertTitle(twin_module->desktopName( d ), 1000 + d); else insertTitle(i18n("On All Desktops"), 2000 ); } // Avoid creating unwanted accelerators. itemText.replace('&', TQString::fromLatin1("&&")); insertItem( pm, itemText, i); map.insert(i, info->win()); if (info->win() == active_window) setItemChecked(i, true); } } if (d == cd) { setItemEnabled(unclutter, items > 0); setItemEnabled(cascade, items > 0); } } // no windows? if (i == 0) { if (nd > 1) { // because we don't have any titles, nor a separator insertSeparator(); } setItemEnabled(insertItem(i18n("No Windows")), false); } }