Some updates to the tabbox.
Provide a pair of methods, setCurrentClient() and setCurrentDesktop(), to allow effects to select items in the tabbox without activating them. Insulate effects from having to know the order of desktops, with currentDesktopList(). DesktopMode and DesktopListMode should be effectively identical as far as how effects work. Some changes to how the tabbox refcounting is done, should work a little better. Other small cosmetic changes. Update BoxSwitchEffect. svn path=/branches/work/kwin_composite/; revision=647594
This commit is contained in:
parent
d809643245
commit
574e562906
5 changed files with 345 additions and 216 deletions
|
@ -10,10 +10,11 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "boxswitch.h"
|
||||
|
||||
#include <tabbox.h>
|
||||
#include <client.h>
|
||||
#include <scene_xrender.h>
|
||||
#include <scene_opengl.h>
|
||||
#include "tabbox.h"
|
||||
#include "client.h"
|
||||
#include "scene_xrender.h"
|
||||
#include "scene_opengl.h"
|
||||
|
||||
#include <QSize>
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
|
@ -96,7 +97,7 @@ void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
|
|||
{
|
||||
paintFrame();
|
||||
|
||||
for( painting_desktop = 1; painting_desktop <= desktops.count(); painting_desktop++ )
|
||||
foreach( painting_desktop, desktops.keys())
|
||||
{
|
||||
if( painting_desktop == selected_desktop )
|
||||
{
|
||||
|
@ -120,7 +121,7 @@ void BoxSwitchEffect::paintWindow( EffectWindow* w, int mask, QRegion region, Wi
|
|||
{
|
||||
if( windows.contains( w ) && w != selected_window )
|
||||
{
|
||||
data.opacity *= 0.1;
|
||||
data.opacity *= 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,28 +143,17 @@ void BoxSwitchEffect::windowInputMouseEvent( Window w, QEvent* e )
|
|||
{
|
||||
if( windows[ w ]->clickable.contains( pos ))
|
||||
{
|
||||
if( Client* c = static_cast< Client* >( w->window()))
|
||||
{
|
||||
Workspace::self()->activateClient( c );
|
||||
if( c->isShade() && options->shadeHover )
|
||||
c->setShade( ShadeActivated );
|
||||
Workspace::self()->unrefTabBox();
|
||||
setInactive();
|
||||
break;
|
||||
}
|
||||
Workspace::self()->setTabBoxClient( static_cast< Client* >( w->window()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 1; i <= desktops.count(); i++ )
|
||||
foreach( int i, desktops.keys())
|
||||
{
|
||||
if( desktops[ i ]->clickable.contains( pos ))
|
||||
{
|
||||
Workspace::self()->setCurrentDesktop( i );
|
||||
Workspace::self()->unrefTabBox();
|
||||
setInactive();
|
||||
break;
|
||||
Workspace::self()->setTabBoxDesktop( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,8 +225,8 @@ void BoxSwitchEffect::tabBoxAdded( int mode )
|
|||
}
|
||||
}
|
||||
else
|
||||
{ // DesktopMode or DesktopListMode
|
||||
if( Workspace::self()->numberOfDesktops() > 0 )
|
||||
{ // DesktopMode
|
||||
if( Workspace::self()->currentTabBoxDesktopList().count() > 0 )
|
||||
{
|
||||
mMode = mode;
|
||||
painting_desktop = 0;
|
||||
|
@ -269,19 +259,20 @@ void BoxSwitchEffect::tabBoxUpdated()
|
|||
if( windows.contains( selected_window ))
|
||||
workspace()->addRepaint( windows.value( selected_window )->area );
|
||||
selected_window->window()->addRepaintFull();
|
||||
if( Workspace::self()->currentTabBoxClientList() == tab_clients )
|
||||
if( Workspace::self()->currentTabBoxClientList() == original_windows )
|
||||
return;
|
||||
tab_clients = Workspace::self()->currentTabBoxClientList();
|
||||
original_windows = Workspace::self()->currentTabBoxClientList();
|
||||
}
|
||||
else
|
||||
{
|
||||
{ // DesktopMode
|
||||
if( desktops.contains( selected_desktop ))
|
||||
workspace()->addRepaint( desktops.value( selected_desktop )->area );
|
||||
selected_desktop = Workspace::self()->currentTabBoxDesktop();
|
||||
if( desktops.contains( selected_desktop ))
|
||||
workspace()->addRepaint( desktops.value( selected_desktop )->area );
|
||||
if( Workspace::self()->numberOfDesktops() == desktops.count())
|
||||
if( Workspace::self()->currentTabBoxDesktopList() == original_desktops )
|
||||
return;
|
||||
original_desktops = Workspace::self()->currentTabBoxDesktopList();
|
||||
}
|
||||
workspace()->addRepaint( frame_area );
|
||||
calculateFrameSize();
|
||||
|
@ -296,11 +287,12 @@ void BoxSwitchEffect::setActive()
|
|||
mActivated = true;
|
||||
if( mMode == TabBox::WindowsMode )
|
||||
{
|
||||
tab_clients = Workspace::self()->currentTabBoxClientList();
|
||||
original_windows = Workspace::self()->currentTabBoxClientList();
|
||||
selected_window = Workspace::self()->currentTabBoxClient()->effectWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
original_desktops = Workspace::self()->currentTabBoxDesktopList();
|
||||
selected_desktop = Workspace::self()->currentTabBoxDesktop();
|
||||
}
|
||||
calculateFrameSize();
|
||||
|
@ -321,6 +313,7 @@ void BoxSwitchEffect::setActive()
|
|||
void BoxSwitchEffect::setInactive()
|
||||
{
|
||||
mActivated = false;
|
||||
Workspace::self()->unrefTabBox();
|
||||
if( mInput != None )
|
||||
{
|
||||
effects->destroyInputWindow( mInput );
|
||||
|
@ -369,13 +362,13 @@ void BoxSwitchEffect::calculateFrameSize()
|
|||
|
||||
if( mMode == TabBox::WindowsMode )
|
||||
{
|
||||
itemcount = tab_clients.count();
|
||||
itemcount = original_windows.count();
|
||||
item_max_size.setWidth( 200 );
|
||||
item_max_size.setHeight( 200 );
|
||||
}
|
||||
else
|
||||
{
|
||||
itemcount = Workspace::self()->numberOfDesktops();
|
||||
itemcount = original_desktops.count();
|
||||
item_max_size.setWidth( 200 );
|
||||
item_max_size.setHeight( 200 );
|
||||
}
|
||||
|
@ -395,9 +388,9 @@ void BoxSwitchEffect::calculateItemSizes()
|
|||
if( mMode == TabBox::WindowsMode )
|
||||
{
|
||||
windows.clear();
|
||||
for( int i = 0; i < tab_clients.count(); i++ )
|
||||
for( int i = 0; i < original_windows.count(); i++ )
|
||||
{
|
||||
EffectWindow* w = tab_clients.at( i )->effectWindow();
|
||||
EffectWindow* w = original_windows.at( i )->effectWindow();
|
||||
windows[ w ] = new ItemInfo();
|
||||
|
||||
windows[ w ]->area = QRect( frame_area.x() + frame_margin
|
||||
|
@ -410,21 +403,16 @@ void BoxSwitchEffect::calculateItemSizes()
|
|||
else
|
||||
{
|
||||
desktops.clear();
|
||||
int iDesktop = ( mMode == TabBox::DesktopMode ) ? Workspace::self()->currentDesktop() : 1;
|
||||
for( int i = 1; i <= Workspace::self()->numberOfDesktops(); i++ )
|
||||
for( int i = 0; i < original_desktops.count(); i++ )
|
||||
{
|
||||
desktops[ iDesktop ] = new ItemInfo();
|
||||
int it = original_desktops.at( i );
|
||||
desktops[ it ] = new ItemInfo();
|
||||
|
||||
desktops[ iDesktop ]->area = QRect( frame_area.x() + frame_margin
|
||||
+ ( i - 1 ) * item_max_size.width(),
|
||||
desktops[ it ]->area = QRect( frame_area.x() + frame_margin
|
||||
+ i * item_max_size.width(),
|
||||
frame_area.y() + frame_margin,
|
||||
item_max_size.width(), item_max_size.height());
|
||||
desktops[ iDesktop ]->clickable = desktops[ iDesktop ]->area;
|
||||
|
||||
if( mMode == TabBox::DesktopMode )
|
||||
iDesktop = Workspace::self()->nextDesktopFocusChain( iDesktop );
|
||||
else
|
||||
iDesktop++;
|
||||
desktops[ it ]->clickable = desktops[ it ]->area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -439,12 +427,17 @@ void BoxSwitchEffect::paintFrame()
|
|||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 0, 0, 0, alpha );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( frame_area.x(), frame_area.y());
|
||||
glVertex2i( frame_area.x() + frame_area.width(), frame_area.y());
|
||||
glVertex2i( frame_area.x() + frame_area.width(), frame_area.y() + frame_area.height());
|
||||
glVertex2i( frame_area.x(), frame_area.y() + frame_area.height());
|
||||
glEnd();
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
int verts[ 4 * 2 ] =
|
||||
{
|
||||
frame_area.x(), frame_area.y(),
|
||||
frame_area.x(), frame_area.y() + frame_area.height(),
|
||||
frame_area.x() + frame_area.width(), frame_area.y() + frame_area.height(),
|
||||
frame_area.x() + frame_area.width(), frame_area.y()
|
||||
};
|
||||
glVertexPointer( 2, GL_INT, 0, verts );
|
||||
glDrawArrays( GL_QUADS, 0, 4 );
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glPopAttrib();
|
||||
}
|
||||
else
|
||||
|
@ -480,12 +473,17 @@ void BoxSwitchEffect::paintHighlight( QRect area, QString text )
|
|||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 1, 1, 1, alpha );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( area.x(), area.y());
|
||||
glVertex2i( area.x() + area.width(), area.y());
|
||||
glVertex2i( area.x() + area.width(), area.y() + area.height());
|
||||
glVertex2i( area.x(), area.y() + area.height());
|
||||
glEnd();
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
int verts[ 4 * 2 ] =
|
||||
{
|
||||
area.x(), area.y(),
|
||||
area.x(), area.y() + area.height(),
|
||||
area.x() + area.width(), area.y() + area.height(),
|
||||
area.x() + area.width(), area.y()
|
||||
};
|
||||
glVertexPointer( 2, GL_INT, 0, verts );
|
||||
glDrawArrays( GL_QUADS, 0, 4 );
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glPopAttrib();
|
||||
}
|
||||
else
|
||||
|
@ -512,6 +510,22 @@ void BoxSwitchEffect::paintHighlight( QRect area, QString text )
|
|||
// kDebug() << text << endl; // TODO draw this nicely on screen
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintWindowThumbnail( EffectWindow* w )
|
||||
{
|
||||
if( !windows.contains( w ))
|
||||
return;
|
||||
WindowPaintData data;
|
||||
|
||||
setPositionTransformations( data,
|
||||
windows[ w ]->thumbnail, w,
|
||||
windows[ w ]->area.adjusted( highlight_margin, highlight_margin, -highlight_margin, -highlight_margin ),
|
||||
Qt::KeepAspectRatio );
|
||||
|
||||
effects->drawWindow( w,
|
||||
Scene::PAINT_WINDOW_OPAQUE | Scene::PAINT_WINDOW_TRANSFORMED,
|
||||
windows[ w ]->thumbnail, data );
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintDesktopThumbnail( int iDesktop )
|
||||
{
|
||||
if( !desktops.contains( iDesktop ))
|
||||
|
@ -538,22 +552,6 @@ void BoxSwitchEffect::paintDesktopThumbnail( int iDesktop )
|
|||
region, data );
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintWindowThumbnail( EffectWindow* w )
|
||||
{
|
||||
if( !windows.contains( w ))
|
||||
return;
|
||||
WindowPaintData data;
|
||||
|
||||
setPositionTransformations( data,
|
||||
windows[ w ]->thumbnail, w,
|
||||
windows[ w ]->area.adjusted( highlight_margin, highlight_margin, -highlight_margin, -highlight_margin ),
|
||||
Qt::KeepAspectRatio );
|
||||
|
||||
effects->drawWindow( w,
|
||||
Scene::PAINT_WINDOW_OPAQUE | Scene::PAINT_WINDOW_TRANSFORMED,
|
||||
windows[ w ]->thumbnail, data );
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintWindowIcon( EffectWindow* w )
|
||||
{
|
||||
if( !windows.contains( w ))
|
||||
|
@ -586,23 +584,32 @@ void BoxSwitchEffect::paintWindowIcon( EffectWindow* w )
|
|||
#ifdef HAVE_OPENGL
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
glPushMatrix();
|
||||
glPushAttrib( GL_ENABLE_BIT );
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
windows[ w ]->iconTexture.bind();
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2i( 0, 1 );
|
||||
glVertex2i( x, y );
|
||||
glTexCoord2i( 1, 1 );
|
||||
glVertex2i( x + width, y );
|
||||
glTexCoord2i( 1, 0 );
|
||||
glVertex2i( x + width, y + height );
|
||||
glTexCoord2i( 0, 0 );
|
||||
glVertex2i( x, y + height );
|
||||
glEnd();
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
int verts[ 4 * 2 ] =
|
||||
{
|
||||
x, y,
|
||||
x, y + height,
|
||||
x + width, y + height,
|
||||
x + width, y
|
||||
};
|
||||
glVertexPointer( 2, GL_INT, 0, verts );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
int texcoords[ 4 * 2 ] =
|
||||
{
|
||||
0, 1,
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1
|
||||
};
|
||||
glTexCoordPointer( 2, GL_INT, 0, texcoords );
|
||||
glDrawArrays( GL_QUADS, 0, 4 );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
windows[ w ]->iconTexture.unbind();
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -12,8 +12,8 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#define KWIN_BOXSWITCH_H
|
||||
|
||||
#include <effects.h>
|
||||
#include <scene_xrender.h>
|
||||
#include <scene_opengl.h>
|
||||
#include "scene_xrender.h"
|
||||
#include "scene_opengl.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
|
@ -52,8 +52,8 @@ class BoxSwitchEffect
|
|||
|
||||
void paintFrame();
|
||||
void paintHighlight( QRect area, QString text );
|
||||
void paintDesktopThumbnail( int iDesktop );
|
||||
void paintWindowThumbnail( EffectWindow* w );
|
||||
void paintDesktopThumbnail( int iDesktop );
|
||||
void paintWindowIcon( EffectWindow* w );
|
||||
|
||||
bool mActivated;
|
||||
|
@ -61,17 +61,16 @@ class BoxSwitchEffect
|
|||
int mMode;
|
||||
|
||||
QRect frame_area;
|
||||
int frame_margin;
|
||||
|
||||
int frame_margin; // TODO graphical background
|
||||
int highlight_margin; // TODO graphical background
|
||||
QSize item_max_size; // maximum item display size (including highlight)
|
||||
int highlight_margin; // TODO graphical background, highlight
|
||||
|
||||
QHash< int, ItemInfo* > desktops;
|
||||
QHash< EffectWindow*, ItemInfo* > windows;
|
||||
|
||||
int selected_desktop;
|
||||
ClientList tab_clients;
|
||||
ClientList original_windows;
|
||||
EffectWindow* selected_window;
|
||||
QHash< int, ItemInfo* > desktops;
|
||||
QList< int > original_desktops;
|
||||
int selected_desktop;
|
||||
|
||||
int painting_desktop;
|
||||
|
||||
|
|
296
tabbox.cpp
296
tabbox.cpp
|
@ -45,11 +45,13 @@ extern QPixmap* kwin_get_menu_pix_hack();
|
|||
|
||||
TabBox::TabBox( Workspace *ws )
|
||||
: QFrame( 0, Qt::X11BypassWindowManagerHint )
|
||||
, client(0)
|
||||
, wspace(ws)
|
||||
, client(0)
|
||||
, display_refcount( 0 )
|
||||
{
|
||||
setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
setFrameShadow(QFrame::Plain);
|
||||
setBackgroundRole(QPalette::Base);
|
||||
setLineWidth(2);
|
||||
setContentsMargins( 2, 2, 2, 2 );
|
||||
|
||||
|
@ -91,7 +93,7 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client
|
|||
Client* start = c;
|
||||
|
||||
if ( chain )
|
||||
c = workspace()->nextFocusChainClient(c);
|
||||
c = workspace()->nextClientFocusChain(c);
|
||||
else
|
||||
c = workspace()->stackingOrder().first();
|
||||
|
||||
|
@ -118,7 +120,7 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client
|
|||
}
|
||||
|
||||
if ( chain )
|
||||
c = workspace()->nextFocusChainClient( c );
|
||||
c = workspace()->nextClientFocusChain( c );
|
||||
else
|
||||
{
|
||||
if ( idx >= (workspace()->stackingOrder().size()-1) )
|
||||
|
@ -133,6 +135,30 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
Create list of desktops, starting with desktop start
|
||||
*/
|
||||
void TabBox::createDesktopList(QList< int > &list, int start, SortOrder order)
|
||||
{
|
||||
list.clear();
|
||||
|
||||
int iDesktop = start;
|
||||
|
||||
for( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
|
||||
{
|
||||
list.append( iDesktop );
|
||||
if ( order == StaticOrder )
|
||||
{
|
||||
iDesktop = workspace()->nextDesktopStatic( iDesktop );
|
||||
}
|
||||
else
|
||||
{ // MostRecentlyUsedOrder
|
||||
iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Resets the tab box to display the active client in WindowsMode, or the
|
||||
current desktop in DesktopListMode
|
||||
|
@ -158,18 +184,16 @@ void TabBox::reset( bool partial_reset )
|
|||
// get all clients to show
|
||||
createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), starting_client, true);
|
||||
|
||||
displayed_clients = clients;
|
||||
|
||||
// calculate maximum caption width
|
||||
cw = fontMetrics().width(no_tasks)+20;
|
||||
for (ClientList::ConstIterator it = displayed_clients.begin(); it != displayed_clients.end(); ++it)
|
||||
for (ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
|
||||
{
|
||||
cw = fontMetrics().width( (*it)->caption() );
|
||||
if ( cw > wmax ) wmax = cw;
|
||||
}
|
||||
|
||||
// calculate height for the popup
|
||||
if ( displayed_clients.count() == 0 ) // height for the "not tasks" text
|
||||
if ( clients.count() == 0 ) // height for the "not tasks" text
|
||||
{
|
||||
QFont f = font();
|
||||
f.setBold( true );
|
||||
|
@ -180,7 +204,7 @@ void TabBox::reset( bool partial_reset )
|
|||
else
|
||||
{
|
||||
showMiniIcon = false;
|
||||
h = displayed_clients.count() * lineHeight;
|
||||
h = clients.count() * lineHeight;
|
||||
|
||||
if ( h > (r.height()-(2*frameWidth())) ) // if too high, use mini icons
|
||||
{
|
||||
|
@ -188,33 +212,47 @@ void TabBox::reset( bool partial_reset )
|
|||
// fontheight + 1 pixel above + 1 pixel below, or 16x16 icon + 1 pixel above + below
|
||||
lineHeight = qMax(fontMetrics().height() + 2, 16 + 2);
|
||||
|
||||
h = displayed_clients.count() * lineHeight;
|
||||
h = clients.count() * lineHeight;
|
||||
|
||||
if ( h > (r.height()-(2*frameWidth())) ) // if still too high, remove some clients
|
||||
{
|
||||
// how many clients to remove
|
||||
int howMany = (h - (r.height()-(2*frameWidth())))/lineHeight;
|
||||
for (; howMany; howMany--)
|
||||
displayed_clients.removeAll(displayed_clients.last());
|
||||
clients.removeAll(clients.last());
|
||||
|
||||
h = displayed_clients.count() * lineHeight;
|
||||
h = clients.count() * lineHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // DesktopListMode
|
||||
showMiniIcon = false;
|
||||
{
|
||||
int starting_desktop;
|
||||
if( mode() == DesktopListMode )
|
||||
{
|
||||
starting_desktop = 1;
|
||||
createDesktopList(desktops, starting_desktop, StaticOrder );
|
||||
}
|
||||
else
|
||||
{ // DesktopMode
|
||||
starting_desktop = workspace()->currentDesktop();
|
||||
createDesktopList(desktops, starting_desktop, MostRecentlyUsedOrder );
|
||||
}
|
||||
|
||||
if( !partial_reset )
|
||||
desk = workspace()->currentDesktop();
|
||||
|
||||
for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
|
||||
showMiniIcon = false;
|
||||
|
||||
foreach (int it, desktops)
|
||||
{
|
||||
cw = fontMetrics().width( workspace()->desktopName(i) );
|
||||
cw = fontMetrics().width( workspace()->desktopName(it) );
|
||||
if ( cw > wmax ) wmax = cw;
|
||||
}
|
||||
|
||||
// calculate height for the popup (max. 16 desktops always fit in a 800x600 screen)
|
||||
h = workspace()->numberOfDesktops() * lineHeight;
|
||||
h = desktops.count() * lineHeight;
|
||||
}
|
||||
|
||||
// height, width for the popup
|
||||
|
@ -239,47 +277,37 @@ void TabBox::nextPrev( bool next)
|
|||
if ( mode() == WindowsMode )
|
||||
{
|
||||
Client* firstClient = 0;
|
||||
Client* newClient = client;
|
||||
do
|
||||
{
|
||||
if ( next )
|
||||
client = workspace()->nextFocusChainClient(client);
|
||||
newClient = workspace()->nextClientFocusChain(newClient);
|
||||
else
|
||||
client = workspace()->previousFocusChainClient(client);
|
||||
newClient = workspace()->previousClientFocusChain(newClient);
|
||||
if (!firstClient)
|
||||
{
|
||||
// When we see our first client for the second time,
|
||||
// it's time to stop.
|
||||
firstClient = client;
|
||||
firstClient = newClient;
|
||||
}
|
||||
else if (client == firstClient)
|
||||
else if (newClient == firstClient)
|
||||
{
|
||||
// No candidates found.
|
||||
client = 0;
|
||||
newClient = 0;
|
||||
break;
|
||||
}
|
||||
} while ( client && !clients.contains( client ));
|
||||
} while ( newClient && !clients.contains( newClient ));
|
||||
setCurrentClient( newClient );
|
||||
}
|
||||
else if( mode() == DesktopMode )
|
||||
{
|
||||
if ( next )
|
||||
desk = workspace()->nextDesktopFocusChain( desk );
|
||||
else
|
||||
desk = workspace()->previousDesktopFocusChain( desk );
|
||||
setCurrentDesktop ( next ? workspace()->nextDesktopFocusChain( desk )
|
||||
: workspace()->previousDesktopFocusChain( desk ) );
|
||||
}
|
||||
else
|
||||
{ // DesktopListMode
|
||||
if ( next )
|
||||
{
|
||||
desk++;
|
||||
if ( desk > workspace()->numberOfDesktops() )
|
||||
desk = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
desk--;
|
||||
if ( desk < 1 )
|
||||
desk = workspace()->numberOfDesktops();
|
||||
}
|
||||
setCurrentDesktop ( next ? workspace()->nextDesktopStatic( desk )
|
||||
: workspace()->previousDesktopStatic( desk )) ;
|
||||
}
|
||||
|
||||
if( effects )
|
||||
|
@ -324,11 +352,47 @@ int TabBox::currentDesktop()
|
|||
{
|
||||
if ( mode() == DesktopListMode || mode() == DesktopMode )
|
||||
return desk;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the list of desktops potentially displayed ( only works in
|
||||
DesktopListMode )
|
||||
Returns an empty list if no desktops are available.
|
||||
*/
|
||||
QList< int > TabBox::currentDesktopList()
|
||||
{
|
||||
if ( mode() == DesktopListMode || mode() == DesktopMode )
|
||||
return desktops;
|
||||
return QList< int >();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Change the currently selected client, and notify the effects.
|
||||
|
||||
\sa setCurrentDesktop()
|
||||
*/
|
||||
void TabBox::setCurrentClient( Client* newClient )
|
||||
{
|
||||
client = newClient;
|
||||
if( effects )
|
||||
effects->tabBoxUpdated();
|
||||
}
|
||||
|
||||
/*!
|
||||
Change the currently selected desktop, and notify the effects.
|
||||
|
||||
\sa setCurrentClient()
|
||||
*/
|
||||
void TabBox::setCurrentDesktop( int newDesktop )
|
||||
{
|
||||
desk = newDesktop;
|
||||
if( effects )
|
||||
effects->tabBoxUpdated();
|
||||
}
|
||||
|
||||
/*!
|
||||
Reimplemented to raise the tab box as well
|
||||
*/
|
||||
|
@ -374,7 +438,7 @@ void TabBox::paintEvent( QPaintEvent* e )
|
|||
}
|
||||
else
|
||||
{
|
||||
for (ClientList::ConstIterator it = displayed_clients.begin(); it != displayed_clients.end(); ++it)
|
||||
for (ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
|
||||
{
|
||||
if ( workspace()->hasClient( *it ) ) // safety
|
||||
{
|
||||
|
@ -458,22 +522,19 @@ void TabBox::paintEvent( QPaintEvent* e )
|
|||
QFontMetrics fm(f);
|
||||
|
||||
int wmax = 0;
|
||||
for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
|
||||
foreach (int it, desktops)
|
||||
{
|
||||
wmax = qMax(wmax, fontMetrics().width(workspace()->desktopName(i)));
|
||||
wmax = qMax(wmax, fontMetrics().width(workspace()->desktopName(it)));
|
||||
|
||||
// calculate max width of desktop-number text
|
||||
QString num = QString::number(i);
|
||||
QString num = QString::number(it);
|
||||
iconWidth = qMax(iconWidth - 4, fm.boundingRect(num).width()) + 4;
|
||||
}
|
||||
|
||||
// In DesktopMode, start at the current desktop
|
||||
// In DesktopListMode, start at desktop #1
|
||||
int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
|
||||
for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
|
||||
foreach (int it, desktops)
|
||||
{
|
||||
// draw highlight background
|
||||
if ( iDesktop == desk ) // current desktop
|
||||
if ( it == desk ) // current desktop
|
||||
p.fillRect(x, y, r.width(), lineHeight, palette().brush( QPalette::Highlight ));
|
||||
|
||||
p.save();
|
||||
|
@ -485,26 +546,26 @@ void TabBox::paintEvent( QPaintEvent* e )
|
|||
|
||||
// draw desktop-number
|
||||
p.setFont(f);
|
||||
QString num = QString::number(iDesktop);
|
||||
QString num = QString::number(it);
|
||||
p.drawText(x+5, y+2, iconWidth, iconHeight, Qt::AlignCenter, num);
|
||||
|
||||
p.restore();
|
||||
|
||||
// draw desktop name text
|
||||
if ( iDesktop == desk )
|
||||
if ( it == desk )
|
||||
p.setPen(palette().color( QPalette::HighlightedText ));
|
||||
else
|
||||
p.setPen(palette().color( QPalette::Text ));
|
||||
|
||||
p.drawText(x+5 + iconWidth + 8, y, r.width() - 5 - iconWidth - 8, lineHeight,
|
||||
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
|
||||
workspace()->desktopName(iDesktop));
|
||||
workspace()->desktopName(it));
|
||||
|
||||
// show mini icons from that desktop aligned to each other
|
||||
int x1 = x + 5 + iconWidth + 8 + wmax + 5;
|
||||
|
||||
ClientList list;
|
||||
createClientList(list, iDesktop, 0, false);
|
||||
createClientList(list, it, 0, false);
|
||||
// clients are in reversed stacking order
|
||||
for ( int i = list.size() - 1; i>=0; i-- )
|
||||
{
|
||||
|
@ -521,29 +582,38 @@ void TabBox::paintEvent( QPaintEvent* e )
|
|||
// next desktop
|
||||
y += lineHeight;
|
||||
if ( y >= r.height() ) break;
|
||||
|
||||
if( mode() == DesktopMode )
|
||||
iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
|
||||
else
|
||||
iDesktop++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Notify effects that the tab box is being shown, and only display the
|
||||
default tab box QFrame if no effect has referenced the tab box.
|
||||
*/
|
||||
void TabBox::show()
|
||||
{
|
||||
if( display_refcount > 0 )
|
||||
return;
|
||||
display_refcount = 0;
|
||||
if( effects )
|
||||
effects->tabBoxAdded( mode());
|
||||
if( display_refcount == 0 ) // no effects have claimed TabBox
|
||||
if( isDisplayed())
|
||||
return;
|
||||
refDisplay();
|
||||
QWidget::show();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Notify effects that the tab box is being hidden.
|
||||
*/
|
||||
void TabBox::hide()
|
||||
{
|
||||
delayedShowTimer.stop();
|
||||
if( isVisible())
|
||||
unrefDisplay();
|
||||
if( effects )
|
||||
effects->tabBoxClosed();
|
||||
if( isDisplayed())
|
||||
kDebug( 1212 ) << "Tab box was not properly closed by an effect" << endl;
|
||||
QWidget::hide();
|
||||
QApplication::syncX();
|
||||
XEvent otherEvent;
|
||||
|
@ -553,13 +623,12 @@ void TabBox::hide()
|
|||
|
||||
|
||||
/*!
|
||||
Reduce the reference count, eventually closing the tabbox.
|
||||
Decrease the reference count. Only when the reference count is 0 will
|
||||
the default tab box be shown.
|
||||
*/
|
||||
void TabBox::unrefTabBox()
|
||||
void TabBox::unrefDisplay()
|
||||
{
|
||||
if( --display_refcount > 0 )
|
||||
return;
|
||||
workspace()->closeTabBox();
|
||||
--display_refcount;
|
||||
}
|
||||
|
||||
void TabBox::reconfigure()
|
||||
|
@ -607,33 +676,34 @@ void TabBox::delayedShow()
|
|||
void TabBox::handleMouseEvent( XEvent* e )
|
||||
{
|
||||
XAllowEvents( display(), AsyncPointer, xTime() );
|
||||
if( display_refcount > 0 ) // tabbox has been replaced, check effects
|
||||
{
|
||||
if( effects && !effects->checkInputWindowEvent( e ) && e->type == ButtonPress )
|
||||
unrefTabBox();
|
||||
if( !isVisible() && isDisplayed())
|
||||
{ // tabbox has been replaced, check effects
|
||||
if( effects && effects->checkInputWindowEvent( e ))
|
||||
return;
|
||||
}
|
||||
if( e->type != ButtonPress )
|
||||
return;
|
||||
QPoint pos( e->xbutton.x_root, e->xbutton.y_root );
|
||||
if( !geometry().contains( pos ))
|
||||
QPoint widgetPos = mapFromGlobal( pos ); // inside tabbox
|
||||
|
||||
if(( !isVisible() && isDisplayed())
|
||||
|| !geometry().contains( pos ))
|
||||
{
|
||||
unrefTabBox(); // click outside closes tab
|
||||
workspace()->closeTabBox(); // click outside closes tab
|
||||
return;
|
||||
}
|
||||
pos.rx() -= x(); // pos is now inside tabbox
|
||||
pos.ry() -= y();
|
||||
int num = (pos.y()-frameWidth()) / lineHeight;
|
||||
|
||||
int num = (widgetPos.y()-frameWidth()) / lineHeight;
|
||||
|
||||
if( mode() == WindowsMode )
|
||||
{
|
||||
for( ClientList::ConstIterator it = displayed_clients.begin();
|
||||
it != displayed_clients.end();
|
||||
for( ClientList::ConstIterator it = clients.begin();
|
||||
it != clients.end();
|
||||
++it)
|
||||
{
|
||||
if( workspace()->hasClient( *it ) && (num == 0) ) // safety
|
||||
{
|
||||
client = *it;
|
||||
setCurrentClient( *it );
|
||||
break;
|
||||
}
|
||||
num--;
|
||||
|
@ -641,21 +711,14 @@ void TabBox::handleMouseEvent( XEvent* e )
|
|||
}
|
||||
else
|
||||
{
|
||||
int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
|
||||
for( int i = 1;
|
||||
i <= workspace()->numberOfDesktops();
|
||||
++i )
|
||||
foreach( int it, desktops )
|
||||
{
|
||||
if( num == 0 )
|
||||
{
|
||||
desk = iDesktop;
|
||||
setCurrentDesktop( it );
|
||||
break;
|
||||
}
|
||||
num--;
|
||||
if( mode() == DesktopMode )
|
||||
iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
|
||||
else
|
||||
iDesktop++;
|
||||
}
|
||||
}
|
||||
update();
|
||||
|
@ -996,7 +1059,7 @@ void Workspace::CDEWalkThroughWindows( bool forward )
|
|||
Client* firstClient = 0;
|
||||
do
|
||||
{
|
||||
nc = forward ? nextStaticClient(nc) : previousStaticClient(nc);
|
||||
nc = forward ? nextClientStatic(nc) : previousClientStatic(nc);
|
||||
if (!firstClient)
|
||||
{
|
||||
// When we see our first client for the second time,
|
||||
|
@ -1097,7 +1160,7 @@ void Workspace::tabBoxKeyPress( int keyQt )
|
|||
if ( ((keyQt & ~Qt::KeyboardModifierMask) == Qt::Key_Escape)
|
||||
&& !(forward || backward) )
|
||||
{ // if Escape is part of the shortcut, don't cancel
|
||||
unrefTabBox();
|
||||
closeTabBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1105,21 +1168,19 @@ void Workspace::tabBoxKeyPress( int keyQt )
|
|||
void Workspace::refTabBox()
|
||||
{
|
||||
if( tab_box )
|
||||
tab_box->refTabBox();
|
||||
tab_box->refDisplay();
|
||||
}
|
||||
|
||||
void Workspace::unrefTabBox()
|
||||
{
|
||||
if( tab_box )
|
||||
tab_box->unrefTabBox();
|
||||
tab_box->unrefDisplay();
|
||||
}
|
||||
|
||||
void Workspace::closeTabBox()
|
||||
{
|
||||
removeTabBoxGrab();
|
||||
tab_box->hide();
|
||||
if( effects )
|
||||
effects->tabBoxClosed();
|
||||
keys->setEnabled( true );
|
||||
disable_shortcuts_keys->setEnabled( true );
|
||||
client_keys->setEnabled( true );
|
||||
|
@ -1168,7 +1229,7 @@ void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
|
|||
if (tab_grab)
|
||||
{
|
||||
bool old_control_grab = control_grab;
|
||||
unrefTabBox();
|
||||
closeTabBox();
|
||||
control_grab = old_control_grab;
|
||||
if( Client* c = tab_box->currentClient())
|
||||
{
|
||||
|
@ -1180,7 +1241,7 @@ void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
|
|||
if (control_grab)
|
||||
{
|
||||
bool old_tab_grab = tab_grab;
|
||||
unrefTabBox();
|
||||
closeTabBox();
|
||||
tab_grab = old_tab_grab;
|
||||
if ( tab_box->currentDesktop() != -1 )
|
||||
{
|
||||
|
@ -1212,11 +1273,27 @@ int Workspace::previousDesktopFocusChain( int iDesktop ) const
|
|||
return numberOfDesktops();
|
||||
}
|
||||
|
||||
int Workspace::nextDesktopStatic( int iDesktop ) const
|
||||
{
|
||||
int i = ++iDesktop;
|
||||
if( i > numberOfDesktops())
|
||||
i = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
int Workspace::previousDesktopStatic( int iDesktop ) const
|
||||
{
|
||||
int i = --iDesktop;
|
||||
if( i < 1 )
|
||||
i = numberOfDesktops();
|
||||
return i;
|
||||
}
|
||||
|
||||
/*!
|
||||
auxiliary functions to travers all clients according the focus
|
||||
order. Useful for kwms Alt-tab feature.
|
||||
*/
|
||||
Client* Workspace::nextFocusChainClient( Client* c ) const
|
||||
Client* Workspace::nextClientFocusChain( Client* c ) const
|
||||
{
|
||||
if ( global_focus_chain.isEmpty() )
|
||||
return 0;
|
||||
|
@ -1233,7 +1310,7 @@ Client* Workspace::nextFocusChainClient( Client* c ) const
|
|||
auxiliary functions to travers all clients according the focus
|
||||
order. Useful for kwms Alt-tab feature.
|
||||
*/
|
||||
Client* Workspace::previousFocusChainClient( Client* c ) const
|
||||
Client* Workspace::previousClientFocusChain( Client* c ) const
|
||||
{
|
||||
if ( global_focus_chain.isEmpty() )
|
||||
return 0;
|
||||
|
@ -1250,7 +1327,7 @@ Client* Workspace::previousFocusChainClient( Client* c ) const
|
|||
auxiliary functions to travers all clients according the static
|
||||
order. Useful for the CDE-style Alt-tab feature.
|
||||
*/
|
||||
Client* Workspace::nextStaticClient( Client* c ) const
|
||||
Client* Workspace::nextClientStatic( Client* c ) const
|
||||
{
|
||||
if ( !c || clients.isEmpty() )
|
||||
return 0;
|
||||
|
@ -1266,7 +1343,7 @@ Client* Workspace::nextStaticClient( Client* c ) const
|
|||
auxiliary functions to travers all clients according the static
|
||||
order. Useful for the CDE-style Alt-tab feature.
|
||||
*/
|
||||
Client* Workspace::previousStaticClient( Client* c ) const
|
||||
Client* Workspace::previousClientStatic( Client* c ) const
|
||||
{
|
||||
if ( !c || clients.isEmpty() )
|
||||
return 0;
|
||||
|
@ -1300,6 +1377,25 @@ int Workspace::currentTabBoxDesktop() const
|
|||
return tab_box->currentDesktop();
|
||||
}
|
||||
|
||||
QList< int > Workspace::currentTabBoxDesktopList() const
|
||||
{
|
||||
if( !tab_box )
|
||||
return QList< int >();
|
||||
return tab_box->currentDesktopList();
|
||||
}
|
||||
|
||||
void Workspace::setTabBoxClient( Client* c )
|
||||
{
|
||||
if( tab_box )
|
||||
tab_box->setCurrentClient( c );
|
||||
}
|
||||
|
||||
void Workspace::setTabBoxDesktop( int iDesktop )
|
||||
{
|
||||
if( tab_box )
|
||||
tab_box->setCurrentDesktop( iDesktop );
|
||||
}
|
||||
|
||||
bool Workspace::establishTabBoxGrab()
|
||||
{
|
||||
if( XGrabKeyboard( display(), root, false,
|
||||
|
|
40
tabbox.h
40
tabbox.h
|
@ -34,11 +34,16 @@ class TabBox : public QFrame
|
|||
Client* currentClient();
|
||||
ClientList currentClientList();
|
||||
int currentDesktop();
|
||||
QList< int > currentDesktopList();
|
||||
|
||||
void setCurrentClient( Client* newClient );
|
||||
void setCurrentDesktop( int newDesktop );
|
||||
|
||||
// DesktopMode and WindowsMode are based on the order in which the desktop
|
||||
// or window were viewed.
|
||||
// DesktopListMode lists them in the order created.
|
||||
enum Mode { DesktopMode, DesktopListMode, WindowsMode };
|
||||
enum SortOrder { StaticOrder, MostRecentlyUsedOrder };
|
||||
void setMode( Mode mode );
|
||||
Mode mode() const;
|
||||
|
||||
|
@ -48,8 +53,9 @@ class TabBox : public QFrame
|
|||
void delayedShow();
|
||||
void hide();
|
||||
|
||||
void refTabBox();
|
||||
void unrefTabBox();
|
||||
void refDisplay();
|
||||
void unrefDisplay();
|
||||
bool isDisplayed() const;
|
||||
|
||||
void handleMouseEvent( XEvent* );
|
||||
|
||||
|
@ -68,19 +74,22 @@ class TabBox : public QFrame
|
|||
|
||||
private:
|
||||
void createClientList(ClientList &list, int desktop /*-1 = all*/, Client *start, bool chain);
|
||||
void createDesktopList(QList< int > &list, int start, SortOrder order);
|
||||
|
||||
private:
|
||||
Client* client;
|
||||
Mode m;
|
||||
Workspace* wspace;
|
||||
ClientList clients, displayed_clients;
|
||||
Mode m;
|
||||
ClientList clients;
|
||||
Client* client;
|
||||
QList< int > desktops;
|
||||
int desk;
|
||||
|
||||
QTimer delayedShowTimer;
|
||||
int display_refcount;
|
||||
QString no_tasks;
|
||||
int lineHeight;
|
||||
bool showMiniIcon;
|
||||
QTimer delayedShowTimer;
|
||||
QString no_tasks;
|
||||
bool options_traverse_all;
|
||||
int display_refcount;
|
||||
};
|
||||
|
||||
|
||||
|
@ -104,12 +113,25 @@ inline TabBox::Mode TabBox::mode() const
|
|||
|
||||
/*!
|
||||
Increase the reference count, preventing the default tabbox from showing.
|
||||
|
||||
\sa unrefDisplay(), isDisplayed()
|
||||
*/
|
||||
inline void TabBox::refTabBox()
|
||||
inline void TabBox::refDisplay()
|
||||
{
|
||||
++display_refcount;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the tab box is being displayed, either natively or by an
|
||||
effect.
|
||||
|
||||
\sa refDisplay(), unrefDisplay()
|
||||
*/
|
||||
inline bool TabBox::isDisplayed() const
|
||||
{
|
||||
return display_refcount > 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
13
workspace.h
13
workspace.h
|
@ -172,12 +172,17 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
Client* currentTabBoxClient() const;
|
||||
ClientList currentTabBoxClientList() const;
|
||||
int currentTabBoxDesktop() const;
|
||||
Client* nextFocusChainClient(Client*) const;
|
||||
Client* previousFocusChainClient(Client*) const;
|
||||
Client* nextStaticClient(Client*) const;
|
||||
Client* previousStaticClient(Client*) const;
|
||||
QList< int > currentTabBoxDesktopList() const;
|
||||
void setTabBoxClient(Client*);
|
||||
void setTabBoxDesktop(int);
|
||||
Client* nextClientFocusChain(Client*) const;
|
||||
Client* previousClientFocusChain(Client*) const;
|
||||
Client* nextClientStatic(Client*) const;
|
||||
Client* previousClientStatic(Client*) const;
|
||||
int nextDesktopFocusChain( int iDesktop ) const;
|
||||
int previousDesktopFocusChain( int iDesktop ) const;
|
||||
int nextDesktopStatic( int iDesktop ) const;
|
||||
int previousDesktopStatic( int iDesktop ) const;
|
||||
void refTabBox();
|
||||
void unrefTabBox();
|
||||
void closeTabBox();
|
||||
|
|
Loading…
Reference in a new issue