Use the new windowmanager interaction API
svn path=/trunk/kdebase/kwin/; revision=52623
This commit is contained in:
parent
9b9570699b
commit
900e2e6c0b
10 changed files with 332 additions and 411 deletions
|
@ -8,10 +8,10 @@ class KWinInterface : virtual public DCOPObject
|
|||
K_DCOP
|
||||
|
||||
k_dcop:
|
||||
|
||||
virtual ASYNC cascadeDesktop() = 0;
|
||||
virtual ASYNC unclutterDesktop() = 0;
|
||||
|
||||
virtual void updateClientArea() = 0;
|
||||
virtual QRect clientArea() = 0;
|
||||
virtual QRect edgeClientArea() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@ SUBDIRS = . pics clients
|
|||
bin_PROGRAMS = kwin
|
||||
lib_LTLIBRARIES = kwin.la
|
||||
|
||||
kwin_la_SOURCES = atoms.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp plugins.cpp events.cpp KWinInterface.skel
|
||||
kwin_la_SOURCES = atoms.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp plugins.cpp events.cpp killwindow.cpp KWinInterface.skel
|
||||
kwin_la_LIBADD = $(LIB_KDEUI)
|
||||
kwin_la_LDFLAGS = $(all_libraries) -module -avoid-version
|
||||
|
||||
|
|
40
atoms.cpp
40
atoms.cpp
|
@ -15,6 +15,9 @@ Atoms::Atoms()
|
|||
Atom atoms_return[max];
|
||||
int n = 0;
|
||||
|
||||
atoms[n] = &kwin_running;
|
||||
names[n++] = (char *) "KWIN_RUNNING";
|
||||
|
||||
atoms[n] = &wm_protocols;
|
||||
names[n++] = (char *) "WM_PROTOCOLS";
|
||||
|
||||
|
@ -27,49 +30,12 @@ Atoms::Atoms()
|
|||
atoms[n] = &wm_change_state;
|
||||
names[n++] = (char *) "WM_CHANGE_STATE";
|
||||
|
||||
// compatibility
|
||||
atoms[n] = &kwm_win_icon;
|
||||
names[n++] = (char *) "KWM_WIN_ICON";
|
||||
|
||||
// compatibility
|
||||
atoms[n] = &kwm_running;
|
||||
names[n++] = (char *) "KWM_RUNNING";
|
||||
|
||||
atoms[n] = &kwm_command;
|
||||
names[n++] = (char *) "KWM_COMMAND";
|
||||
|
||||
atoms[n] = &motif_wm_hints;
|
||||
names[n++] = (char *) "_MOTIF_WM_HINTS";
|
||||
|
||||
atoms[n] = &net_number_of_desktops;
|
||||
names[n++] = (char *) "_NET_NUMBER_OF_DESKTOPS";
|
||||
|
||||
atoms[n] = &net_current_desktop;
|
||||
names[n++] = (char *) "_NET_CURRENT_DESKTOP";
|
||||
|
||||
atoms[n] = &net_active_window;
|
||||
names[n++] = (char *) "_NET_ACTIVE_WINDOW";
|
||||
|
||||
atoms[n] = &net_wm_context_help;
|
||||
names[n++] = (char *) "_NET_WM_CONTEXT_HELP";
|
||||
|
||||
atoms[n] = &net_client_list;
|
||||
names[n++] = (char *) "_NET_CLIENT_LIST";
|
||||
|
||||
atoms[n] = &net_client_list_stacking;
|
||||
names[n++] = (char *) "_NET_CLIENT_LIST_STACKING";
|
||||
|
||||
atoms[n] = &net_kde_docking_windows;
|
||||
names[n++] = (char *) "_NET_KDE_DOCKING_WINDOWS";
|
||||
|
||||
atoms[n] = &net_avoid_spec;
|
||||
names[n++] = (char *) "_NET_AVOID_SPEC";
|
||||
|
||||
// FIXME: standardize? KWIN_ prefix is deliberate so this isn't missed
|
||||
// set by kdelibs/kio/kmapnotify.c
|
||||
atoms[n] = &kwin_initial_desktop;
|
||||
names[n++] = (char *) "KWIN_INITIAL_DESKTOP"; // _NET_INITIAL_DESKTOP?
|
||||
|
||||
XInternAtoms( qt_xdisplay(), names, n, FALSE, atoms_return );
|
||||
for (int i = 0; i < n; i++ )
|
||||
*atoms[i] = atoms_return[i];
|
||||
|
|
16
atoms.h
16
atoms.h
|
@ -11,28 +11,16 @@ class Atoms {
|
|||
public:
|
||||
Atoms();
|
||||
|
||||
Atom kwin_running;
|
||||
|
||||
Atom wm_protocols;
|
||||
Atom wm_delete_window;
|
||||
Atom wm_take_focus;
|
||||
Atom wm_change_state;
|
||||
Atom kwm_win_icon; // compatibility
|
||||
Atom kwm_command; // compatibility
|
||||
Atom kwm_running;
|
||||
|
||||
Atom motif_wm_hints;
|
||||
|
||||
Atom net_number_of_desktops;
|
||||
Atom net_current_desktop;
|
||||
Atom net_active_window;
|
||||
Atom net_client_list;
|
||||
Atom net_client_list_stacking;
|
||||
Atom net_wm_context_help;
|
||||
|
||||
Atom net_kde_docking_windows;
|
||||
Atom net_avoid_spec;
|
||||
|
||||
Atom kwin_initial_desktop;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
201
client.cpp
201
client.cpp
|
@ -3,6 +3,7 @@ kwin - the KDE window manager
|
|||
|
||||
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
******************************************************************/
|
||||
#define QT_CLEAN_NAMESPACE
|
||||
#include <klocale.h>
|
||||
#include <kapp.h>
|
||||
#include <kdebug.h>
|
||||
|
@ -16,6 +17,8 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <qpainter.h>
|
||||
#include <qwhatsthis.h>
|
||||
#include <qtimer.h>
|
||||
#include <kwin.h>
|
||||
#include <netwm.h>
|
||||
#include "workspace.h"
|
||||
#include "client.h"
|
||||
#include "events.h"
|
||||
|
@ -35,6 +38,20 @@ static bool resizeVerticalDirectionFixed = FALSE;
|
|||
|
||||
static QRect* visible_bound = 0;
|
||||
|
||||
|
||||
// NET WM Protocol handler class
|
||||
class WinInfo : public NETWinInfo {
|
||||
public:
|
||||
WinInfo(Display * display, Window window,
|
||||
Window rwin, unsigned long pr )
|
||||
: NETWinInfo( display, window, rwin, pr, NET::WindowManager ) {
|
||||
}
|
||||
|
||||
void changeDesktop(CARD32 /* desktop */) { }
|
||||
void changeState(CARD32 /* state */, CARD32 /* mask */) { }
|
||||
};
|
||||
|
||||
|
||||
void Client::drawbound( const QRect& geom )
|
||||
{
|
||||
if ( visible_bound )
|
||||
|
@ -326,11 +343,19 @@ bool WindowWrapper::x11Event( XEvent * e)
|
|||
Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags f )
|
||||
: QWidget( parent, name, f | WStyle_Customize | WStyle_NoBorder )
|
||||
{
|
||||
avoid = false;
|
||||
anchor = AnchorNorth;
|
||||
|
||||
wspace = ws;
|
||||
win = w;
|
||||
|
||||
unsigned long properties =
|
||||
NET::WMDesktop |
|
||||
NET::WMState |
|
||||
NET::WMWindowType |
|
||||
NET::WMStrut |
|
||||
NET::WMName
|
||||
;
|
||||
|
||||
info = new WinInfo( qt_xdisplay(), win, qt_xrootwin(), properties );
|
||||
|
||||
XWindowAttributes attr;
|
||||
if (XGetWindowAttributes(qt_xdisplay(), win, &attr)){
|
||||
original_geometry.setRect(attr.x, attr.y, attr.width, attr.height );
|
||||
|
@ -367,33 +392,19 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
if ( mainClient()->isSticky() )
|
||||
setSticky( TRUE );
|
||||
|
||||
updateAvoidPolicy();
|
||||
|
||||
// should we open this window on a certain desktop?
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long nitems, bytes;
|
||||
long *data = 0L;
|
||||
|
||||
int status=XGetWindowProperty(qt_xdisplay(), w, atoms->kwin_initial_desktop, 0, 1L,
|
||||
False, atoms->kwin_initial_desktop, &type, &format, &nitems, &bytes,
|
||||
(unsigned char **)&data);
|
||||
if ( info->desktop() )
|
||||
desk= info->desktop(); // window had the initial desktop property!
|
||||
|
||||
if (status==Success) {
|
||||
if (nitems>0)
|
||||
desk=data[0]; // window had the initial desktop property!
|
||||
|
||||
XFree((char *)data);
|
||||
}
|
||||
|
||||
// if this window is transient, ensure that it is opened on the
|
||||
// same window as its parent. this is necessary when an application
|
||||
// starts up on a different desktop than is currently displayed
|
||||
//
|
||||
// are there any other cases we need to check?
|
||||
//
|
||||
if (transient_for != None)
|
||||
desk=KWM::desktop(transient_for);
|
||||
if ( isTransient() )
|
||||
desk = mainClient()->desktop();
|
||||
|
||||
}
|
||||
|
||||
|
@ -405,6 +416,8 @@ Client::~Client()
|
|||
releaseWindow();
|
||||
if (workspace()->activeClient() == this)
|
||||
workspace()->setEnableFocusChange(true); // Safety
|
||||
|
||||
delete info;
|
||||
}
|
||||
|
||||
|
||||
|
@ -420,12 +433,12 @@ void Client::manage( bool isMapped )
|
|||
QRect geom( original_geometry );
|
||||
bool placementDone = FALSE;
|
||||
|
||||
SessionInfo* info = workspace()->takeSessionInfo( this );
|
||||
if ( info )
|
||||
geom.setRect( info->x, info->y, info->width, info->height );
|
||||
SessionInfo* session = workspace()->takeSessionInfo( this );
|
||||
if ( session )
|
||||
geom.setRect( session->x, session->y, session->width, session->height );
|
||||
|
||||
|
||||
if ( isMapped || info )
|
||||
if ( isMapped || session )
|
||||
placementDone = TRUE;
|
||||
else {
|
||||
if ( (xSizeHint.flags & PPosition) || (xSizeHint.flags & USPosition) ) {
|
||||
|
@ -465,8 +478,8 @@ void Client::manage( bool isMapped )
|
|||
|
||||
// initial state
|
||||
int state = NormalState;
|
||||
if ( info ) {
|
||||
if ( info->iconified )
|
||||
if ( session ) {
|
||||
if ( session->iconified )
|
||||
state = IconicState;
|
||||
} else {
|
||||
// find out the initial state. Several possibilities exist
|
||||
|
@ -480,19 +493,15 @@ void Client::manage( bool isMapped )
|
|||
// initial desktop placement - note we don't clobber desk if it is
|
||||
// set to some value, in case the initial desktop code in the
|
||||
// constructor has already set a value for us
|
||||
if ( info ) {
|
||||
desk = info->desktop;
|
||||
} else if (desk<=0) {
|
||||
|
||||
if ( session ) {
|
||||
desk = session->desktop;
|
||||
} else if ( desk <= 0 ) {
|
||||
// assume window wants to be visible on the current desktop
|
||||
desk = workspace()->currentDesktop();
|
||||
|
||||
// KDE 1.x compatibility
|
||||
desk = KWM::desktop( win );
|
||||
}
|
||||
|
||||
info->setDesktop( desk );
|
||||
|
||||
// initial desktop code needs this now
|
||||
KWM::moveToDesktop( win, desk ); // KDE 1.x compatibility
|
||||
|
||||
setMappingState( state );
|
||||
if ( state == NormalState && isOnDesktop( workspace()->currentDesktop() ) ) {
|
||||
|
@ -503,11 +512,11 @@ void Client::manage( bool isMapped )
|
|||
}
|
||||
|
||||
// other settings from the previous session
|
||||
if ( info ) {
|
||||
setSticky( info->sticky );
|
||||
if ( session ) {
|
||||
setSticky( session->sticky );
|
||||
}
|
||||
|
||||
delete info;
|
||||
delete session;
|
||||
|
||||
workspace()->updateClientArea();
|
||||
}
|
||||
|
@ -530,7 +539,14 @@ void Client::getWmNormalHints()
|
|||
*/
|
||||
void Client::fetchName()
|
||||
{
|
||||
QString s = KWM::title( win );
|
||||
//#### QString s = KWM::title( win );
|
||||
QString s;
|
||||
|
||||
char* c = 0;
|
||||
if ( XFetchName( qt_xdisplay(), win, &c ) != 0 ) {
|
||||
s = QString::fromLocal8Bit( c );
|
||||
XFree( c );
|
||||
}
|
||||
|
||||
if ( s != caption() ) {
|
||||
setCaption( "" );
|
||||
|
@ -544,6 +560,8 @@ void Client::fetchName()
|
|||
s = s2;
|
||||
}
|
||||
setCaption( s );
|
||||
|
||||
info->setVisibleName( s.utf8() );
|
||||
|
||||
if ( !isWithdrawn() )
|
||||
captionChange( caption() );
|
||||
|
@ -572,6 +590,11 @@ void Client::setMappingState(int s){
|
|||
*/
|
||||
bool Client::windowEvent( XEvent * e)
|
||||
{
|
||||
|
||||
unsigned int dirty = info->event( e ); // pass through the NET stuff
|
||||
|
||||
dirty = 0; // shut up, compiler
|
||||
|
||||
switch (e->type) {
|
||||
case UnmapNotify:
|
||||
if ( e->xunmap.window == winId() ) {
|
||||
|
@ -636,8 +659,8 @@ bool Client::mapRequest( XMapRequestEvent& /* e */ )
|
|||
break;
|
||||
case NormalState:
|
||||
// only show window if we're on current desktop
|
||||
if (desk == KWM::currentDesktop())
|
||||
show(); // for safety
|
||||
if ( isOnDesktop( workspace()->currentDesktop() ) )
|
||||
show(); // for safety
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -686,7 +709,7 @@ void Client::withdraw()
|
|||
{
|
||||
Events::raise( isTransient() ? Events::TransDelete : Events::Delete );
|
||||
setMappingState( WithdrawnState );
|
||||
KWM::moveToDesktop( win, -1 ); // compatibility
|
||||
//### KWM::moveToDesktop( win, -1 ); // compatibility
|
||||
releaseWindow();
|
||||
workspace()->destroyClient( this );
|
||||
}
|
||||
|
@ -791,9 +814,6 @@ bool Client::propertyNotify( XPropertyEvent& e )
|
|||
default:
|
||||
if ( e.atom == atoms->wm_protocols )
|
||||
getWindowProtocols();
|
||||
else if ( e.atom == atoms->kwm_win_icon ) {
|
||||
getWMHints(); // for the icons
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -810,9 +830,6 @@ bool Client::clientMessage( XClientMessageEvent& e )
|
|||
if ( e.data.l[0] == IconicState && isNormal() )
|
||||
iconify();
|
||||
return TRUE;
|
||||
} else if ( e.message_type == atoms->net_active_window ) {
|
||||
workspace()->activateClient( this );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -836,6 +853,16 @@ void Client::sendSynteticConfigureNotify()
|
|||
c.height = windowWrapper()->height();
|
||||
c.border_width = 0;
|
||||
XSendEvent( qt_xdisplay(), c.event, TRUE, NoEventMask, (XEvent*)&c );
|
||||
|
||||
// inform clients about the frame geometry
|
||||
NETStrut strut;
|
||||
QRect wr = windowWrapper()->geometry();
|
||||
QRect mr = rect();
|
||||
strut.left = wr.left();
|
||||
strut.right = mr.right() - wr.right();
|
||||
strut.top = wr.top();
|
||||
strut.bottom = mr.bottom() - wr.bottom();
|
||||
info->setKDEFrameStrut( strut );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1066,7 +1093,7 @@ void Client::mouseMoveEvent( QMouseEvent * e)
|
|||
geom.moveTopLeft( pp );
|
||||
break;
|
||||
default:
|
||||
//fprintf(stderr, "KWin::mouseMoveEvent with mode = %d\n", mode);
|
||||
//fprintf(stderr, "KWin::mouseMoveEvent with mode = %d\n", mode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1654,6 +1681,8 @@ void Client::setSticky( bool b )
|
|||
Events::raise( Events::UnSticky );
|
||||
if ( !is_sticky )
|
||||
setDesktop( workspace()->currentDesktop() );
|
||||
else
|
||||
info->setDesktop( NETWinInfo::OnAllDesktops );
|
||||
workspace()->setStickyTransientsOf( this, b );
|
||||
stickyChange( is_sticky );
|
||||
}
|
||||
|
@ -1661,16 +1690,15 @@ void Client::setSticky( bool b )
|
|||
|
||||
void Client::setDesktop( int desktop)
|
||||
{
|
||||
if ( isOnDesktop( desktop ) )
|
||||
return;
|
||||
desk = desktop;
|
||||
KWM::moveToDesktop( win, desk );//##### compatibility
|
||||
info->setDesktop( desktop );
|
||||
}
|
||||
|
||||
void Client::getWMHints()
|
||||
{
|
||||
icon_pix = KWM::icon( win, 32, 32 ); // TODO sizes from workspace
|
||||
miniicon_pix = KWM::miniIcon( win, 16, 16 );
|
||||
// get the icons, allow scaling
|
||||
icon_pix = KWin::icon( win, 32, 32, TRUE );
|
||||
miniicon_pix = KWin::icon( win, 16, 16, TRUE );
|
||||
if ( !isWithdrawn() )
|
||||
iconChange();
|
||||
|
||||
|
@ -2016,58 +2044,22 @@ void Client::activateLayout()
|
|||
layout()->activate();
|
||||
}
|
||||
|
||||
void Client::updateAvoidPolicy()
|
||||
QRect Client::adjustedClientArea( const QRect& area ) const
|
||||
{
|
||||
avoid = false;
|
||||
|
||||
// Find out if we should be avoided.
|
||||
XTextProperty avoidProp;
|
||||
if ( XGetTextProperty(
|
||||
qt_xdisplay(),
|
||||
win,
|
||||
&avoidProp,
|
||||
atoms->net_avoid_spec
|
||||
) == 0 )
|
||||
return;
|
||||
|
||||
char ** avoidList;
|
||||
int avoidListCount;
|
||||
|
||||
if ( XTextPropertyToStringList(
|
||||
&avoidProp, &avoidList, &avoidListCount) == 0 ) {
|
||||
kdDebug() << "kwin: Client::updateAvoidPolicy: " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Must be one value only in string list.
|
||||
if (avoidListCount != 1) {
|
||||
kdDebug() << "kwin: Client::updateAvoidPolicy(): " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Which border is the client anchored to ?
|
||||
avoid = true;
|
||||
switch (avoidList[0][0]) {
|
||||
case 'N':
|
||||
anchor = AnchorNorth;
|
||||
break;
|
||||
case 'S':
|
||||
anchor = AnchorSouth;
|
||||
break;
|
||||
case 'E':
|
||||
anchor = AnchorEast;
|
||||
break;
|
||||
case 'W':
|
||||
anchor = AnchorWest;
|
||||
break;
|
||||
default:
|
||||
avoid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
XFreeStringList(avoidList);
|
||||
QRect r = area;
|
||||
NETStrut strut = info->strut();
|
||||
if ( strut.left > 0 )
|
||||
r.setLeft( r.left() + (int) strut.left );
|
||||
if ( strut.top > 0 )
|
||||
r.setTop( r.top() + (int) strut.top );
|
||||
if ( strut.right > 0 )
|
||||
r.setRight( r.right() - (int) strut.right );
|
||||
if ( strut.bottom > 0 )
|
||||
r.setBottom( r.bottom() - (int) strut.bottom );
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
NoBorderClient::NoBorderClient( Workspace *ws, WId w, QWidget *parent, const char *name )
|
||||
: Client( ws, w, parent, name )
|
||||
{
|
||||
|
@ -2079,3 +2071,4 @@ NoBorderClient::~NoBorderClient()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
|
|
11
client.h
11
client.h
|
@ -7,7 +7,6 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#define CLIENT_H
|
||||
|
||||
#include "options.h"
|
||||
#include <kwm.h>
|
||||
#include <qframe.h>
|
||||
#include <qvbox.h>
|
||||
#include <qpixmap.h>
|
||||
|
@ -18,6 +17,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
|
||||
class Workspace;
|
||||
class Client;
|
||||
class WinInfo;
|
||||
|
||||
class WindowWrapper : public QWidget
|
||||
{
|
||||
|
@ -70,10 +70,6 @@ public:
|
|||
bool isTransient() const;
|
||||
Client* mainClient();
|
||||
|
||||
void updateAvoidPolicy();
|
||||
bool isAvoid() const { return avoid; }
|
||||
int anchorEdge() const { return anchor; }
|
||||
|
||||
virtual bool windowEvent( XEvent * );
|
||||
|
||||
void manage( bool isMapped = FALSE );
|
||||
|
@ -159,6 +155,8 @@ public:
|
|||
|
||||
QCString windowRole();
|
||||
QCString sessionId();
|
||||
|
||||
QRect adjustedClientArea( const QRect& area ) const;
|
||||
|
||||
public slots:
|
||||
void iconify();
|
||||
|
@ -257,9 +255,8 @@ private:
|
|||
QPixmap miniicon_pix;
|
||||
QRect geom_restore;
|
||||
QRegion mask;
|
||||
WinInfo* info;
|
||||
|
||||
bool avoid;
|
||||
int anchor;
|
||||
};
|
||||
|
||||
inline WId Client::window() const
|
||||
|
|
9
main.cpp
9
main.cpp
|
@ -7,6 +7,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
// X11/Qt conflict
|
||||
#undef Bool
|
||||
|
||||
#define QT_CLEAN_NAMESPACE
|
||||
#include <kconfig.h>
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
|
@ -22,11 +23,11 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#define INT8 _X11INT8
|
||||
#define INT32 _X11INT32
|
||||
// #define INT8 _X11INT8
|
||||
// #define INT32 _X11INT32
|
||||
#include <X11/Xproto.h>
|
||||
#undef INT8
|
||||
#undef INT32
|
||||
// #undef INT8
|
||||
// #undef INT32
|
||||
|
||||
#include <kcmdlineargs.h>
|
||||
#include <kaboutdata.h>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/*****************************************************************
|
||||
kwin - the KDE window manager
|
||||
|
||||
|
||||
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
******************************************************************/
|
||||
#define QT_CLEAN_NAMESPACE
|
||||
#include "tabbox.h"
|
||||
#include "workspace.h"
|
||||
#include "client.h"
|
||||
|
@ -103,7 +104,7 @@ void TabBox::nextPrev( bool next)
|
|||
else
|
||||
client = workspace()->previousClient(client);
|
||||
if (!firstClient) {
|
||||
// When we see our first client for the second time,
|
||||
// When we see our first client for the second time,
|
||||
// it's time to stop.
|
||||
firstClient = client;
|
||||
}
|
||||
|
@ -210,7 +211,7 @@ void TabBox::paintContents()
|
|||
if ( currentClient() ) {
|
||||
QString s;
|
||||
if (!client->isOnDesktop(workspace()->currentDesktop())){
|
||||
s = KWM::desktopName(client->desktop());
|
||||
//### s = KWM::desktopName(client->desktop());
|
||||
s.append(": ");
|
||||
}
|
||||
|
||||
|
|
420
workspace.cpp
420
workspace.cpp
|
@ -3,6 +3,7 @@ kwin - the KDE window manager
|
|||
|
||||
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
******************************************************************/
|
||||
#define QT_CLEAN_NAMESPACE
|
||||
#include <kconfig.h>
|
||||
#include <kglobal.h>
|
||||
#include <kglobalsettings.h>
|
||||
|
@ -15,6 +16,8 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <dcopclient.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <netwm.h>
|
||||
|
||||
#include "workspace.h"
|
||||
#include "client.h"
|
||||
#include "stdclient.h"
|
||||
|
@ -22,6 +25,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include "atoms.h"
|
||||
#include "plugins.h"
|
||||
#include "events.h"
|
||||
#include "killwindow.h"
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
@ -38,6 +42,41 @@ const int XIconicState = IconicState;
|
|||
#include <kwin.h>
|
||||
#include <kapp.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// NET WM Protocol handler class
|
||||
class RootInfo : public NETRootInfo
|
||||
{
|
||||
public:
|
||||
RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr, int scr= -1)
|
||||
: NETRootInfo( dpy, w, name, pr, scr ) {
|
||||
workspace = ws;
|
||||
}
|
||||
~RootInfo() {}
|
||||
|
||||
void changeNumberOfDesktops(CARD32 n) { workspace->setNumberOfDesktops( n ); }
|
||||
void changeCurrentDesktop(CARD32 d) { workspace->setCurrentDesktop( d ); }
|
||||
void changeActiveWindow(Window w) {
|
||||
::Client* c = workspace->findClient( (WId) w );
|
||||
if ( c )
|
||||
workspace->activateClient( c );
|
||||
}
|
||||
void closeWindow(Window w) {
|
||||
::Client* c = workspace->findClient( (WId) w );
|
||||
if ( c ) {
|
||||
c->closeWindow();
|
||||
}
|
||||
}
|
||||
void moveResize(Window, int, int, unsigned long) { }
|
||||
|
||||
private:
|
||||
Workspace* workspace;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern Time kwin_time;
|
||||
|
||||
// used to store the return values of
|
||||
|
@ -48,15 +87,15 @@ static int kwin_shape_event = 0;
|
|||
static bool block_focus = FALSE;
|
||||
// does the window w need a shape combine mask around it?
|
||||
bool Shape::hasShape( WId w){
|
||||
int xws, yws, xbs, ybs;
|
||||
unsigned wws, hws, wbs, hbs;
|
||||
int boundingShaped, clipShaped;
|
||||
if (!kwin_has_shape)
|
||||
return FALSE;
|
||||
XShapeQueryExtents(qt_xdisplay(), w,
|
||||
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||
return boundingShaped != 0;
|
||||
int xws, yws, xbs, ybs;
|
||||
unsigned wws, hws, wbs, hbs;
|
||||
int boundingShaped, clipShaped;
|
||||
if (!kwin_has_shape)
|
||||
return FALSE;
|
||||
XShapeQueryExtents(qt_xdisplay(), w,
|
||||
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||
return boundingShaped != 0;
|
||||
}
|
||||
|
||||
int Shape::shapeEvent()
|
||||
|
@ -106,7 +145,7 @@ static void updateTime()
|
|||
if ( !w )
|
||||
w = new QWidget;
|
||||
long data = 1;
|
||||
XChangeProperty(qt_xdisplay(), w->winId(), atoms->kwm_running, atoms->kwm_running, 32,
|
||||
XChangeProperty(qt_xdisplay(), w->winId(), atoms->kwin_running, atoms->kwin_running, 32,
|
||||
PropModeAppend, (unsigned char*) &data, 1);
|
||||
XEvent ev;
|
||||
XWindowEvent( qt_xdisplay(), w->winId(), PropertyChangeMask, &ev );
|
||||
|
@ -118,36 +157,43 @@ Client* Workspace::clientFactory( Workspace *ws, WId w )
|
|||
if ( Motif::noBorder( w ) )
|
||||
return new NoBorderClient( ws, w );
|
||||
|
||||
NETWinInfo ni( qt_xdisplay(), w, root, NET::WMWindowType );
|
||||
|
||||
// hack TODO hints
|
||||
QString s = KWM::title( w );
|
||||
if ( s == "THE DESKTOP" ) {
|
||||
switch ( ni.windowType() ) {
|
||||
case NET::Desktop: {
|
||||
XLowerWindow( qt_xdisplay(), w );
|
||||
Client * c = new NoBorderClient( ws, w);
|
||||
c->setSticky( TRUE );
|
||||
c->setMayMove( FALSE );
|
||||
ws->setDesktopClient( c );
|
||||
c->setPassiveFocus( TRUE );
|
||||
c->setPassiveFocus( TRUE );
|
||||
return c;
|
||||
}
|
||||
if ( s.lower().right(6) == "kicker" ) {
|
||||
|
||||
case NET::Dock: {
|
||||
Client * c = new NoBorderClient( ws, w);
|
||||
c->setSticky( TRUE );
|
||||
c->setMayMove( FALSE );
|
||||
c->setPassiveFocus( TRUE );
|
||||
c->setPassiveFocus( TRUE );
|
||||
return c;
|
||||
}
|
||||
if ( s == "MAC MENU [menu]" ) {
|
||||
|
||||
case NET::Menu: {
|
||||
Client * c = new NoBorderClient( ws, w);
|
||||
c->setSticky( TRUE );
|
||||
c->setMayMove( FALSE );
|
||||
c->setPassiveFocus( TRUE );
|
||||
c->setPassiveFocus( TRUE );
|
||||
return c;
|
||||
}
|
||||
if ( ( s.right(6) == "[menu]" ) || ( s.right(7) == "[tools]" ) ) {
|
||||
|
||||
case NET::Toolbar: {
|
||||
Client * c = new NoBorderClient( ws, w);
|
||||
return c;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Shape::hasShape( w ) ){
|
||||
return new NoBorderClient( ws, w );
|
||||
|
@ -179,8 +225,7 @@ Workspace::Workspace( bool restore )
|
|||
root = qt_xrootwin();
|
||||
session.setAutoDelete( TRUE );
|
||||
|
||||
clientArea_ = QApplication::desktop()->geometry();
|
||||
edgeClientArea_ = QApplication::desktop()->geometry();
|
||||
area = QApplication::desktop()->geometry();
|
||||
|
||||
if ( restore )
|
||||
loadSessionInfo();
|
||||
|
@ -213,8 +258,8 @@ Workspace::Workspace( bool restore )
|
|||
XChangeProperty(
|
||||
qt_xdisplay(),
|
||||
qt_xrootwin(),
|
||||
atoms->kwm_running,
|
||||
atoms->kwm_running,
|
||||
atoms->kwin_running,
|
||||
atoms->kwin_running,
|
||||
32,
|
||||
PropModeAppend,
|
||||
(unsigned char*) &data,
|
||||
|
@ -234,6 +279,32 @@ Workspace::Workspace( bool restore )
|
|||
|
||||
void Workspace::init()
|
||||
{
|
||||
supportWindow = new QWidget;
|
||||
|
||||
unsigned long protocols =
|
||||
NET::Supported |
|
||||
NET::SupportingWMCheck |
|
||||
NET::ClientList |
|
||||
NET::ClientListStacking |
|
||||
NET::NumberOfDesktops |
|
||||
NET::CurrentDesktop |
|
||||
NET::ActiveWindow |
|
||||
NET::WorkArea |
|
||||
NET::CloseWindow |
|
||||
|
||||
NET::WMName |
|
||||
NET::WMDesktop |
|
||||
NET::WMWindowType |
|
||||
NET::WMState |
|
||||
NET::WMStrut |
|
||||
NET::WMIconGeometry |
|
||||
NET::WMIcon |
|
||||
NET::WMPid |
|
||||
NET::WMKDEDockWinFor
|
||||
;
|
||||
|
||||
rootInfo = new RootInfo( this, qt_xdisplay(), supportWindow->winId(), "KWin", protocols, qt_xscreen() );
|
||||
|
||||
KConfig* config = KGlobal::config();
|
||||
config->setGroup("Desktops");
|
||||
if (!config->hasKey("NumberOfDesktops"))
|
||||
|
@ -308,8 +379,11 @@ Workspace::~Workspace()
|
|||
delete popup;
|
||||
delete keys;
|
||||
if ( root == qt_xrootwin() )
|
||||
XDeleteProperty(qt_xdisplay(), qt_xrootwin(), atoms->kwm_running);
|
||||
XDeleteProperty(qt_xdisplay(), qt_xrootwin(), atoms->kwin_running);
|
||||
KGlobal::config()->sync();
|
||||
|
||||
delete rootInfo;
|
||||
delete supportWindow;
|
||||
}
|
||||
|
||||
|
||||
|
@ -342,8 +416,8 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
return c->windowEvent( e );
|
||||
|
||||
// check for dock windows
|
||||
if ( removeDockwin( e->xunmap.window ) )
|
||||
return TRUE;
|
||||
if ( removeDockwin( e->xunmap.window ) )
|
||||
return TRUE;
|
||||
|
||||
if ( e->xunmap.event == root ) {
|
||||
// keep track of map/unmap for own own windows to avoid
|
||||
|
@ -365,8 +439,9 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
}
|
||||
case ReparentNotify:
|
||||
c = findClient( e->xreparent.window );
|
||||
if ( c )
|
||||
if ( c )
|
||||
(void) c->windowEvent( e );
|
||||
|
||||
//do not confuse Qt with these events. After all, _we_ are the
|
||||
//window manager who does the reparenting.
|
||||
return TRUE;
|
||||
|
@ -459,8 +534,9 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
break;
|
||||
case FocusOut:
|
||||
break;
|
||||
case PropertyNotify:
|
||||
case ClientMessage:
|
||||
return clientMessage(e->xclient);
|
||||
return netCheck( e );
|
||||
break;
|
||||
default:
|
||||
if ( e->type == Shape::shapeEvent() ) {
|
||||
|
@ -847,11 +923,8 @@ void Workspace::setActiveClient( Client* c )
|
|||
if ( c->wantsTabFocus() )
|
||||
focus_chain.append( c );
|
||||
}
|
||||
WId w = active_client? active_client->window() : 0;
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_active_window, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)&w, 1);
|
||||
|
||||
|
||||
rootInfo->setActiveWindow( active_client? active_client->window() : 0 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1340,7 +1413,7 @@ void Workspace::cascadePlacement (Client* c, bool re_init) {
|
|||
cci[d].pos = QPoint( xp + delta_x, yp + delta_y );
|
||||
}
|
||||
|
||||
void Workspace::deskCleanup(CleanupType ct)
|
||||
void Workspace::cascadeDesktop()
|
||||
{
|
||||
ClientList::Iterator it(clients.fromLast());
|
||||
for (; it != clients.end(); --it) {
|
||||
|
@ -1349,14 +1422,25 @@ void Workspace::deskCleanup(CleanupType ct)
|
|||
((*it)->isSticky()) ||
|
||||
(!(*it)->mayMove()) )
|
||||
continue;
|
||||
|
||||
if (ct == Cascade)
|
||||
cascadePlacement(*it);
|
||||
else if (ct == Unclutter)
|
||||
smartPlacement(*it);
|
||||
cascadePlacement(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::unclutterDesktop()
|
||||
{
|
||||
ClientList::Iterator it(clients.fromLast());
|
||||
for (; it != clients.end(); --it) {
|
||||
if((!(*it)->isOnDesktop(currentDesktop())) ||
|
||||
((*it)->isIconified()) ||
|
||||
((*it)->isSticky()) ||
|
||||
(!(*it)->mayMove()) )
|
||||
continue;
|
||||
smartPlacement(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Lowers the client \a c taking layers, transient windows and window
|
||||
groups into account.
|
||||
|
@ -1545,63 +1629,59 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
block_focus = TRUE;
|
||||
|
||||
if (new_desktop != current_desktop) {
|
||||
/*
|
||||
/*
|
||||
optimized Desktop switching: unmapping done from back to front
|
||||
mapping done from front to back => less exposure events
|
||||
*/
|
||||
|
||||
for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
|
||||
if ( (*it)->isVisible() && !(*it)->isOnDesktop( new_desktop ) ) {
|
||||
(*it)->hide();
|
||||
}
|
||||
}
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
if ( (*it)->isOnDesktop( new_desktop ) && !(*it)->isIconified() ) {
|
||||
(*it)->show();
|
||||
}
|
||||
}
|
||||
for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
|
||||
if ( (*it)->isVisible() && !(*it)->isOnDesktop( new_desktop ) ) {
|
||||
(*it)->hide();
|
||||
}
|
||||
}
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
if ( (*it)->isOnDesktop( new_desktop ) && !(*it)->isIconified() ) {
|
||||
(*it)->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
current_desktop = new_desktop;
|
||||
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_current_desktop, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)¤t_desktop, 1);
|
||||
|
||||
rootInfo->setCurrentDesktop( current_desktop );
|
||||
|
||||
// restore the focus on this desktop
|
||||
block_focus = FALSE;
|
||||
Client* c = 0;
|
||||
|
||||
if ( options->focusPolicyIsReasonable()) {
|
||||
if (options->focusPolicy == Options::FocusFollowsMouse) {
|
||||
// Search in focus chain
|
||||
for( ClientList::ConstIterator it = focus_chain.fromLast(); it != focus_chain.end(); --it) {
|
||||
if ( (*it)->isVisible() && !(*it)->passiveFocus() ) {
|
||||
c = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options->focusPolicy == Options::FocusFollowsMouse) {
|
||||
// Search in focus chain
|
||||
for( ClientList::ConstIterator it = focus_chain.fromLast(); it != focus_chain.end(); --it) {
|
||||
if ( (*it)->isVisible() && !(*it)->passiveFocus() ) {
|
||||
c = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
// Search top-most visible window
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
if ( (*it)->isVisible() && !(*it)->passiveFocus() ) {
|
||||
c = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
// Search top-most visible window
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
if ( (*it)->isVisible() && !(*it)->passiveFocus() ) {
|
||||
c = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( c )
|
||||
requestFocus( c );
|
||||
requestFocus( c );
|
||||
else
|
||||
focusToNull();
|
||||
focusToNull();
|
||||
|
||||
QApplication::syncX();
|
||||
KWM::switchToDesktop( current_desktop ); // ### compatibility
|
||||
}
|
||||
|
||||
|
||||
|
@ -1619,36 +1699,18 @@ void Workspace::setNumberOfDesktops( int n )
|
|||
if ( n == number_of_desktops )
|
||||
return;
|
||||
number_of_desktops = n;
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_number_of_desktops, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)&number_of_desktops, 1);
|
||||
rootInfo->setNumberOfDesktops( number_of_desktops );
|
||||
}
|
||||
|
||||
/*!
|
||||
Handles client messages sent to the workspace
|
||||
*/
|
||||
bool Workspace::clientMessage( XClientMessageEvent msg )
|
||||
bool Workspace::netCheck( XEvent* e )
|
||||
{
|
||||
if ( msg.message_type == atoms->net_current_desktop ) {
|
||||
setCurrentDesktop( msg.data.l[0] );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (msg.message_type == atoms->kwm_command) {
|
||||
char c[21];
|
||||
int i;
|
||||
for (i=0;i<20;i++)
|
||||
c[i] = msg.data.b[i];
|
||||
c[i] = '\0';
|
||||
QString com = c;
|
||||
if (com == "deskUnclutter") {
|
||||
deskCleanup(Unclutter);
|
||||
} else if (com == "deskCascade") {
|
||||
deskCleanup(Cascade);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned int dirty = rootInfo->event( e );
|
||||
|
||||
dirty = 0; // shut up, compiler
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1665,9 +1727,7 @@ void Workspace::propagateClients( bool onlyStacking )
|
|||
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it ) {
|
||||
cl[i++] = (*it)->window();
|
||||
}
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_client_list, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)cl, clients.count());
|
||||
rootInfo->setClientList( (Window*) cl, i );
|
||||
delete [] cl;
|
||||
}
|
||||
|
||||
|
@ -1676,9 +1736,7 @@ void Workspace::propagateClients( bool onlyStacking )
|
|||
for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
|
||||
cl[i++] = (*it)->window();
|
||||
}
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_client_list_stacking, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)cl, stacking_order.count());
|
||||
rootInfo->setClientListStacking( (Window*) cl, i );
|
||||
delete [] cl;
|
||||
}
|
||||
|
||||
|
@ -1690,13 +1748,18 @@ void Workspace::propagateClients( bool onlyStacking )
|
|||
*/
|
||||
bool Workspace::addDockwin( WId w )
|
||||
{
|
||||
WId dockFor = 0;
|
||||
if ( !KWin::isDockWindow( w, &dockFor ) )
|
||||
return FALSE;
|
||||
if ( dockwins.contains( w ) )
|
||||
return TRUE;
|
||||
|
||||
NETWinInfo ni( qt_xdisplay(), w, root, NET::WMKDEDockWinFor );
|
||||
WId dockFor = ni.kdeDockWinFor();
|
||||
if ( !dockFor )
|
||||
return FALSE;
|
||||
dockwins.append( DockWindow( w, dockFor ) );
|
||||
XSelectInput( qt_xdisplay(), w,
|
||||
StructureNotifyMask
|
||||
);
|
||||
XAddToSaveSet( qt_xdisplay(), w );
|
||||
propagateDockwins();
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1739,9 +1802,8 @@ void Workspace::propagateDockwins()
|
|||
for ( DockWindowList::ConstIterator it = dockwins.begin(); it != dockwins.end(); ++it ) {
|
||||
cl[i++] = (*it).dockWin;
|
||||
}
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_kde_docking_windows, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)cl, dockwins.count());
|
||||
|
||||
rootInfo->setKDEDockingWindows( (Window*) cl, i );
|
||||
delete [] cl;
|
||||
}
|
||||
|
||||
|
@ -1871,70 +1933,20 @@ void Workspace::slotLogout()
|
|||
kapp->requestShutDown();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Kill Window feature, similar to xkill
|
||||
*/
|
||||
void Workspace::slotKillWindow()
|
||||
{
|
||||
static Cursor kill_cursor = 0;
|
||||
if (!kill_cursor)
|
||||
kill_cursor = XCreateFontCursor(qt_xdisplay(), XC_pirate);
|
||||
|
||||
if (XGrabPointer(qt_xdisplay(), qt_xrootwin(), False,
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
EnterWindowMask | LeaveWindowMask,
|
||||
GrabModeAsync, GrabModeAsync, None,
|
||||
kill_cursor, CurrentTime) == GrabSuccess)
|
||||
{
|
||||
XGrabKeyboard(qt_xdisplay(), qt_xrootwin(), False,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
XEvent ev;
|
||||
int return_pressed = 0;
|
||||
int escape_pressed = 0;
|
||||
int button_released = 0;
|
||||
|
||||
XGrabServer(qt_xdisplay());
|
||||
|
||||
while (!return_pressed && !escape_pressed && !button_released)
|
||||
{
|
||||
XMaskEvent(qt_xdisplay(), KeyPressMask | ButtonPressMask |
|
||||
ButtonReleaseMask | PointerMotionMask, &ev);
|
||||
|
||||
if (ev.type == KeyPress)
|
||||
{
|
||||
int kc = XKeycodeToKeysym(qt_xdisplay(), ev.xkey.keycode, 0);
|
||||
int mx = 0;
|
||||
int my = 0;
|
||||
return_pressed = (kc == XK_Return) || (kc == XK_space);
|
||||
escape_pressed = (kc == XK_Escape);
|
||||
if (kc == XK_Left) mx = -10;
|
||||
if (kc == XK_Right) mx = 10;
|
||||
if (kc == XK_Up) my = -10;
|
||||
if (kc == XK_Down) my = 10;
|
||||
if (ev.xkey.state & ControlMask)
|
||||
{
|
||||
mx /= 10;
|
||||
my /= 10;
|
||||
}
|
||||
QCursor::setPos(QCursor::pos()+QPoint(mx, my));
|
||||
}
|
||||
|
||||
if (ev.type == ButtonRelease)
|
||||
{
|
||||
button_released = (ev.xbutton.button == Button1);
|
||||
killWindowAtPosition(ev.xbutton.x_root, ev.xbutton.y_root);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (return_pressed)
|
||||
killWindowAtPosition(QCursor::pos().x(), QCursor::pos().y());
|
||||
|
||||
XUngrabServer(qt_xdisplay());
|
||||
|
||||
XUngrabKeyboard(qt_xdisplay(), CurrentTime);
|
||||
XUngrabPointer(qt_xdisplay(), CurrentTime);
|
||||
}
|
||||
KillWindow kill( this );
|
||||
kill.start();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Kills the window at position \a x, \a y
|
||||
*/
|
||||
void Workspace::killWindowAtPosition(int x, int y)
|
||||
{
|
||||
ClientList::ConstIterator it(stacking_order.fromLast());
|
||||
|
@ -2346,61 +2358,27 @@ SessionInfo* Workspace::takeSessionInfo( Client* c )
|
|||
|
||||
void Workspace::updateClientArea()
|
||||
{
|
||||
QRect area = QApplication::desktop()->geometry();
|
||||
QRect edgeArea = QApplication::desktop()->geometry();
|
||||
|
||||
for (ClientList::ConstIterator it(clients.begin()); it != clients.end(); ++it) {
|
||||
(*it)->updateAvoidPolicy();
|
||||
|
||||
if ((*it)->isAvoid() ) {
|
||||
switch (AnchorEdge((*it)->anchorEdge())) {
|
||||
|
||||
case AnchorNorth:
|
||||
area.setTop(QMAX(area.top(), (*it)->geometry().bottom()));
|
||||
break;
|
||||
|
||||
case AnchorSouth:
|
||||
area.setBottom(QMIN(area.bottom(), (*it)->geometry().top() - 1));
|
||||
break;
|
||||
|
||||
case AnchorEast:
|
||||
area.setRight(QMIN(area.right(), (*it)->geometry().left() - 1));
|
||||
break;
|
||||
|
||||
case AnchorWest:
|
||||
area.setLeft(QMAX(area.left(), (*it)->geometry().right()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Using the hackish method...
|
||||
if (KWM::title((*it)->winId()) == "MAC MENU [menu]")
|
||||
edgeArea.setTop((*it)->geometry().bottom());
|
||||
QRect all = QApplication::desktop()->geometry();
|
||||
QRect a = all;
|
||||
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it) {
|
||||
a = a.intersect( (*it)->adjustedClientArea( all ) );
|
||||
}
|
||||
|
||||
edgeClientArea_ = edgeArea;
|
||||
|
||||
if ( clientArea_ != area ) {
|
||||
// something changed, remember it and notify kdesktop
|
||||
clientArea_ = area;
|
||||
|
||||
QByteArray data;
|
||||
QDataStream arg( data, IO_WriteOnly );
|
||||
arg << clientArea_;
|
||||
kapp->dcopClient()->send("kdesktop", "KDesktopIface", "clientAreaUpdated(QRect)", data);
|
||||
if ( area != a ) {
|
||||
area = a;
|
||||
NETRect r;
|
||||
r.pos.x = area.x();
|
||||
r.pos.y = area.y();
|
||||
r.size.width = area.width();
|
||||
r.size.height = area.height();
|
||||
for( int i = 0; i < numberOfDesktops(); i++) {
|
||||
rootInfo->setWorkArea( i, r );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QRect Workspace::clientArea()
|
||||
{
|
||||
return clientArea_;
|
||||
}
|
||||
|
||||
QRect Workspace::edgeClientArea()
|
||||
{
|
||||
return edgeClientArea_;
|
||||
return area;
|
||||
}
|
||||
|
||||
|
|
31
workspace.h
31
workspace.h
|
@ -12,21 +12,22 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|||
#include <qguardedptr.h>
|
||||
#include <qvaluelist.h>
|
||||
#include <qlist.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "options.h"
|
||||
#include "plugins.h"
|
||||
#include "KWinInterface.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
||||
class Client;
|
||||
class TabBox;
|
||||
|
||||
class KConfig;
|
||||
class KGlobalAccel;
|
||||
class RootInfo;
|
||||
|
||||
typedef QValueList<Client*> ClientList;
|
||||
|
||||
enum AnchorEdge { AnchorNorth, AnchorSouth, AnchorEast, AnchorWest };
|
||||
|
||||
class DockWindow
|
||||
{
|
||||
public:
|
||||
|
@ -180,12 +181,11 @@ public:
|
|||
*/
|
||||
virtual void updateClientArea();
|
||||
|
||||
/**
|
||||
* @return the area available for edge-anchored windows. This
|
||||
* is the desktop geometry adjusted for other edge-anchored
|
||||
* windows that have priority.
|
||||
*/
|
||||
virtual QRect edgeClientArea();
|
||||
|
||||
// dcop interface
|
||||
void cascadeDesktop();
|
||||
void unclutterDesktop();
|
||||
|
||||
|
||||
public slots:
|
||||
void setCurrentDesktop( int new_desktop );
|
||||
|
@ -228,7 +228,7 @@ protected:
|
|||
bool keyPress( XKeyEvent key );
|
||||
bool keyRelease( XKeyEvent key );
|
||||
bool keyPressMouseEmulation( XKeyEvent key );
|
||||
bool clientMessage( XClientMessageEvent msg );
|
||||
bool netCheck( XEvent* e );
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
@ -241,9 +241,6 @@ private:
|
|||
void smartPlacement(Client* c);
|
||||
void cascadePlacement(Client* c, bool re_init = false);
|
||||
|
||||
enum CleanupType { Cascade, Unclutter };
|
||||
void deskCleanup(CleanupType);
|
||||
|
||||
void focusToNull();
|
||||
|
||||
Client* findClientWidthId( WId w ) const;
|
||||
|
@ -299,12 +296,12 @@ private:
|
|||
KGlobalAccel *keys;
|
||||
WId root;
|
||||
|
||||
// -cascading
|
||||
Atom kwm_command;
|
||||
|
||||
PluginMgr mgr;
|
||||
|
||||
RootInfo *rootInfo;
|
||||
QWidget* supportWindow;
|
||||
|
||||
QRect clientArea_, edgeClientArea_;
|
||||
QRect area;
|
||||
};
|
||||
|
||||
inline WId Workspace::rootWin() const
|
||||
|
|
Loading…
Reference in a new issue