From 4aed2c8219774f5d797760606b8489a92ddc5163 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kicker/applets/minipager/Makefile.am | 25 + kicker/applets/minipager/minipagerapplet.desktop | 122 +++ kicker/applets/minipager/pagerapplet.cpp | 906 +++++++++++++++++++++++ kicker/applets/minipager/pagerapplet.h | 138 ++++ kicker/applets/minipager/pagerbutton.cpp | 824 +++++++++++++++++++++ kicker/applets/minipager/pagerbutton.h | 111 +++ kicker/applets/minipager/pagersettings.kcfg | 58 ++ kicker/applets/minipager/pagersettings.kcfgc | 4 + 8 files changed, 2188 insertions(+) create mode 100644 kicker/applets/minipager/Makefile.am create mode 100644 kicker/applets/minipager/minipagerapplet.desktop create mode 100644 kicker/applets/minipager/pagerapplet.cpp create mode 100644 kicker/applets/minipager/pagerapplet.h create mode 100644 kicker/applets/minipager/pagerbutton.cpp create mode 100644 kicker/applets/minipager/pagerbutton.h create mode 100644 kicker/applets/minipager/pagersettings.kcfg create mode 100644 kicker/applets/minipager/pagersettings.kcfgc (limited to 'kicker/applets/minipager') diff --git a/kicker/applets/minipager/Makefile.am b/kicker/applets/minipager/Makefile.am new file mode 100644 index 000000000..da149f468 --- /dev/null +++ b/kicker/applets/minipager/Makefile.am @@ -0,0 +1,25 @@ +INCLUDES = $(all_includes) -I$(srcdir)/../../taskmanager \ + -I$(srcdir)/../../libkicker -I../../libkicker + +kde_module_LTLIBRARIES = minipager_panelapplet.la + +minipager_panelapplet_la_SOURCES = pagerapplet.cpp pagerbutton.cpp pagersettings.kcfgc + +minipager_panelapplet_la_METASOURCES = AUTO +noinst_HEADERS = pagerapplet.h pagerbutton.h + +lnkdir = $(kde_datadir)/kicker/applets +lnk_DATA = minipagerapplet.desktop + +EXTRA_DIST = $(lnk_DATA) + +minipager_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +minipager_panelapplet_la_LIBADD = $(LIB_KDEUI) \ + ../../taskmanager/libtaskmanager.la \ + ../../libkicker/libkickermain.la + +messages: rc.cpp + $(XGETTEXT) *.cpp *.h -o $(podir)/kminipagerapplet.pot + +srcdoc: + kdoc -a -p -H -d $$HOME/web/src/kminipagerapplet kminipagerapplet *.h -lqt -lkdecore -lkdeui -lkfile diff --git a/kicker/applets/minipager/minipagerapplet.desktop b/kicker/applets/minipager/minipagerapplet.desktop new file mode 100644 index 000000000..df5dcfb03 --- /dev/null +++ b/kicker/applets/minipager/minipagerapplet.desktop @@ -0,0 +1,122 @@ +[Desktop Entry] +Type=Plugin +Name=Desktop Preview & Pager +Name[af]=Werkskerm Voorskou & Boodskapper +Name[be]=Прагляд працоўных сталоў і пэйджар +Name[bg]=Изглед на екрана и пейджър +Name[bn]=ডেস্কটপ প্রাকদর্শন এবং পেজার +Name[bs]=Pregled i promjena radnih površina +Name[ca]=Vista prèvia d'escriptori i paginador +Name[cs]=Přepínač a náhled ploch +Name[csb]=Przestôwnik ë przezérnik pùltów +Name[da]=Desktop-forhåndsviser & -pager +Name[de]=Umschalten zwischen Arbeitsflächen +Name[el]=Προεπισκόπηση και αλλαγή επιφάνειας εργασίας +Name[eo]=Tabula antaŭrigardilo kaj paĝilo +Name[es]=Paginador y previsualizador del escritorio +Name[et]=Töölaudade eelvaatlus ja vahetaja +Name[eu]=Mahaigain aurrebista eta orrialdekatzailea +Name[fa]=پیش‌نمایش و پی‌جوی رومیزی +Name[fi]=Työpöydän esikatselu ja sivutus +Name[fr]=Gestionnaire et aperçu des bureaux +Name[fy]=Buroblêdfoarbyld en Pager +Name[gl]=Antevisor e Paxinador do Escritório +Name[hr]=Pager i preglednik radne površine +Name[hu]=Asztali előnézet és lapozó +Name[is]=Skjáborðs forskoðari & flettir +Name[it]=Anteprime e gestione dei desktop +Name[ja]=デスクトッププレビューとページャ +Name[ka]=სამუშაო დაფისა და გვერდების ჩვენება +Name[kk]=Үстелдер ақтарғышы +Name[km]=ការ​មើលផ្ទៃតុ​ជាមុន និង​ភេកយ័រ +Name[lt]=Darbastalių peržiūrėjimo ir puslapiavimo priemonė +Name[mk]=Преглед и пејџер на раб. површина +Name[nb]=Forhåndsvising og bytte av skrivebord +Name[nds]=Schriefdisch-Ümschalter & Vöransicht +Name[ne]=डेस्कटप पूर्वावलोकन र पेजर +Name[nl]=Bureaubladvoorbeeld en pager +Name[nn]=Førehandsvising og byte av skrivebord +Name[pa]=ਵੇਹੜਾ ਝਲਕ ਅਤੇ ਪੇਜ਼ਰ +Name[pl]=Przełącznik i przeglądarka pulpitów +Name[pt]=Antevisão e Paginador do Ecrã +Name[pt_BR]=Pager & Pré-visualizador de Área de Trabalho +Name[ro]=Paginator și previzualizor pentru desktop +Name[ru]=Переключатель рабочих столов +Name[se]=Čállinbevddiid ovdačájeheaddji ja molssodeaddji +Name[sk]=Náhľad a stránkovač pracovnej plochy +Name[sl]=Ogledovalnik in pozivnik namizja +Name[sr]=Прегледач и пејџер радних површина +Name[sr@Latn]=Pregledač i pejdžer radnih površina +Name[sv]=Förhandsgranskning och hantering av skrivbord +Name[te]=రంగస్థల ముందు వీక్షణం & పెజర్ +Name[th]=แสดงตัวอย่างและเปลี่ยนพื้นที่ทำงาน +Name[tr]=Masaüstü Önizleyici ve Sayfalayıcı +Name[uk]=Перегляд стільниці і пейджер +Name[uz]=Ish stolining peyjeri +Name[uz@cyrillic]=Иш столининг пейжери +Name[vi]=Xem thử Màn hình nền & Chuyển đổi +Name[wa]=Préveyeu et pådjeu do scribanne +Name[zh_CN]=桌面预览器和页面切换器 +Name[zh_TW]=桌面預覽與縮圖 + +Comment=Preview, manage and switch to multiple virtual desktops +Comment[af]=Voorskou van, bestuur van en wissel tussen veelvuldige virtuelewerkskerms +Comment[ar]=عايين، دبِر و بدل إلى أسطح المكتب الوهمية المتعددة +Comment[be]=Прагляд, кіраванне і пераключэнне між некалькімі віртуальнымі працоўнымі сталамі +Comment[bg]=Преглед, управление и превключване към виртуалните работни плотове +Comment[bs]=Pregledajte, upravljajte i mijenjajte radne površine +Comment[ca]=Vista prèvia, gestió i canvi entre diversos escriptoris virtuals +Comment[cs]=Správa, náhled a přepínání virtuálních pracovních ploch +Comment[csb]=Pòdzérk, sprôwianié ë przestôwianié wirtualnëch pùltów +Comment[da]=Forhåndsvis, håndtér og skift mellem flere virtuelle desktoppe +Comment[de]=Vorschau und Verwaltung der virtuellen Arbeitsflächen. +Comment[el]=Προεπισκόπηση, διαχείριση και εναλλαγή σε πολλαπλές εικονικές επιφάνειες εργασίας +Comment[eo]=Antaŭrigardi, mastrumi kaj komuti al pluraj virtualaj labortabloj +Comment[es]=Previsualizar, gestionar y cambiar a múltiples escritorios virtuales +Comment[et]=Virtuaalsete töölaudade eelvaatlus, haldus ja vahetamine +Comment[eu]=Aurrebista, kudeatu eta aldatu mahaigain birtual anitzez +Comment[fa]=پیش‌نمایش، مدیریت و سودهی به رومیزیهای مجازی چندگانه +Comment[fi]=Esikatsele, hallitse ja vaihda virtuaalisia työpöytiä +Comment[fr]=Affichage, gestion et changement des bureaux virtuels multiples +Comment[fy]=Foarbyld, beheare en skeakel nei meardere firtuele buroblêden +Comment[gl]=Xestione, cambie e antevexa múltiplos escritórios virtuais +Comment[he]=תצוגה מקדימה, והעברה של שולחנות עבודה וירטואלים +Comment[hr]=Pregled, upravljanje i prebacivanje između višestrukih virtualnih radnih površina +Comment[hu]=A virtuális asztalok előnézete, kezelése, használata +Comment[is]=Forskoðaðu, stjórnaðu og flettu á milli marga sýndarskjáborða +Comment[it]=Gestisce, cambia e mostra le anteprime dei desktop virtuali multipli +Comment[ja]=複数の仮想デスクトップのプレビュー、管理と切り替え +Comment[kk]=Көп қиртуалды үстелдерді қарау, басқару және олаға ауысу +Comment[km]=ការ​មើល​ជាមុន, គ្រប់គ្រង និង​ប្តូរ​ទៅពហុផ្ទៃតុ​និម្មិត​ +Comment[lt]=Peržiūrėkite, tvarkykite ir lengvai vaikščiokite tarp daugelio menamų darbastalių +Comment[mk]=Преглед, управување и префрлање на повеќе виртуелни работни површини +Comment[nb]=Forhåndsvisning, håndtere og bytte til virtuelle skrivebord +Comment[nds]=Vöransicht un Pleeg vun virtuelle Schriefdischen +Comment[ne]=पूर्वावलोकन अनि प्रबन्ध गर्नुहोस् र अवास्तविक डेस्कटपमा स्विच गर्नुहोस् +Comment[nl]=Vooruitblik, beheer en schakel naar meerdere virtuele bureaubladen +Comment[nn]=Førehandsvis, handter og byt til virtuelle skrivebord +Comment[pa]=ਕਈ ਫ਼ਰਜ਼ੀ ਵੇਹੜਿਆਂ ਦੀ ਝਲਕ ਵੇਖਣ, ਉਹਨਾਂ ਦੇ ਪਰਬੰਧ ਅਤੇ ਤਬਦੀਲ ਕਰਨ ਲਈ ਹੈ +Comment[pl]=Podgląd, zarządzanie i przełączanie wirtualnych pulpitów +Comment[pt]=Antever, gerir e mudar para vários ecrãs virtuais +Comment[pt_BR]=Fornece uma pré-visualização, gerencia e alterna entre múltiplos ambientes de trabalho virtuais +Comment[ro]=Previzualizează, gestionează și schimbă desktop-uri virtuale +Comment[ru]=Переключение между виртуальными рабочими столами с возможностью показа их содержимого +Comment[sk]=Náhľad, nastavenie a prepínanie viacerých virtuálnych pracovných plôch +Comment[sl]=Predogled, upravljanje in preklapljanje za več navideznih namizij +Comment[sr]=Прегледајте, управљајте, и пребацујте се између радних површина +Comment[sr@Latn]=Pregledajte, upravljajte, i prebacujte se između radnih površina +Comment[sv]=Förhandsgranska, hantera och byt mellan flera virtuella skrivbord +Comment[te]=ముందు వీక్షణ, ఎక్కువ మిధ్యా రంగస్థలాల నియంత్రణ మరయు మార్పు +Comment[th]=ดูตัวอย่าง, จัดการและเปลี่ยนไปใช้พื้นที่ทำงานเสมือนอื่นๆ +Comment[uk]=Перегляд, керування та перемикання на багато віртуальних стільниць +Comment[uz]=Virtual ish stollarini koʻrib chiqish, boshqarish va ularga oʻtish uchun qulay vosita +Comment[uz@cyrillic]=Виртуал иш столларини кўриб чиқиш, бошқариш ва уларга ўтиш учун қулай восита +Comment[vi]=Xem thử, quản lý và chuyển đổi giữa các màn hình nền ảo +Comment[wa]=Prévey, manaedjî et candjî viè sacwants forveyous scribannes +Comment[zh_CN]=预览、管理及切换多个虚拟桌面 +Comment[zh_TW]=預覽、管理並切換到多個虛擬桌面 + +Icon=kpager + +X-KDE-Library=minipager_panelapplet +X-KDE-UniqueApplet=false diff --git a/kicker/applets/minipager/pagerapplet.cpp b/kicker/applets/minipager/pagerapplet.cpp new file mode 100644 index 000000000..3ba87c0b1 --- /dev/null +++ b/kicker/applets/minipager/pagerapplet.cpp @@ -0,0 +1,906 @@ +/***************************************************************** + +Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "kickertip.h" +#include "kickerSettings.h" +#include "kshadowengine.h" +#include "kshadowsettings.h" +#include "paneldrag.h" +#include "taskmanager.h" + +#include "pagerapplet.h" +#include "pagerapplet.moc" + +#ifdef FocusOut +#undef FocusOut +#endif + +const int knDesktopPreviewSize = 12; +const int knBtnSpacing = 1; + +// The previews tend to have a 4/3 aspect ratio +static const int smallHeight = 32; +static const int smallWidth = 42; + +// config menu id offsets +static const int rowOffset = 2000; +static const int labelOffset = 200; +static const int bgOffset = 300; + +extern "C" +{ + KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("kminipagerapplet"); + return new KMiniPager(configFile, KPanelApplet::Normal, 0, parent, "kminipagerapplet"); + } +} + +KMiniPager::KMiniPager(const QString& configFile, Type type, int actions, + QWidget *parent, const char *name) + : KPanelApplet( configFile, type, actions, parent, name ), + m_layout(0), + m_desktopLayoutOwner( NULL ), + m_shadowEngine(0), + m_contextMenu(0), + m_settings( new PagerSettings(sharedConfig()) ) +{ + setBackgroundOrigin( AncestorOrigin ); + int scnum = QApplication::desktop()->screenNumber(this); + QRect desk = QApplication::desktop()->screenGeometry(scnum); + if (desk.width() <= 800) + { + KConfigSkeleton::ItemBool* item = dynamic_cast(m_settings->findItem("Preview")); + if (item) + { + item->setDefaultValue(false); + } + } + m_settings->readConfig(); + m_windows.setAutoDelete(true); + if (m_settings->preview()) + { + TaskManager::the()->trackGeometry(); + } + + m_group = new QButtonGroup(this); + m_group->setBackgroundOrigin(AncestorOrigin); + m_group->setFrameStyle(QFrame::NoFrame); + m_group->setExclusive( true ); + + setFont( KGlobalSettings::taskbarFont() ); + + m_kwin = new KWinModule(this); + m_activeWindow = m_kwin->activeWindow(); + m_curDesk = m_kwin->currentDesktop(); + + if (m_curDesk == 0) // kwin not yet launched + { + m_curDesk = 1; + } + + desktopLayoutOrientation = Qt::Horizontal; + desktopLayoutX = -1; + desktopLayoutY = -1; + + QSize s(m_kwin->numberOfViewports(m_kwin->currentDesktop())); + m_useViewports = s.width() * s.height() > 1; + + drawButtons(); + + connect( m_kwin, SIGNAL( currentDesktopChanged(int)), SLOT( slotSetDesktop(int) ) ); + connect( m_kwin, SIGNAL( currentDesktopViewportChanged(int, const QPoint&)), + SLOT(slotSetDesktopViewport(int, const QPoint&))); + connect( m_kwin, SIGNAL( numberOfDesktopsChanged(int)), SLOT( slotSetDesktopCount(int) ) ); + connect( m_kwin, SIGNAL( activeWindowChanged(WId)), SLOT( slotActiveWindowChanged(WId) ) ); + connect( m_kwin, SIGNAL( windowAdded(WId) ), this, SLOT( slotWindowAdded(WId) ) ); + connect( m_kwin, SIGNAL( windowRemoved(WId) ), this, SLOT( slotWindowRemoved(WId) ) ); + connect( m_kwin, SIGNAL( windowChanged(WId,unsigned int) ), this, SLOT( slotWindowChanged(WId,unsigned int) ) ); + connect( m_kwin, SIGNAL( desktopNamesChanged() ), this, SLOT( slotDesktopNamesChanged() ) ); + connect( kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int)) ); + + if (kapp->authorizeKAction("kicker_rmb") && kapp->authorizeControlModule("kde-kcmtaskbar.desktop")) + { + m_contextMenu = new QPopupMenu(); + connect(m_contextMenu, SIGNAL(aboutToShow()), SLOT(aboutToShowContextMenu())); + connect(m_contextMenu, SIGNAL(activated(int)), SLOT(contextMenuActivated(int))); + setCustomMenu(m_contextMenu); + } + + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_kwin->windows().end(); + for ( it = m_kwin->windows().begin(); it != itEnd; ++it) + { + slotWindowAdded( (*it) ); + } + + slotSetDesktop( m_curDesk ); + updateLayout(); +} + +KMiniPager::~KMiniPager() +{ + KGlobal::locale()->removeCatalogue("kminipagerapplet"); + delete m_contextMenu; + delete m_settings; + delete m_shadowEngine; +} + +void KMiniPager::slotBackgroundChanged(int desk) +{ + unsigned numDesktops = m_kwin->numberOfDesktops(); + if (numDesktops != m_desktops.count()) + { + slotSetDesktopCount(numDesktops); + } + + if (desk < 1 || (unsigned) desk > m_desktops.count()) + { + // should not happen, but better to be paranoid than crash + return; + } + + m_desktops[desk - 1]->backgroundChanged(); +} + +void KMiniPager::slotSetDesktop(int desktop) +{ + if (m_kwin->numberOfDesktops() > static_cast(m_desktops.count())) + { + slotSetDesktopCount( m_kwin->numberOfDesktops() ); + } + + if (!m_useViewports && (desktop != KWin::currentDesktop())) + { + // this can happen when the user clicks on a desktop, + // holds down the key combo to switch desktops, lets the + // mouse go but keeps the key combo held. the desktop will switch + // back to the desktop associated with the key combo and then it + // becomes a race condition between kwin's signal and the button's + // signal. usually kwin wins. + return; + } + + m_curDesk = desktop; + if (m_curDesk < 1) + { + m_curDesk = 1; + } + + KMiniPagerButton* button = m_desktops[m_curDesk - 1]; + if (!button->isOn()) + { + button->toggle(); + } +} + +void KMiniPager::slotSetDesktopViewport(int desktop, const QPoint& viewport) +{ + // ### + Q_UNUSED(desktop); + QSize s(m_kwin->numberOfViewports(m_kwin->currentDesktop())); + slotSetDesktop((viewport.y()-1) * s.width() + viewport.x() ); +} + +void KMiniPager::slotButtonSelected( int desk ) +{ + if (m_kwin->numberOfViewports(m_kwin->currentDesktop()).width() * + m_kwin->numberOfViewports(m_kwin->currentDesktop()).height() > 1) + { + QPoint p; + + p.setX( (desk-1) * QApplication::desktop()->width()); + p.setY( 0 ); + + KWin::setCurrentDesktopViewport(m_kwin->currentDesktop(), p); + } + else + KWin::setCurrentDesktop( desk ); + + slotSetDesktop( desk ); +} + +int KMiniPager::widthForHeight(int h) const +{ + if (orientation() == Qt::Vertical) + { + return width(); + } + + int deskNum = m_kwin->numberOfDesktops() * m_kwin->numberOfViewports(0).width() + * m_kwin->numberOfViewports(0).height(); + + int rowNum = m_settings->numberOfRows(); + if (rowNum == 0) + { + if (h <= 32 || deskNum <= 1) + { + rowNum = 1; + } + else + { + rowNum = 2; + } + } + + int deskCols = deskNum/rowNum; + if(deskNum == 0 || deskNum % rowNum != 0) + deskCols += 1; + + int bw = (h / rowNum); + if( m_settings->labelType() != PagerSettings::EnumLabelType::LabelName ) + { + if (desktopPreview() || m_settings->backgroundType() == PagerSettings::EnumBackgroundType::BgLive) + { + bw = (int) ( bw * (double) QApplication::desktop()->width() / QApplication::desktop()->height() ); + } + } + else + { + // scale to desktop width as a minimum + bw = (int) (bw * (double) QApplication::desktop()->width() / QApplication::desktop()->height()); + QFontMetrics fm = fontMetrics(); + for (int i = 1; i <= deskNum; i++) + { + int sw = fm.width( m_kwin->desktopName( i ) ) + 8; + if (sw > bw) + { + bw = sw; + } + } + } + + // we add one to the width for the spacing in between the buttons + // however, the last button doesn't have a space on the end of it (it's + // only _between_ buttons) so we then remove that one pixel + return (deskCols * (bw + 1)) - 1; +} + +int KMiniPager::heightForWidth(int w) const +{ + if (orientation() == Qt::Horizontal) + { + return height(); + } + + int deskNum = m_kwin->numberOfDesktops() * m_kwin->numberOfViewports(0).width() + * m_kwin->numberOfViewports(0).height(); + int rowNum = m_settings->numberOfRows(); // actually these are columns now... oh well. + if (rowNum == 0) + { + if (w <= 48 || deskNum == 1) + { + rowNum = 1; + } + else + { + rowNum = 2; + } + } + + int deskCols = deskNum/rowNum; + if(deskNum == 0 || deskNum % rowNum != 0) + { + deskCols += 1; + } + + int bh = (w/rowNum) + 1; + if ( desktopPreview() ) + { + bh = (int) ( bh * (double) QApplication::desktop()->height() / QApplication::desktop()->width() ); + } + else if ( m_settings->labelType() == PagerSettings::EnumLabelType::LabelName ) + { + bh = fontMetrics().lineSpacing() + 8; + } + + // we add one to the width for the spacing in between the buttons + // however, the last button doesn't have a space on the end of it (it's + // only _between_ buttons) so we then remove that one pixel + int nHg = (deskCols * (bh + 1)) - 1; + + return nHg; +} + +void KMiniPager::updateDesktopLayout(int o, int x, int y) +{ + if ((desktopLayoutOrientation == o) && + (desktopLayoutX == x) && + (desktopLayoutY == y)) + { + return; + } + + desktopLayoutOrientation = o; + desktopLayoutX = x; + desktopLayoutY = y; + if( x == -1 ) // do-the-maths-yourself is encoded as 0 in the wm spec + x = 0; + if( y == -1 ) + y = 0; + if( m_desktopLayoutOwner == NULL ) + { // must own manager selection before setting global desktop layout + int screen = DefaultScreen( qt_xdisplay()); + m_desktopLayoutOwner = new KSelectionOwner( QString( "_NET_DESKTOP_LAYOUT_S%1" ).arg( screen ).latin1(), + screen, this ); + if( !m_desktopLayoutOwner->claim( false )) + { + delete m_desktopLayoutOwner; + m_desktopLayoutOwner = NULL; + return; + } + } + NET::Orientation orient = o == Qt::Horizontal ? NET::OrientationHorizontal : NET::OrientationVertical; + NETRootInfo i( qt_xdisplay(), 0 ); + i.setDesktopLayout( orient, x, y, NET::DesktopLayoutCornerTopLeft ); +} + +void KMiniPager::resizeEvent(QResizeEvent*) +{ + bool horiz = orientation() == Horizontal; + + int deskNum = m_desktops.count(); + int rowNum = m_settings->numberOfRows(); + if (rowNum == 0) + { + if (((horiz && height()<=32)||(!horiz && width()<=48)) || deskNum <= 1) + rowNum = 1; + else + rowNum = 2; + } + + int deskCols = deskNum/rowNum; + if(deskNum == 0 || deskNum % rowNum != 0) + deskCols += 1; + + if (m_layout) + { + delete m_layout; + m_layout = 0; + } + + int nDX, nDY; + if (horiz) + { + nDX = rowNum; + nDY = deskCols; + updateDesktopLayout(Qt::Horizontal, -1, nDX); + } + else + { + nDX = deskCols; + nDY = rowNum; + updateDesktopLayout(Qt::Horizontal, nDY, -1); + } + + // 1 pixel spacing. + m_layout = new QGridLayout(this, nDX, nDY, 0, 1); + + QValueList::Iterator it = m_desktops.begin(); + QValueList::Iterator itEnd = m_desktops.end(); + int c = 0, + r = 0; + while( it != itEnd ) { + c = 0; + while( (it != itEnd) && (c < nDY) ) { + m_layout->addWidget( *it, r, c ); + ++it; + ++c; + } + ++r; + } + + m_layout->activate(); + updateGeometry(); +} + +void KMiniPager::wheelEvent( QWheelEvent* e ) +{ + int newDesk; + int desktops = KWin::numberOfDesktops(); + if (m_kwin->numberOfViewports(0).width() * m_kwin->numberOfViewports(0).height() > 1 ) + desktops = m_kwin->numberOfViewports(0).width() * m_kwin->numberOfViewports(0).height(); + if (e->delta() < 0) + { + newDesk = m_curDesk % desktops + 1; + } + else + { + newDesk = (desktops + m_curDesk - 2) % desktops + 1; + } + + slotButtonSelected(newDesk); +} + +void KMiniPager::drawButtons() +{ + int deskNum = m_kwin->numberOfDesktops(); + KMiniPagerButton *desk; + + int count = 1; + int i = 1; + do + { + QSize viewportNum = m_kwin->numberOfViewports(i); + for (int j = 1; j <= viewportNum.width() * viewportNum.height(); ++j) + { + QSize s(m_kwin->numberOfViewports(m_kwin->currentDesktop())); + QPoint viewport( (j-1) % s.width(), (j-1) / s.width()); + desk = new KMiniPagerButton( count, m_useViewports, viewport, this ); + if ( m_settings->labelType() != PagerSettings::EnumLabelType::LabelName ) + { + QToolTip::add( desk, desk->desktopName() ); + } + + m_desktops.append( desk ); + m_group->insert( desk, count ); + + connect(desk, SIGNAL(buttonSelected(int)), + SLOT(slotButtonSelected(int)) ); + connect(desk, SIGNAL(showMenu(const QPoint&, int )), + SLOT(slotShowMenu(const QPoint&, int )) ); + + desk->show(); + ++count; + } + } + while ( ++i <= deskNum ); +} + +void KMiniPager::slotSetDesktopCount( int ) +{ + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + for( it = m_desktops.begin(); it != itEnd; ++it ) + { + delete (*it); + } + m_desktops.clear(); + + drawButtons(); + + m_curDesk = m_kwin->currentDesktop(); + if ( m_curDesk == 0 ) + { + m_curDesk = 1; + } + + resizeEvent(0); + updateLayout(); +} + +void KMiniPager::slotActiveWindowChanged( WId win ) +{ + if (desktopPreview()) + { + KWin::WindowInfo* inf1 = m_activeWindow ? info( m_activeWindow ) : NULL; + KWin::WindowInfo* inf2 = win ? info( win ) : NULL; + m_activeWindow = win; + + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + for ( it = m_desktops.begin(); it != itEnd; ++it) + { + if ( ( inf1 && (*it)->shouldPaintWindow(inf1)) || + ( inf2 && (*it)->shouldPaintWindow(inf2)) ) + { + (*it)->windowsChanged(); + } + } + } +} + +void KMiniPager::slotWindowAdded( WId win) +{ + if (desktopPreview()) + { + KWin::WindowInfo* inf = info( win ); + + if (inf->state() & NET::SkipPager) + { + return; + } + + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + for ( it = m_desktops.begin(); it != itEnd; ++it) + { + if ( (*it)->shouldPaintWindow(inf) ) + { + (*it)->windowsChanged(); + } + } + } +} + +void KMiniPager::slotWindowRemoved(WId win) +{ + if (desktopPreview()) + { + KWin::WindowInfo* inf = info(win); + bool onAllDesktops = inf->onAllDesktops(); + bool onAllViewports = inf->hasState(NET::Sticky); + bool skipPager = inf->state() & NET::SkipPager; + int desktop = inf->desktop(); + + if (win == m_activeWindow) + m_activeWindow = 0; + + m_windows.remove((long) win); + + if (skipPager) + { + return; + } + + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + for (it = m_desktops.begin(); it != itEnd; ++it) + { + if (onAllDesktops || onAllViewports || desktop == (*it)->desktop()) + { + (*it)->windowsChanged(); + } + } + } + else + { + m_windows.remove(win); + return; + } + +} + +void KMiniPager::slotWindowChanged( WId win , unsigned int properties ) +{ + if ((properties & (NET::WMState | NET::XAWMState | NET::WMDesktop)) == 0 && + (!desktopPreview() || (properties & NET::WMGeometry) == 0) && + !(desktopPreview() && windowIcons() && + (properties & NET::WMIcon | NET::WMIconName | NET::WMVisibleIconName) == 0)) + { + return; + } + + if (desktopPreview()) + { + KWin::WindowInfo* inf = m_windows[win]; + bool skipPager = inf->hasState(NET::SkipPager); + QMemArray old_shouldPaintWindow(m_desktops.size()); + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + int i = 0; + for ( it = m_desktops.begin(); it != itEnd; ++it) + { + old_shouldPaintWindow[i++] = (*it)->shouldPaintWindow(inf); + } + + m_windows.remove(win); + inf = info(win); + + if (inf->hasState(NET::SkipPager) || skipPager) + { + return; + } + + for ( i = 0, it = m_desktops.begin(); it != itEnd; ++it) + { + if ( old_shouldPaintWindow[i++] || (*it)->shouldPaintWindow(inf)) + { + (*it)->windowsChanged(); + } + } + } + else + { + m_windows.remove(win); + return; + } +} + +KWin::WindowInfo* KMiniPager::info( WId win ) +{ + if (!m_windows[win]) + { + KWin::WindowInfo* info = new KWin::WindowInfo( win, + NET::WMWindowType | NET::WMState | NET::XAWMState | NET::WMDesktop | NET::WMGeometry | NET::WMKDEFrameStrut, 0 ); + + m_windows.insert(win, info); + return info; + } + + return m_windows[win]; +} + +KTextShadowEngine* KMiniPager::shadowEngine() +{ + if (!m_shadowEngine) + m_shadowEngine = new KTextShadowEngine(); + + return m_shadowEngine; +} + +void KMiniPager::refresh() +{ + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + for ( it = m_desktops.begin(); it != itEnd; ++it) + { + (*it)->update(); + } +} + +void KMiniPager::aboutToShowContextMenu() +{ + m_contextMenu->clear(); + + m_contextMenu->insertItem(SmallIcon("kpager"), i18n("&Launch Pager"), LaunchExtPager); + m_contextMenu->insertSeparator(); + + m_contextMenu->insertItem(i18n("&Rename Desktop \"%1\"") + .arg(kwin()->desktopName(m_rmbDesk)), RenameDesktop); + m_contextMenu->insertSeparator(); + + KPopupMenu* showMenu = new KPopupMenu(m_contextMenu); + showMenu->setCheckable(true); + showMenu->insertTitle(i18n("Pager Layout")); + + QPopupMenu* rowMenu = new QPopupMenu(showMenu); + rowMenu->setCheckable(true); + rowMenu->insertItem(i18n("&Automatic"), 0 + rowOffset); + rowMenu->insertItem(i18n("one row or column", "&1"), 1 + rowOffset); + rowMenu->insertItem(i18n("two rows or columns", "&2"), 2 + rowOffset); + rowMenu->insertItem( i18n("three rows or columns", "&3"), 3 + rowOffset); + connect(rowMenu, SIGNAL(activated(int)), SLOT(contextMenuActivated(int))); + showMenu->insertItem((orientation()==Horizontal) ? i18n("&Rows"): + i18n("&Columns"), + rowMenu); + + showMenu->insertItem(i18n("&Window Thumbnails"), WindowThumbnails); + showMenu->insertItem(i18n("&Window Icons"), WindowIcons); + + showMenu->insertTitle(i18n("Text Label")); + showMenu->insertItem(i18n("Desktop N&umber"), + PagerSettings::EnumLabelType::LabelNumber + labelOffset); + showMenu->insertItem(i18n("Desktop N&ame"), + PagerSettings::EnumLabelType::LabelName + labelOffset); + showMenu->insertItem(i18n("N&o Label"), + PagerSettings::EnumLabelType::LabelNone + labelOffset); + + showMenu->insertTitle(i18n("Background")); + showMenu->insertItem(i18n("&Elegant"), + PagerSettings::EnumBackgroundType::BgPlain + bgOffset); + showMenu->insertItem(i18n("&Transparent"), + PagerSettings::EnumBackgroundType::BgTransparent + bgOffset); + showMenu->insertItem(i18n("&Desktop Wallpaper"), + PagerSettings::EnumBackgroundType::BgLive + bgOffset); + connect(showMenu, SIGNAL(activated(int)), SLOT(contextMenuActivated(int))); + m_contextMenu->insertItem(i18n("&Pager Options"),showMenu); + + m_contextMenu->insertItem(SmallIcon("configure"), + i18n("&Configure Desktops..."), + ConfigureDesktops); + + rowMenu->setItemChecked(m_settings->numberOfRows() + rowOffset, true); + m_contextMenu->setItemChecked(m_settings->labelType() + labelOffset, showMenu); + m_contextMenu->setItemChecked(m_settings->backgroundType() + bgOffset, showMenu); + + m_contextMenu->setItemChecked(WindowThumbnails, m_settings->preview()); + m_contextMenu->setItemChecked(WindowIcons, m_settings->icons()); + m_contextMenu->setItemEnabled(WindowIcons, m_settings->preview()); + m_contextMenu->setItemEnabled(RenameDesktop, + m_settings->labelType() == + PagerSettings::EnumLabelType::LabelName); +} + +void KMiniPager::slotShowMenu(const QPoint& pos, int desktop) +{ + if (!m_contextMenu) + { + return; + } + + m_rmbDesk = desktop; + m_contextMenu->exec(pos); + m_rmbDesk = -1; +} + +void KMiniPager::contextMenuActivated(int result) +{ + if (result < 1) + { + return; + } + + switch (result) + { + case LaunchExtPager: + showPager(); + return; + + case ConfigureDesktops: + kapp->startServiceByDesktopName("desktop"); + return; + + case RenameDesktop: + m_desktops[(m_rmbDesk == -1) ? m_curDesk - 1 : m_rmbDesk - 1]->rename(); + return; + } + + if (result >= rowOffset) + { + m_settings->setNumberOfRows(result - rowOffset); + resizeEvent(0); + } + + switch (result) + { + case WindowThumbnails: + m_settings->setPreview(!m_settings->preview()); + TaskManager::the()->trackGeometry(); + break; + + case WindowIcons: + m_settings->setIcons(!m_settings->icons()); + break; + + case PagerSettings::EnumBackgroundType::BgPlain + bgOffset: + m_settings->setBackgroundType(PagerSettings::EnumBackgroundType::BgPlain); + break; + case PagerSettings::EnumBackgroundType::BgTransparent + bgOffset: + m_settings->setBackgroundType(PagerSettings::EnumBackgroundType::BgTransparent); + break; + case PagerSettings::EnumBackgroundType::BgLive + bgOffset: + { + m_settings->setBackgroundType(PagerSettings::EnumBackgroundType::BgLive); + QValueList::ConstIterator it; + QValueList::ConstIterator itEnd = m_desktops.end(); + for( it = m_desktops.begin(); it != itEnd; ++it ) + { + (*it)->backgroundChanged(); + } + break; + } + + case PagerSettings::EnumLabelType::LabelNone + labelOffset: + m_settings->setLabelType(PagerSettings::EnumLabelType::LabelNone); + break; + case PagerSettings::EnumLabelType::LabelNumber + labelOffset: + m_settings->setLabelType(PagerSettings::EnumLabelType::LabelNumber); + break; + case PagerSettings::EnumLabelType::LabelName + labelOffset: + m_settings->setLabelType(PagerSettings::EnumLabelType::LabelName); + break; + } + + m_settings->writeConfig(); + updateGeometry(); + refresh(); +} + +void KMiniPager::slotDesktopNamesChanged() +{ + QValueList::ConstIterator it = m_desktops.begin(); + QValueList::ConstIterator itEnd = m_desktops.end(); + + for (int i = 1; it != itEnd; ++it, ++i) + { + QString name = m_kwin->desktopName(i); + (*it)->setDesktopName(name); + (*it)->repaint(); + QToolTip::remove((*it)); + QToolTip::add((*it), name); + } + + updateLayout(); +} + +void KMiniPager::showPager() +{ + DCOPClient *dcop=kapp->dcopClient(); + + if (dcop->isApplicationRegistered("kpager")) + { + showKPager(true); + } + else + { + // Let's run kpager if it isn't running + connect( dcop, SIGNAL( applicationRegistered(const QCString &) ), this, SLOT(applicationRegistered(const QCString &)) ); + dcop->setNotifications(true); + QString strAppPath(locate("exe", "kpager")); + if (!strAppPath.isEmpty()) + { + KProcess process; + process << strAppPath; + process << "--hidden"; + process.start(KProcess::DontCare); + } + } +} + +void KMiniPager::showKPager(bool toggleShow) +{ + QPoint pt; + switch ( position() ) + { + case pTop: + pt = mapToGlobal( QPoint(x(), y() + height()) ); + break; + case pLeft: + pt = mapToGlobal( QPoint(x() + width(), y()) ); + break; + case pRight: + case pBottom: + default: + pt=mapToGlobal( QPoint(x(), y()) ); + } + + DCOPClient *dcop=kapp->dcopClient(); + + QByteArray data; + QDataStream arg(data, IO_WriteOnly); + arg << pt.x() << pt.y() ; + if (toggleShow) + { + dcop->send("kpager", "KPagerIface", "toggleShow(int,int)", data); + } + else + { + dcop->send("kpager", "KPagerIface", "showAt(int,int)", data); + } +} + +void KMiniPager::applicationRegistered( const QCString & appName ) +{ + if (appName == "kpager") + { + disconnect( kapp->dcopClient(), SIGNAL( applicationRegistered(const QCString &) ), + this, SLOT(applicationRegistered(const QCString &)) ); + showKPager(false); + } +} + diff --git a/kicker/applets/minipager/pagerapplet.h b/kicker/applets/minipager/pagerapplet.h new file mode 100644 index 000000000..f47b0411d --- /dev/null +++ b/kicker/applets/minipager/pagerapplet.h @@ -0,0 +1,138 @@ +/***************************************************************** + +Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __MINIPAGER_H +#define __MINIPAGER_H + +#include +#include + +#include +#include + +#include "pagerbutton.h" +#include "pagersettings.h" + +class QButtonGroup; +class QGridLayout; +class QTimer; + +class KProcess; +class KWinModule; +class KTextShadowEngine; +class KSelectionOwner; + +class PagerSettings; + +class KMiniPager : public KPanelApplet +{ + Q_OBJECT + +public: + KMiniPager(const QString& configFile, Type t = Normal, int actions = 0, + QWidget *parent = 0, const char *name = 0); + + virtual ~KMiniPager(); + + int widthForHeight(int height) const; + int heightForWidth(int width) const; + + KWin::WindowInfo* info( WId win ); + KWinModule* kwin() { return m_kwin; } + KTextShadowEngine* shadowEngine(); + + void setActive( WId active ) { m_activeWindow = active; } + WId activeWindow() { return m_activeWindow; } + + enum ConfigOptions { LaunchExtPager = 96, WindowThumbnails, + WindowIcons, ConfigureDesktops, RenameDesktop }; + int labelType() const { return m_settings->labelType(); } + + int bgType() const { return m_settings->backgroundType(); } + + bool desktopPreview() const { return m_settings->preview(); } + bool windowIcons() const { return m_settings->icons(); } + + Orientation orientation() const { return KPanelApplet::orientation(); } + Direction popupDirection() { return KPanelApplet::popupDirection(); } + + void emitRequestFocus() { emit requestFocus(); } + + QPoint clickPos; + +public slots: + void slotSetDesktop(int desktop); + void slotSetDesktopViewport(int desktop, const QPoint& viewport); + void slotSetDesktopCount(int count); + void slotButtonSelected(int desk ); + void slotActiveWindowChanged( WId win ); + void slotWindowAdded( WId ); + void slotWindowRemoved( WId ); + void slotWindowChanged( WId, unsigned int ); + void slotShowMenu( const QPoint&, int ); + void slotDesktopNamesChanged(); + void slotBackgroundChanged( int ); + + void refresh(); + +protected: + void drawButtons(); + void startDrag( const QPoint &point ); + + void updateDesktopLayout(int,int,int); + void resizeEvent(QResizeEvent*); + void wheelEvent( QWheelEvent* e ); + void showKPager(bool toggleShow); + +protected slots: + void showPager(); + void applicationRegistered(const QCString &appName); + void aboutToShowContextMenu(); + void contextMenuActivated(int); + +private: + QValueList m_desktops; + int m_curDesk; + int m_rmbDesk; + + QIntDict m_windows; + WId m_activeWindow; + + QButtonGroup *m_group; + + QGridLayout *m_layout; + bool m_useViewports; + int desktopLayoutOrientation; + int desktopLayoutX; + int desktopLayoutY; + KSelectionOwner* m_desktopLayoutOwner; + + KWinModule *m_kwin; + KTextShadowEngine* m_shadowEngine; + + QPopupMenu *m_contextMenu; + PagerSettings *m_settings; +}; + +#endif + diff --git a/kicker/applets/minipager/pagerbutton.cpp b/kicker/applets/minipager/pagerbutton.cpp new file mode 100644 index 000000000..b4e268b8e --- /dev/null +++ b/kicker/applets/minipager/pagerbutton.cpp @@ -0,0 +1,824 @@ +/***************************************************************** + +Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "kickertip.h" +#include "kickerSettings.h" +#include "kshadowengine.h" +#include "paneldrag.h" + +#include "pagerapplet.h" +#include "pagerbutton.h" +#include "pagerbutton.moc" +#include "pagersettings.h" + +#ifdef FocusOut +#undef FocusOut +#endif + +KSharedPixmap* KMiniPagerButton::s_commonSharedPixmap; +KPixmap* KMiniPagerButton::s_commonBgPixmap; + +KMiniPagerButton::KMiniPagerButton(int desk, bool useViewPorts, const QPoint& viewport, + KMiniPager *parent, const char *name) + : QButton(parent, name), + m_pager(parent), + m_desktop(desk), + m_useViewports(useViewPorts), + m_viewport(viewport), + m_lineEdit(0), + m_sharedPixmap(0), + m_bgPixmap(0), + m_isCommon(false), + m_currentWindow(0), + m_inside(false) +{ + setToggleButton(true); + setAcceptDrops(true); + setWFlags(WNoAutoErase); + + setBackgroundOrigin(AncestorOrigin); + installEventFilter(KickerTip::the()); + + m_desktopName = m_pager->kwin()->desktopName(m_desktop); + + connect(this, SIGNAL(clicked()), SLOT(slotClicked())); + connect(this, SIGNAL(toggled(bool)), SLOT(slotToggled(bool))); + connect(&m_dragSwitchTimer, SIGNAL(timeout()), this, SLOT(slotDragSwitch())); + connect(&m_updateCompressor, SIGNAL(timeout()), this, SLOT(update())); + + if (m_pager->desktopPreview()) + { + setMouseTracking(true); + } + loadBgPixmap(); +} + +KMiniPagerButton::~KMiniPagerButton() +{ + delete m_sharedPixmap; + delete m_bgPixmap; +} + +QRect KMiniPagerButton::mapGeometryToViewport(const KWin::WindowInfo& info) const +{ + if (!m_useViewports) + return info.frameGeometry(); + + // ### fix vertically layouted viewports + QRect _r(info.frameGeometry()); + QPoint vx(m_pager->kwin()->currentViewport(m_pager->kwin()->currentDesktop())); + + _r.moveBy( - (m_desktop - vx.x()) * QApplication::desktop()->width(), + 0); + + if ((info.state() & NET::Sticky)) + { + _r.moveTopLeft(QPoint(_r.x() % QApplication::desktop()->width(), + _r.y() % QApplication::desktop()->height())); + + } + + return _r; +} + +QPoint KMiniPagerButton::mapPointToViewport(const QPoint& _p) const +{ + if (!m_useViewports) return _p; + + QPoint vx(m_pager->kwin()->currentViewport(m_pager->kwin()->currentDesktop())); + + // ### fix vertically layouted viewports + QPoint p(_p); + p.setX(p.x() + (m_desktop - vx.x()) * QApplication::desktop()->width()); + return p; +} + +bool KMiniPagerButton::shouldPaintWindow( KWin::WindowInfo *info ) const +{ + if (!info) + return false; + +// if (info->mappingState != NET::Visible) +// return false; + + NET::WindowType type = info->windowType( NET::NormalMask | NET::DesktopMask + | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask + | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask ); + + if (type == NET::Desktop || type == NET::Dock || type == NET::TopMenu) + return false; + + if (!m_useViewports && !info->isOnDesktop(m_desktop)) + return false; + + if (m_useViewports) { + QRect r = mapGeometryToViewport(*info); + + if (!info->hasState(NET::Sticky) && + !QApplication::desktop()->geometry().contains(r.topLeft()) && + !QApplication::desktop()->geometry().contains(r.topRight())) + return false; + } + + if (info->state() & NET::SkipPager || info->state() & NET::Shaded ) + return false; + + if (info->win() == m_pager->winId()) + return false; + + if ( info->isMinimized() ) + return false; + + return true; +} + +void KMiniPagerButton::resizeEvent(QResizeEvent *ev) +{ + if (m_lineEdit) + { + m_lineEdit->setGeometry(rect()); + } + + delete m_bgPixmap; + m_bgPixmap = 0; + + QButton::resizeEvent(ev); +} + +void KMiniPagerButton::windowsChanged() +{ + m_currentWindow = 0; + + if (!m_updateCompressor.isActive()) + { + m_updateCompressor.start(50, true); + } +} + +void KMiniPagerButton::backgroundChanged() +{ + delete s_commonSharedPixmap; + s_commonSharedPixmap = 0; + delete s_commonBgPixmap; + s_commonBgPixmap = 0; + loadBgPixmap(); +} + +void KMiniPagerButton::loadBgPixmap() +{ + if (m_pager->bgType() != PagerSettings::EnumBackgroundType::BgLive) + return; // not needed + + DCOPClient *client = kapp->dcopClient(); + if (!client->isAttached()) + { + client->attach(); + } + + QCString kdesktop_name; + int screen_number = DefaultScreen(qt_xdisplay()); + if (screen_number == 0) + kdesktop_name = "kdesktop"; + else + kdesktop_name.sprintf("kdesktop-screen-%d", screen_number); + + QByteArray data, replyData; + QCString replyType; + if (client->call(kdesktop_name, "KBackgroundIface", "isCommon()", + data, replyType, replyData)) + { + if (replyType == "bool") + { + QDataStream reply(replyData, IO_ReadOnly); + reply >> m_isCommon; + } + } + + if (m_isCommon) + { + if (s_commonBgPixmap) + { // pixmap is already ready, just use it + backgroundLoaded( true ); + return; + } + else if (s_commonSharedPixmap) + { // other button is already fetching the pixmap + connect(s_commonSharedPixmap, SIGNAL(done(bool)), + SLOT(backgroundLoaded(bool))); + return; + } + } + + QDataStream args( data, IO_WriteOnly ); + args << 1; + client->send(kdesktop_name, "KBackgroundIface", "setExport(int)", data); + + if (m_isCommon) + { + if (!s_commonSharedPixmap) + { + s_commonSharedPixmap = new KSharedPixmap; + connect(s_commonSharedPixmap, SIGNAL(done(bool)), + SLOT(backgroundLoaded(bool))); + } + s_commonSharedPixmap->loadFromShared(QString("DESKTOP1")); + } + else + { + if (!m_sharedPixmap) + { + m_sharedPixmap = new KSharedPixmap; + connect(m_sharedPixmap, SIGNAL(done(bool)), + SLOT(backgroundLoaded(bool))); + } + m_sharedPixmap->loadFromShared(QString("DESKTOP%1").arg(m_desktop)); + } +} + +static QPixmap scalePixmap(const QPixmap &pixmap, int width, int height) +{ + if (pixmap.width()>100) + { + KPixmapIO io; + QImage img( io.convertToImage( pixmap ) ); + return io.convertToPixmap( img.smoothScale( width, height ) ); + } + + QImage img( pixmap.convertToImage().smoothScale( width, height ) ); + QPixmap pix; + pix.convertFromImage( img ); + + return pix; +} + +void KMiniPagerButton::backgroundLoaded( bool loaded ) +{ + if (loaded) + { + if (!m_bgPixmap) + { + m_bgPixmap = new KPixmap; + } + if (m_isCommon) + { + if (!s_commonBgPixmap) + { + s_commonBgPixmap = new KPixmap; + *s_commonBgPixmap = scalePixmap(*s_commonSharedPixmap, width(), height()); + s_commonSharedPixmap->deleteLater(); // let others get the signal too + s_commonSharedPixmap = 0; + } + *m_bgPixmap = *s_commonBgPixmap; + } + else + { + *m_bgPixmap = scalePixmap(*m_sharedPixmap, width(), height()); + delete m_sharedPixmap; + m_sharedPixmap = 0L; + } + + update(); + } + else + { + kdWarning() << "Error getting the background\n"; + } +} + +void KMiniPagerButton::enterEvent(QEvent *) +{ + m_inside = true; + update(); +} + +void KMiniPagerButton::leaveEvent(QEvent *) +{ + m_inside = false; + update(); +} + +void KMiniPagerButton::drawButton(QPainter *bp) +{ + int w = width(); + int h = height(); + bool on = isOn(); + bool down = isDown(); + + QBrush background; + + bool liveBkgnd = m_pager->bgType() == PagerSettings::EnumBackgroundType::BgLive; + bool transparent = m_pager->bgType() == PagerSettings::EnumBackgroundType::BgTransparent; + + // background + + if (backgroundPixmap()) + { + QPoint pt = backgroundOffset(); + bp->drawTiledPixmap(0, 0, width(), height(), *backgroundPixmap(), pt.x(), pt.y()); + } + else + { + bp->fillRect(0, 0, width(), height(), paletteBackgroundColor()); + } + + + // desktop background + + if (liveBkgnd) + { + if (m_bgPixmap && !m_bgPixmap->isNull()) + { + if (on) + { + KPixmap tmp = *m_bgPixmap; + KPixmapEffect::intensity(tmp, 0.33); + bp->drawPixmap(0, 0, tmp); + } + else + { + bp->drawPixmap(0, 0, *m_bgPixmap); + } + } + else + { + liveBkgnd = false; + } + } + + if (!liveBkgnd) + { + if (transparent) + { + // transparent windows get an 1 pixel frame... + if (on) + { + bp->setPen(colorGroup().midlight()); + } + else if (down) + { + bp->setPen(KickerLib::blendColors(colorGroup().mid(), + colorGroup().midlight())); + } + else + { + bp->setPen(colorGroup().dark()); + } + + bp->drawRect(0, 0, w, h); + } + else + { + QBrush background; + + if (on) + { + background = colorGroup().brush(QColorGroup::Midlight); + } + else if (down) + { + background = KickerLib::blendColors(colorGroup().mid(), + colorGroup().midlight()); + } + else + { + background = colorGroup().brush(QColorGroup::Mid); + } + + bp->fillRect(0, 0, w, h, background); + } + } + + // window preview... + if (m_pager->desktopPreview()) + { + KWinModule* kwin = m_pager->kwin(); + KWin::WindowInfo *info = 0; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + + QValueList windows = kwin->stackingOrder(); + QValueList::const_iterator itEnd = windows.constEnd(); + for (QValueList::ConstIterator it = windows.constBegin(); it != itEnd; ++it) + { + info = m_pager->info(*it); + + if (shouldPaintWindow(info)) + { + QRect r = mapGeometryToViewport(*info); + r = QRect(r.x() * width() / dw, 2 + r.y() * height() / dh, + r.width() * width() / dw, r.height() * height() / dh); + + if (kwin->activeWindow() == info->win()) + { + QBrush brush = colorGroup().brush(QColorGroup::Highlight); + qDrawShadeRect(bp, r, colorGroup(), false, 1, 0, &brush); + } + else + { + QBrush brush = colorGroup().brush(QColorGroup::Button); + + if (on) + { + brush.setColor(brush.color().light(120)); + } + + bp->fillRect(r, brush); + qDrawShadeRect(bp, r, colorGroup(), true, 1, 0); + } + + if (m_pager->windowIcons() && r.width() > 15 && r.height() > 15) + { + QPixmap icon = KWin::icon(*it, 16, 16, true); + if (!icon.isNull()) + { + bp->drawPixmap(r.left() + ((r.width() - 16) / 2), + r.top() + ((r.height() - 16) / 2), + icon); + } + } + } + } + } + + if (liveBkgnd) + { + // draw a little border around the individual buttons + // makes it look a bit more finished. + if (on) + { + bp->setPen(colorGroup().midlight()); + } + else + { + bp->setPen(colorGroup().mid()); + } + + bp->drawRect(0, 0, w, h); + } + + if (m_pager->labelType() != PagerSettings::EnumLabelType::LabelNone) + { + QString label = (m_pager->labelType() == PagerSettings::EnumLabelType::LabelNumber) ? + QString::number(m_desktop) : m_desktopName; + + if (transparent || liveBkgnd) + { + bp->setPen(on ? colorGroup().midlight() : colorGroup().buttonText()); + m_pager->shadowEngine()->drawText(*bp, QRect(0, 0, w, h), AlignCenter, label, size()); + } + else + bp->drawText(0, 0, w, h, AlignCenter, label); + } + + if (m_inside) + KickerLib::drawBlendedRect(bp, QRect(1, 1, width() - 2, height() - 2), colorGroup().foreground()); +} + +void KMiniPagerButton::mousePressEvent(QMouseEvent * e) +{ + if (e->button() == RightButton) + { + // prevent LMB down -> RMB down -> LMB up sequence + if ((e->state() & MouseButtonMask ) == NoButton) + { + emit showMenu(e->globalPos(), m_desktop); + return; + } + } + + if (m_pager->desktopPreview()) + { + m_pager->clickPos = e->pos(); + } + + QButton::mousePressEvent(e); +} + +void KMiniPagerButton::mouseReleaseEvent(QMouseEvent* e) +{ + m_pager->clickPos = QPoint(); + QButton::mouseReleaseEvent(e); +} + +void KMiniPagerButton::mouseMoveEvent(QMouseEvent* e) +{ + if (!m_pager->desktopPreview()) + { + return; + } + + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + int w = width(); + int h = height(); + + QPoint pos(m_pager->clickPos.isNull() ? mapFromGlobal(QCursor::pos()) : m_pager->clickPos); + QPoint p = mapPointToViewport(QPoint(pos.x() * dw / w, pos.y() * dh / h)); + + Task::Ptr wasWindow = m_currentWindow; + m_currentWindow = TaskManager::the()->findTask(m_useViewports ? 1 : m_desktop, p); + + if (wasWindow != m_currentWindow) + { + KickerTip::Client::updateKickerTip(); + } + + if (m_currentWindow && !m_pager->clickPos.isNull() && + (m_pager->clickPos - e->pos()).manhattanLength() > KGlobalSettings::dndEventDelay()) + { + QRect r = m_currentWindow->geometry(); + + // preview window height, window width + int ww = r.width() * w / dw; + int wh = r.height() * h / dh; + QPixmap windowImage(ww, wh); + QPainter bp(&windowImage, this); + + bp.setPen(colorGroup().foreground()); + bp.drawRect(0, 0, ww, wh); + bp.fillRect(1, 1, ww - 2, wh - 2, colorGroup().background()); + + Task::List tasklist; + tasklist.append(m_currentWindow); + TaskDrag* drag = new TaskDrag(tasklist, this); + QPoint offset(m_pager->clickPos.x() - (r.x() * w / dw), + m_pager->clickPos.y() - (r.y() * h / dh)); + drag->setPixmap(windowImage, offset); + drag->dragMove(); + + if (isDown()) + { + setDown(false); + } + + m_pager->clickPos = QPoint(); + } +} + +void KMiniPagerButton::dragEnterEvent(QDragEnterEvent* e) +{ + if (PanelDrag::canDecode(e)) + { + // ignore container drags + return; + } + else if (TaskDrag::canDecode(e)) + { + // if it's a task drag don't switch the desktop, just accept it + e->accept(); + setDown(true); + } + else + { + // if a dragitem is held for over a pager button for two seconds, + // activate corresponding desktop + m_dragSwitchTimer.start(1000, true); + QButton::dragEnterEvent(e); + } +} + +void KMiniPagerButton::dropEvent(QDropEvent* e) +{ + if (TaskDrag::canDecode(e)) + { + e->accept(); + Task::List tasks(TaskDrag::decode(e)); + + if ((m_useViewports || e->source() == this) && tasks.count() == 1) + { + Task::Ptr task = tasks[0]; + int dw = QApplication::desktop()->width(); + int dh = QApplication::desktop()->height(); + int w = width(); + int h = height(); + QRect location = mapGeometryToViewport(task->info()); + QPoint pos = mapPointToViewport(e->pos()); + int deltaX = pos.x() - m_pager->clickPos.x(); + int deltaY = pos.y() - m_pager->clickPos.y(); + + if (abs(deltaX) < 3) + { + deltaX = 0; + } + else + { + deltaX = deltaX * dw / w; + } + + if (abs(deltaY) < 3) + { + deltaY = 0; + } + else + { + deltaY = deltaY * dh / h; + } + + location.moveBy(deltaX, deltaY); + + XMoveWindow(x11Display(), task->window(), location.x(), location.y()); + if ((e->source() != this || !task->isOnAllDesktops()) && + task->desktop() != m_desktop) + { + task->toDesktop(m_desktop); + } + } + else + { + Task::List::iterator itEnd = tasks.end(); + for (Task::List::iterator it = tasks.begin(); it != itEnd; ++it) + { + (*it)->toDesktop(m_desktop); + } + } + + setDown(false); + } + + QButton::dropEvent( e ); +} + +void KMiniPagerButton::enabledChange( bool oldEnabled ) +{ + if (m_pager->bgType() == PagerSettings::EnumBackgroundType::BgLive) + { + m_pager->refresh(); + } + + QButton::enabledChange(oldEnabled); +} + +void KMiniPagerButton::dragLeaveEvent( QDragLeaveEvent* e ) +{ + m_dragSwitchTimer.stop(); + + if (m_pager->kwin()->currentDesktop() != m_desktop) + { + setDown(false); + } + + QButton::dragLeaveEvent( e ); +} + +void KMiniPagerButton::slotDragSwitch() +{ + emit buttonSelected(m_desktop); +} + +void KMiniPagerButton::slotClicked() +{ + emit buttonSelected(m_desktop); +} + +void KMiniPagerButton::rename() +{ + if ( !m_lineEdit ) { + m_lineEdit = new QLineEdit( this ); + connect( m_lineEdit, SIGNAL( returnPressed() ), m_lineEdit, SLOT( hide() ) ); + m_lineEdit->installEventFilter( this ); + } + m_lineEdit->setGeometry( rect() ); + m_lineEdit->setText(m_desktopName); + m_lineEdit->show(); + m_lineEdit->setFocus(); + m_lineEdit->selectAll(); + m_pager->emitRequestFocus(); +} + +void KMiniPagerButton::slotToggled( bool b ) +{ + if ( !b && m_lineEdit ) + { + m_lineEdit->hide(); + } +} + +bool KMiniPagerButton::eventFilter( QObject *o, QEvent * e) +{ + if (o && o == m_lineEdit && + (e->type() == QEvent::FocusOut || e->type() == QEvent::Hide)) + { + m_pager->kwin()->setDesktopName( m_desktop, m_lineEdit->text() ); + m_desktopName = m_lineEdit->text(); + QTimer::singleShot( 0, m_lineEdit, SLOT( deleteLater() ) ); + m_lineEdit = 0; + return true; + } + + return QButton::eventFilter(o, e); +} + +void KMiniPagerButton::updateKickerTip(KickerTip::Data &data) +{ + Task::Dict tasks = TaskManager::the()->tasks(); + Task::Dict::iterator taskEnd = tasks.end(); + uint taskCounter = 0; + uint taskLimiter = 4; + QString lastWindow; + + for (Task::Dict::iterator it = tasks.begin(); it != taskEnd; ++it) + { + if (it.data()->desktop() == m_desktop || it.data()->isOnAllDesktops()) + { + taskCounter++; + if (taskCounter > taskLimiter) + { + lastWindow = it.data()->visibleName(); + continue; + } + + QPixmap winIcon = it.data()->pixmap(); + QString bullet; + + if (winIcon.isNull()) + { + bullet = "•"; + } + else + { + data.mimeFactory->setPixmap(QString::number(taskCounter), winIcon); + bullet = QString("").arg(taskCounter).arg(16).arg(16); + } + + QString name = KStringHandler::cPixelSqueeze(it.data()->visibleName(), fontMetrics(), 400); + name = QStyleSheet::escape(name); + if (it.data() == m_currentWindow) + { + data.subtext.append(QString("
%1  ").arg(bullet)); + data.subtext.append(name).append(""); + } + else + { + data.subtext.append(QString("
%1  ").arg(bullet)); + data.subtext.append(name); + } + } + } + + if (taskCounter > taskLimiter) + { + if (taskCounter - taskLimiter == 1) + { + data.subtext.append("
• ").append(lastWindow); + } + else + { + data.subtext.append("
") + .append(i18n("and 1 other", "and %n others", taskCounter - taskLimiter)) + .append(""); + } + } + + if (taskCounter > 0) + { + data.subtext.prepend(i18n("One window:", + "%n windows:", + taskCounter)); + } + + data.duration = 4000; + data.icon = DesktopIcon("window_list", KIcon::SizeMedium); + data.message = QStyleSheet::escape(m_desktopName); + data.direction = m_pager->popupDirection(); +} + diff --git a/kicker/applets/minipager/pagerbutton.h b/kicker/applets/minipager/pagerbutton.h new file mode 100644 index 000000000..1547201e0 --- /dev/null +++ b/kicker/applets/minipager/pagerbutton.h @@ -0,0 +1,111 @@ +/***************************************************************** + +Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __MINIPAGERBUTTON_H +#define __MINIPAGERBUTTON_H + +#include + +#include "taskmanager.h" +#include "kickertip.h" + +class KPixmap; +class KWinModule; +class KMiniPager; +class KSharedPixmap; +class QLineEdit; + +class KMiniPagerButton : public QButton, public KickerTip::Client +{ + Q_OBJECT +public: + KMiniPagerButton(int desk, bool useViewports, const QPoint& viewport, + KMiniPager *parent=0, const char *name=0); + ~KMiniPagerButton(); + + int desktop() { return m_desktop; } + + QString desktopName() { return m_desktopName; } + void setDesktopName( QString name ) { m_desktopName = name; } + + void rename(); + void backgroundChanged(); + void windowsChanged(); + + bool shouldPaintWindow( KWin::WindowInfo *info ) const; + +signals: + void buttonSelected( int desk ); + void showMenu( const QPoint&, int ); + +protected: + void drawButton(QPainter *); + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + void resizeEvent(QResizeEvent *ev); + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void dragEnterEvent(QDragEnterEvent* e); + void dragLeaveEvent(QDragLeaveEvent* e); + void enabledChange( bool oldEnabled ); + void dropEvent(QDropEvent* e); + + bool eventFilter(QObject*, QEvent*); + void updateKickerTip(KickerTip::Data &data); + +private slots: + void slotToggled(bool); + void slotClicked(); + void slotDragSwitch(); + + void backgroundLoaded( bool loaded ); + +private: + void loadBgPixmap(); + QRect mapGeometryToViewport(const KWin::WindowInfo&) const; + QPoint mapPointToViewport(const QPoint&) const; + + KMiniPager* m_pager; + int m_desktop; + bool m_useViewports; + QString m_desktopName; + QPoint m_viewport; + + QTimer m_updateCompressor; + QTimer m_dragSwitchTimer; + Task::Ptr m_dragging; + + QLineEdit* m_lineEdit; + + KSharedPixmap *m_sharedPixmap; + KPixmap *m_bgPixmap; + static KSharedPixmap *s_commonSharedPixmap; + static KPixmap *s_commonBgPixmap; + bool m_isCommon; + + Task::Ptr m_currentWindow; + bool m_inside; +}; + +#endif diff --git a/kicker/applets/minipager/pagersettings.kcfg b/kicker/applets/minipager/pagersettings.kcfg new file mode 100644 index 000000000..8a26bdc86 --- /dev/null +++ b/kicker/applets/minipager/pagersettings.kcfg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + LabelNumber + + + + + + + + + + + + + + + + BgPlain + + + + + + 0 + 0 + 4 + + + + + true + + + + + true + + + diff --git a/kicker/applets/minipager/pagersettings.kcfgc b/kicker/applets/minipager/pagersettings.kcfgc new file mode 100644 index 000000000..47a1915f4 --- /dev/null +++ b/kicker/applets/minipager/pagersettings.kcfgc @@ -0,0 +1,4 @@ +File=pagersettings.kcfg +Singleton=false +ClassName=PagerSettings +Mutators=true -- cgit v1.2.1