staysOnTop support.
Fixed titlebar-dblclick-commands (Shade instead of winShade ) svn path=/trunk/kdebase/kwin/; revision=54719
This commit is contained in:
parent
10658d11e0
commit
f5226e0281
7 changed files with 135 additions and 51 deletions
67
client.cpp
67
client.cpp
|
@ -76,7 +76,12 @@ public:
|
|||
m_client->maximize( Client::MaximizeHorizontal );
|
||||
else
|
||||
m_client->maximize( Client::MaximizeRestore );
|
||||
}
|
||||
}
|
||||
|
||||
if ( mask & NET::StaysOnTop ) {
|
||||
m_client->setStaysOnTop( state & NET::StaysOnTop );
|
||||
m_client->workspace()->raiseClient( m_client );
|
||||
}
|
||||
}
|
||||
private:
|
||||
::Client * m_client;
|
||||
|
@ -411,6 +416,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
passive_focus = FALSE;
|
||||
is_shape = FALSE;
|
||||
is_sticky = FALSE;
|
||||
stays_on_top = FALSE;
|
||||
may_move = TRUE;
|
||||
|
||||
getWMHints();
|
||||
|
@ -426,10 +432,17 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
|
||||
|
||||
// should we open this window on a certain desktop?
|
||||
|
||||
if ( info->desktop() )
|
||||
if ( info->desktop() == NETWinInfo::OnAllDesktops )
|
||||
setSticky( TRUE );
|
||||
else if ( info->desktop() )
|
||||
desk= info->desktop(); // window had the initial desktop property!
|
||||
|
||||
|
||||
// window wants to stay on top?
|
||||
stays_on_top = info->state() & NET::StaysOnTop;
|
||||
|
||||
|
||||
|
||||
|
||||
// if this window is transient, ensure that it is opened on the
|
||||
// same window as its parent. this is necessary when an application
|
||||
|
@ -862,7 +875,7 @@ bool Client::propertyNotify( XPropertyEvent& e )
|
|||
*/
|
||||
bool Client::clientMessage( XClientMessageEvent& e )
|
||||
{
|
||||
|
||||
|
||||
if ( e.message_type == atoms->kde_wm_change_state ) {
|
||||
if ( e.data.l[0] == IconicState && isNormal() ) {
|
||||
if ( e.data.l[1] )
|
||||
|
@ -879,7 +892,7 @@ bool Client::clientMessage( XClientMessageEvent& e )
|
|||
}
|
||||
blockAnimation = FALSE;
|
||||
} else if ( e.message_type == atoms->wm_change_state) {
|
||||
if ( e.data.l[0] == IconicState && isNormal() )
|
||||
if ( e.data.l[0] == IconicState && isNormal() )
|
||||
iconify();
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1372,16 +1385,16 @@ void Client::iconify()
|
|||
}
|
||||
Events::raise( Events::Iconify );
|
||||
setMappingState( IconicState );
|
||||
|
||||
|
||||
if ( !isTransient() )
|
||||
animateIconifyOrDeiconify( TRUE );
|
||||
hide();
|
||||
|
||||
|
||||
workspace()->iconifyOrDeiconifyTransientsOf( this );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
/*!
|
||||
Closes the window by either sending a delete_window message or
|
||||
using XKill.
|
||||
*/
|
||||
|
@ -1426,7 +1439,7 @@ void Client::maximize( MaximizeMode m)
|
|||
|
||||
if ( !geom_restore.isNull() )
|
||||
m = MaximizeRestore;
|
||||
|
||||
|
||||
if ( m != MaximizeRestore ) {
|
||||
Events::raise( Events::Maximize );
|
||||
geom_restore = geometry();
|
||||
|
@ -1451,7 +1464,7 @@ void Client::maximize( MaximizeMode m)
|
|||
);
|
||||
info->setState( NET::MaxHoriz, NET::MaxHoriz );
|
||||
break;
|
||||
|
||||
|
||||
case MaximizeRestore: {
|
||||
Events::raise( Events::UnMaximize );
|
||||
setGeometry(geom_restore);
|
||||
|
@ -1753,10 +1766,12 @@ void Client::setSticky( bool b )
|
|||
if ( is_sticky == b )
|
||||
return;
|
||||
is_sticky = b;
|
||||
if ( is_sticky )
|
||||
Events::raise( Events::Sticky );
|
||||
else
|
||||
Events::raise( Events::UnSticky );
|
||||
if ( isVisible() ) {
|
||||
if ( is_sticky )
|
||||
Events::raise( Events::Sticky );
|
||||
else
|
||||
Events::raise( Events::UnSticky );
|
||||
}
|
||||
if ( !is_sticky )
|
||||
setDesktop( workspace()->currentDesktop() );
|
||||
else
|
||||
|
@ -1766,6 +1781,20 @@ void Client::setSticky( bool b )
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
Let the window stay on top or not, depending on \a b
|
||||
|
||||
\sa Workspace::setClientOnTop()
|
||||
*/
|
||||
void Client::setStaysOnTop( bool b )
|
||||
{
|
||||
if ( b == staysOnTop() )
|
||||
return;
|
||||
stays_on_top = b;
|
||||
info->setState( b?NET::StaysOnTop:0, NET::StaysOnTop );
|
||||
}
|
||||
|
||||
|
||||
void Client::setDesktop( int desktop)
|
||||
{
|
||||
desk = desktop;
|
||||
|
@ -2208,15 +2237,15 @@ void Client::animateIconifyOrDeiconify( bool iconify)
|
|||
before = QRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() );
|
||||
after = QRect( x(), y(), width(), pm.height() );
|
||||
}
|
||||
|
||||
|
||||
lf = (after.left() - before.left())/step;
|
||||
rf = (after.right() - before.right())/step;
|
||||
tf = (after.top() - before.top())/step;
|
||||
rf = (after.right() - before.right())/step;
|
||||
tf = (after.top() - before.top())/step;
|
||||
bf = (after.bottom() - before.bottom())/step;
|
||||
|
||||
|
||||
XGrabServer( qt_xdisplay() );
|
||||
|
||||
|
||||
QRect area = before;
|
||||
QRect area2;
|
||||
QPixmap pm2;
|
||||
|
@ -2259,7 +2288,7 @@ void Client::animateIconifyOrDeiconify( bool iconify)
|
|||
} while ( t.elapsed() < step);
|
||||
if (area2 == area || need_to_clear )
|
||||
p.drawPixmap( area2.x(), area2.y(), pm2 );
|
||||
|
||||
|
||||
p.end();
|
||||
XUngrabServer( qt_xdisplay() );
|
||||
}
|
||||
|
|
12
client.h
12
client.h
|
@ -117,6 +117,8 @@ public:
|
|||
bool isSticky() const;
|
||||
void setSticky( bool );
|
||||
|
||||
bool staysOnTop() const;
|
||||
void setStaysOnTop( bool );
|
||||
|
||||
// auxiliary functions, depend on the windowType
|
||||
bool wantsTabFocus() const;
|
||||
|
@ -153,7 +155,7 @@ public:
|
|||
QCString sessionId();
|
||||
|
||||
QRect adjustedClientArea( const QRect& area ) const;
|
||||
|
||||
|
||||
public slots:
|
||||
void iconify();
|
||||
void closeWindow();
|
||||
|
@ -198,7 +200,7 @@ protected:
|
|||
virtual MousePosition mousePosition( const QPoint& ) const;
|
||||
virtual void setMouseCursor( MousePosition m );
|
||||
|
||||
|
||||
|
||||
virtual void animateIconifyOrDeiconify( bool iconify );
|
||||
virtual QPixmap animationPixmap( int w );
|
||||
|
||||
|
@ -242,6 +244,7 @@ private:
|
|||
uint shaded :1;
|
||||
uint active :1;
|
||||
uint is_sticky :1;
|
||||
uint stays_on_top : 1;
|
||||
uint is_shape :1;
|
||||
uint may_move :1;
|
||||
uint passive_focus :1;
|
||||
|
@ -343,6 +346,11 @@ inline bool Client::isSticky() const
|
|||
return is_sticky;
|
||||
}
|
||||
|
||||
inline bool Client::staysOnTop() const
|
||||
{
|
||||
return stays_on_top;
|
||||
}
|
||||
|
||||
|
||||
inline bool Client::shape() const
|
||||
{
|
||||
|
|
|
@ -161,7 +161,7 @@ void Options::reload()
|
|||
window_snap_zone = config->readNumEntry("WindowSnapZone", 10);
|
||||
|
||||
|
||||
OpTitlebarDblClick = windowOperation( config->readEntry("TitlebarDoubleClickCommand", "winShade") );
|
||||
OpTitlebarDblClick = windowOperation( config->readEntry("TitlebarDoubleClickCommand", "Shade") );
|
||||
|
||||
// Mouse bindings
|
||||
config->setGroup( "MouseBindings");
|
||||
|
|
13
options.h
13
options.h
|
@ -55,28 +55,28 @@ public:
|
|||
enum FocusPolicy { ClickToFocus, FocusFollowsMouse, FocusUnderMouse, FocusStrictlyUnderMouse };
|
||||
FocusPolicy focusPolicy;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Different Alt-Tab-Styles:
|
||||
<ul>
|
||||
|
||||
|
||||
<li> KDE - the recommended KDE style. Alt-Tab opens a nice icon
|
||||
box that makes it easy to select the window you want to tab
|
||||
to. The order automatically adjusts to the most recently used
|
||||
windows. Note that KDE style does not work with the
|
||||
FocusUnderMouse and FocusStrictlyUnderMouse focus
|
||||
policies. Choose ClickToFocus or FocusFollowsMouse instead.
|
||||
|
||||
|
||||
<li> CDE - the old-fashion CDE style. Alt-Tab cycles between
|
||||
the windows in static order. The current window gets raised,
|
||||
the previous window gets lowered.
|
||||
|
||||
|
||||
</ul>
|
||||
*/
|
||||
enum AltTabStyle { KDE, CDE };
|
||||
AltTabStyle altTabStyle;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
MoveResizeMode, either Tranparent or Opaque.
|
||||
*/
|
||||
|
@ -148,6 +148,7 @@ public:
|
|||
CloseOp,
|
||||
StickyOp,
|
||||
ShadeOp,
|
||||
StaysOnTopOp,
|
||||
OperationsOp,
|
||||
NoOp
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <qdrawutil.h>
|
||||
#include <qbitmap.h>
|
||||
#include <kdrawutil.h>
|
||||
#include <qdatetime.h>
|
||||
#include "workspace.h"
|
||||
#include "options.h"
|
||||
|
||||
|
@ -355,8 +356,6 @@ void StdClient::init()
|
|||
{
|
||||
Client::init();
|
||||
button[0]->setIconSet( miniIcon() );
|
||||
|
||||
// ### TODO transient etc.
|
||||
}
|
||||
|
||||
void StdClient::iconChange()
|
||||
|
@ -369,12 +368,25 @@ void StdClient::iconChange()
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
Indicates that the menu button has been clicked
|
||||
/*!
|
||||
Indicates that the menu button has been clicked. One press shows
|
||||
the window operation menu, a double click closes the window.
|
||||
*/
|
||||
void StdClient::menuButtonPressed()
|
||||
{
|
||||
(void ) workspace()->clientPopup( this ); //trigger the popup menu
|
||||
static QTime* t = 0;
|
||||
static StdClient* tc = 0;
|
||||
if ( !t )
|
||||
t = new QTime;
|
||||
|
||||
if ( tc != this || t->elapsed() > QApplication::doubleClickInterval() )
|
||||
button[0]->setPopup( workspace()->clientPopup( this ) );
|
||||
else {
|
||||
button[0]->setPopup( 0 );
|
||||
closeWindow();
|
||||
}
|
||||
t->start();
|
||||
tc = this;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1082,6 +1082,7 @@ QPopupMenu* Workspace::clientPopup( Client* c )
|
|||
popup->insertItem( i18n("Mi&nimize"), Options::IconifyOp );
|
||||
popup->insertItem( i18n("Ma&ximize"), Options::MaximizeOp );
|
||||
popup->insertItem( i18n("Sh&ade"), Options::ShadeOp );
|
||||
popup->insertItem( i18n("Always &On Top"), Options::StaysOnTopOp );
|
||||
|
||||
popup->insertSeparator();
|
||||
|
||||
|
@ -1119,6 +1120,10 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
|
|||
case Options::ShadeOp:
|
||||
c->setShade( !c->isShade() );
|
||||
break;
|
||||
case Options::StaysOnTopOp:
|
||||
c->setStaysOnTop( !c->staysOnTop() );
|
||||
raiseClient( c );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1450,9 +1455,9 @@ void Workspace::reconfigure()
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
Lowers the client \a c taking layers, transient windows and window
|
||||
groups into account.
|
||||
/*!
|
||||
Lowers the client \a c taking stays-on-top flags, layers,
|
||||
transient windows and window groups into account.
|
||||
*/
|
||||
void Workspace::lowerClient( Client* c, bool dropFocus )
|
||||
{
|
||||
|
@ -1489,16 +1494,18 @@ void Workspace::lowerClient( Client* c, bool dropFocus )
|
|||
stacking_order.remove(c);
|
||||
stacking_order.prepend(c);
|
||||
|
||||
Window* new_stack = new Window[ stacking_order.count()+1];
|
||||
ClientList list = constrainedStackingOrder( stacking_order );
|
||||
Window* new_stack = new Window[ list.count() + 1 ];
|
||||
int i = 0;
|
||||
Client *new_top = 0;
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
for ( ClientList::ConstIterator it = list.fromLast(); it != list.end(); --it) {
|
||||
new_stack[i++] = (*it)->winId();
|
||||
if (!new_top && (*it)->isVisible()) new_top = (*it);
|
||||
}
|
||||
XRaiseWindow(qt_xdisplay(), new_stack[0]);
|
||||
XRestackWindows(qt_xdisplay(), new_stack, i);
|
||||
delete [] new_stack;
|
||||
|
||||
propagateClients( TRUE );
|
||||
if (dropFocus && new_top) {
|
||||
requestFocus(new_top);
|
||||
|
@ -1506,9 +1513,9 @@ void Workspace::lowerClient( Client* c, bool dropFocus )
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
Raises the client \a c taking layers, transient windows and window
|
||||
groups into account.
|
||||
/*!
|
||||
Raises the client \a c taking layers, stays-on-top flags,
|
||||
transient windows and window groups into account.
|
||||
*/
|
||||
void Workspace::raiseClient( Client* c )
|
||||
{
|
||||
|
@ -1546,10 +1553,11 @@ void Workspace::raiseClient( Client* c )
|
|||
saveset.clear();
|
||||
saveset.append( c );
|
||||
raiseTransientsOf(saveset, c );
|
||||
|
||||
Window* new_stack = new Window[ stacking_order.count()+1];
|
||||
|
||||
ClientList list = constrainedStackingOrder( stacking_order );
|
||||
Window* new_stack = new Window[ list.count() + 1 ];
|
||||
int i = 0;
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
for ( ClientList::ConstIterator it = list.fromLast(); it != list.end(); --it) {
|
||||
new_stack[i++] = (*it)->winId();
|
||||
}
|
||||
XRaiseWindow(qt_xdisplay(), new_stack[0]);
|
||||
|
@ -1583,10 +1591,7 @@ void Workspace::raiseTransientsOf( ClientList& safeset, Client* c )
|
|||
void Workspace::lowerTransientsOf( ClientList& safeset, Client* c )
|
||||
{
|
||||
ClientList local = stacking_order;
|
||||
ClientList::ConstIterator it = local.fromLast();
|
||||
/* QT docu says --begin() is undefined, actually it is ==end(),
|
||||
so the usual for loops work: for(bla;it!=end()...) */
|
||||
for (; it!=local.end(); --it) {
|
||||
for ( ClientList::ConstIterator it = local.fromLast(); it!=local.end(); --it) {
|
||||
if ((*it)->transientFor() == c->window() && !safeset.contains(*it)) {
|
||||
safeset.append( *it );
|
||||
lowerTransientsOf( safeset, *it );
|
||||
|
@ -1596,6 +1601,30 @@ void Workspace::lowerTransientsOf( ClientList& safeset, Client* c )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Returns a stacking order based upon \a list that fulfills certain contained.
|
||||
|
||||
Currently it obeyes the staysOnTop flag only.
|
||||
|
||||
\sa Client::staysOnTop()
|
||||
*/
|
||||
ClientList Workspace::constrainedStackingOrder( const ClientList& list )
|
||||
{
|
||||
ClientList result;
|
||||
ClientList::ConstIterator it;
|
||||
for ( it = list.begin(); it!=list.end(); ++it) {
|
||||
if ( !(*it)->staysOnTop() )
|
||||
result.append( *it );
|
||||
}
|
||||
for ( it = list.begin(); it!=list.end(); ++it) {
|
||||
if ( (*it)->staysOnTop() )
|
||||
result.append( *it );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Puts the focus on a dummy window
|
||||
*/
|
||||
|
@ -1785,7 +1814,7 @@ bool Workspace::addSystemTrayWin( WId w )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
/*!
|
||||
Check whether \a w is a system tray window. If so, remove it from
|
||||
the respective datastructures and propagate this to the world.
|
||||
*/
|
||||
|
@ -2019,6 +2048,7 @@ void Workspace::clientPopupAboutToShow()
|
|||
return;
|
||||
popup->setItemChecked( Options::MaximizeOp, popup_client->isMaximized() );
|
||||
popup->setItemChecked( Options::ShadeOp, popup_client->isShade() );
|
||||
popup->setItemChecked( Options::StaysOnTopOp, popup_client->staysOnTop() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2552,4 +2582,5 @@ QRect Workspace::clientArea()
|
|||
return area;
|
||||
}
|
||||
|
||||
|
||||
#include "workspace.moc"
|
||||
|
|
|
@ -139,8 +139,8 @@ public:
|
|||
Client* previousClient(Client*) const;
|
||||
Client* nextStaticClient(Client*) const;
|
||||
Client* previousStaticClient(Client*) const;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Returns the list of clients sorted in stacking order, with topmost client
|
||||
* at the last position
|
||||
*/
|
||||
|
@ -223,6 +223,8 @@ private:
|
|||
void init();
|
||||
void createKeybindings();
|
||||
void freeKeyboard(bool pass);
|
||||
|
||||
ClientList constrainedStackingOrder( const ClientList& list );
|
||||
|
||||
Client* clientFactory(WId w);
|
||||
|
||||
|
@ -327,4 +329,5 @@ inline const ClientList& Workspace::stackingOrder() const
|
|||
return stacking_order;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue