update, usable with kicker now
svn path=/trunk/kdebase/kwin/; revision=33064
This commit is contained in:
parent
5b3d19e42d
commit
1884091309
9 changed files with 143 additions and 197 deletions
|
@ -12,4 +12,11 @@ Atoms::Atoms()
|
|||
// compatibility
|
||||
kwm_win_icon = XInternAtom(qt_xdisplay(), "KWM_WIN_ICON", FALSE);
|
||||
|
||||
|
||||
net_number_of_desktops = XInternAtom(qt_xdisplay(), "_NET_NUMBER_OF_DESKTOPS", False);
|
||||
net_current_desktop = XInternAtom(qt_xdisplay(), "_NET_CURRENT_DESKTOP", False);
|
||||
net_active_window = XInternAtom(qt_xdisplay(), "_NET_ACTIVE_WINDOW", False);
|
||||
|
||||
net_client_list = XInternAtom(qt_xdisplay(), "_NET_CLIENT_LIST", False);
|
||||
net_client_list_stacking = XInternAtom(qt_xdisplay(), "_NET_CLIENT_LIST_STACKIN", False);
|
||||
}
|
||||
|
|
6
atoms.h
6
atoms.h
|
@ -11,6 +11,12 @@ public:
|
|||
Atom wm_take_focus;
|
||||
Atom kwm_win_icon; // compatibility
|
||||
|
||||
Atom net_number_of_desktops;
|
||||
Atom net_current_desktop;
|
||||
Atom net_active_window;
|
||||
Atom net_client_list;
|
||||
Atom net_client_list_stacking;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
176
client.cpp
176
client.cpp
|
@ -58,173 +58,6 @@ static void sendClientMessage(Window w, Atom a, long x){
|
|||
}
|
||||
|
||||
|
||||
static int _getprop(Window w, Atom a, Atom type, long len, unsigned char **p){
|
||||
Atom real_type;
|
||||
int format;
|
||||
unsigned long n, extra;
|
||||
int status;
|
||||
|
||||
status = XGetWindowProperty(qt_xdisplay(), w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p);
|
||||
if (status != Success || *p == 0)
|
||||
return -1;
|
||||
if (n == 0)
|
||||
XFree((char*) *p);
|
||||
/* could check real_type, format, extra here... */
|
||||
return n;
|
||||
}
|
||||
static bool getDoubleProperty(Window w, Atom a, long &result1, long &result2){
|
||||
long *p = 0;
|
||||
|
||||
if (_getprop(w, a, a, 2L, (unsigned char**)&p) <= 0){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
result1 = p[0];
|
||||
result2 = p[1];
|
||||
XFree((char *) p);
|
||||
return TRUE;
|
||||
}
|
||||
QPixmap KWM::miniIcon(Window w, int width, int height){
|
||||
QPixmap result;
|
||||
Pixmap p = None;
|
||||
Pixmap p_mask = None;
|
||||
|
||||
long tmp[2] = {None, None};
|
||||
if (!getDoubleProperty(w, atoms->kwm_win_icon, tmp[0], tmp[1])){
|
||||
XWMHints *hints = XGetWMHints(qt_xdisplay(), w);
|
||||
if (hints && (hints->flags & IconPixmapHint)){
|
||||
p = hints->icon_pixmap;
|
||||
}
|
||||
if (hints && (hints->flags & IconMaskHint)){
|
||||
p_mask = hints->icon_mask;
|
||||
}
|
||||
if (hints)
|
||||
XFree((char*)hints);
|
||||
}
|
||||
else {
|
||||
p = (Pixmap) tmp[0];
|
||||
p_mask = (Pixmap) tmp[1];
|
||||
}
|
||||
|
||||
if (p != None){
|
||||
Window root;
|
||||
int x, y;
|
||||
unsigned int w = 0;
|
||||
unsigned int h = 0;
|
||||
unsigned int border_w, depth;
|
||||
XGetGeometry(qt_xdisplay(), p,
|
||||
&root,
|
||||
&x, &y, &w, &h, &border_w, &depth);
|
||||
if (w > 0 && h > 0){
|
||||
QPixmap pm(w, h, depth);
|
||||
XCopyArea(qt_xdisplay(), p, pm.handle(),
|
||||
qt_xget_temp_gc(depth==1),
|
||||
0, 0, w, h, 0, 0);
|
||||
if (p_mask != None){
|
||||
QBitmap bm(w, h);
|
||||
XCopyArea(qt_xdisplay(), p_mask, bm.handle(),
|
||||
qt_xget_temp_gc(TRUE),
|
||||
0, 0, w, h, 0, 0);
|
||||
pm.setMask(bm);
|
||||
}
|
||||
if (width > 0 && height > 0 && (w > (unsigned int)width
|
||||
|| h > (unsigned int) height)){
|
||||
// scale
|
||||
QWMatrix m;
|
||||
m.scale(width/(float)w, height/(float)h);
|
||||
result = pm.xForm(m);
|
||||
}
|
||||
else
|
||||
result = pm;
|
||||
}
|
||||
}
|
||||
else {
|
||||
XWMHints *hints = XGetWMHints(qt_xdisplay(), w);
|
||||
if (hints &&
|
||||
(hints->flags & WindowGroupHint)
|
||||
&& hints->window_group != None
|
||||
&& hints->window_group != w){
|
||||
Window wg = hints->window_group;
|
||||
XFree((char*)hints);
|
||||
return miniIcon(wg, width, height);
|
||||
}
|
||||
if (hints)
|
||||
XFree((char*)hints);
|
||||
Window trans = None;
|
||||
if (XGetTransientForHint(qt_xdisplay(), w, &trans)){
|
||||
if (trans != w)
|
||||
return miniIcon(trans, width, height);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap KWM::icon(Window w, int width, int height){
|
||||
QPixmap result;
|
||||
Pixmap p = None;
|
||||
Pixmap p_mask = None;
|
||||
|
||||
XWMHints *hints = XGetWMHints(qt_xdisplay(), w);
|
||||
if (hints && (hints->flags & IconPixmapHint)){
|
||||
p = hints->icon_pixmap;
|
||||
}
|
||||
if (hints && (hints->flags & IconMaskHint)){
|
||||
p_mask = hints->icon_mask;
|
||||
}
|
||||
if (hints)
|
||||
XFree((char*)hints);
|
||||
|
||||
if (p != None){
|
||||
Window root;
|
||||
int x, y;
|
||||
unsigned int w = 0;
|
||||
unsigned int h = 0;
|
||||
unsigned int border_w, depth;
|
||||
XGetGeometry(qt_xdisplay(), p,
|
||||
&root,
|
||||
&x, &y, &w, &h, &border_w, &depth);
|
||||
if (w > 0 && h > 0){
|
||||
QPixmap pm(w, h, depth);
|
||||
XCopyArea(qt_xdisplay(), p, pm.handle(),
|
||||
qt_xget_temp_gc(depth==1),
|
||||
0, 0, w, h, 0, 0);
|
||||
if (p_mask != None){
|
||||
QBitmap bm(w, h);
|
||||
XCopyArea(qt_xdisplay(), p_mask, bm.handle(),
|
||||
qt_xget_temp_gc(TRUE),
|
||||
0, 0, w, h, 0, 0);
|
||||
pm.setMask(bm);
|
||||
}
|
||||
if (width > 0 && height > 0 && (w > (unsigned int)width
|
||||
|| h > (unsigned int) height)){
|
||||
// scale
|
||||
QWMatrix m;
|
||||
m.scale(width/(float)w, height/(float)h);
|
||||
result = pm.xForm(m);
|
||||
}
|
||||
else
|
||||
result = pm;
|
||||
}
|
||||
}
|
||||
else {
|
||||
XWMHints *hints = XGetWMHints(qt_xdisplay(), w);
|
||||
if (hints &&
|
||||
(hints->flags & WindowGroupHint)
|
||||
&& hints->window_group != None
|
||||
&& hints->window_group != w){
|
||||
XFree((char*)hints);
|
||||
return icon(hints->window_group, width, height);
|
||||
}
|
||||
if (hints)
|
||||
XFree((char*)hints);
|
||||
Window trans = None;
|
||||
if (XGetTransientForHint(qt_xdisplay(), w, &trans)){
|
||||
if (trans != w)
|
||||
return icon(trans, width, height);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class WindowWrapper client.h
|
||||
|
@ -493,10 +326,11 @@ void Client::manage( bool isMapped )
|
|||
|
||||
// ### TODO check XGetWMHints() for initial mapping state, icon, etc. pp.
|
||||
// assume window wants to be visible on the current desktop
|
||||
desk = workspace()->currentDesktop();
|
||||
desk = KWM::desktop( win ); //workspace()->currentDesktop();
|
||||
setMappingState( NormalState );
|
||||
desk = workspace()->currentDesktop();
|
||||
if ( isOnDesktop( workspace()->currentDesktop() ) ) {
|
||||
show();
|
||||
}
|
||||
|
||||
if ( options->focusPolicyIsReasonable() )
|
||||
workspace()->requestFocus( this );
|
||||
|
@ -1451,8 +1285,10 @@ void Client::setSticky( bool b )
|
|||
if ( is_sticky == b )
|
||||
return;
|
||||
is_sticky = b;
|
||||
if ( !is_sticky )
|
||||
if ( !is_sticky ) {
|
||||
desk = workspace()->currentDesktop();
|
||||
KWM::moveToDesktop( win, desk );//##### compatibility
|
||||
}
|
||||
stickyChange( is_sticky );
|
||||
}
|
||||
|
||||
|
|
8
client.h
8
client.h
|
@ -2,6 +2,7 @@
|
|||
#define CLIENT_H
|
||||
|
||||
#include "options.h"
|
||||
#include <kwm.h>
|
||||
#include <qframe.h>
|
||||
#include <qvbox.h>
|
||||
#include <qpixmap.h>
|
||||
|
@ -12,13 +13,6 @@
|
|||
class Workspace;
|
||||
class Client;
|
||||
|
||||
class KWM
|
||||
{
|
||||
public:
|
||||
static QPixmap miniIcon(Window w, int width=0, int height=0);
|
||||
static QPixmap icon(Window w, int width=0, int height=0);
|
||||
};
|
||||
|
||||
class WindowWrapper : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
13
options.cpp
13
options.cpp
|
@ -57,20 +57,24 @@ void Options::reload()
|
|||
// normal colors
|
||||
colors[Frame] = Qt::lightGray;
|
||||
colors[Frame] = config->readColorEntry("frame", &colors[Frame]);
|
||||
colors[Handle] = config->readColorEntry("handle", &colors[Frame]);
|
||||
colors[Handle] = QColor( 140, 140, 140 );
|
||||
colors[Handle] = config->readColorEntry("handle", &colors[Handle]);
|
||||
colors[ButtonBg] = QColor(163,163,163 );
|
||||
colors[ButtonBg] = config->readColorEntry("buttonBackgroundDown",
|
||||
&colors[Frame]);
|
||||
colors[ButtonBlend] = QColor(0,0,0);
|
||||
colors[ButtonBlend] = config->readColorEntry("buttonBlendDown",
|
||||
&colors[ButtonBg]);
|
||||
&colors[ButtonBlend]);
|
||||
colors[TitleBar] = Qt::darkBlue;
|
||||
colors[TitleBar] = config->readColorEntry("activeBackground",
|
||||
&colors[TitleBar]);
|
||||
colors[TitleBlend] = colors[ TitleBar ];
|
||||
colors[TitleBlend] = config->readColorEntry("activeBlend",
|
||||
&colors[TitleBar]);
|
||||
&colors[TitleBlend]);
|
||||
|
||||
colors[Font] = Qt::white;
|
||||
colors[Font] = config->readColorEntry("activeForeground", &colors[Font]);
|
||||
colors[ButtonFg] = Qt::lightGray;
|
||||
colors[ButtonFg] = QColor(144,170,191);
|
||||
colors[ButtonFg] = config->readColorEntry("buttonForegroundDown",
|
||||
&colors[ButtonFg]);
|
||||
|
||||
|
@ -82,6 +86,7 @@ void Options::reload()
|
|||
readColorEntry("inactiveBackground", &colors[TitleBar+KWINCOLORS]);
|
||||
colors[TitleBlend+KWINCOLORS] =
|
||||
config->readColorEntry("inactiveBlend", &colors[TitleBar+KWINCOLORS]);
|
||||
colors[ButtonBg+KWINCOLORS] = QColor(163,163,163);
|
||||
colors[ButtonBg+KWINCOLORS] =
|
||||
config->readColorEntry("buttonBackground",
|
||||
&colors[ButtonBg]);
|
||||
|
|
|
@ -154,7 +154,7 @@ void TabBox::paintContents()
|
|||
if ( currentClient() ) {
|
||||
QString s;
|
||||
if (!client->isOnDesktop(workspace()->currentDesktop())){
|
||||
//TODO s = KWM::desktopName(client->desktop);
|
||||
s = KWM::desktopName(client->desktop());
|
||||
s.append(": ");
|
||||
}
|
||||
|
||||
|
|
105
workspace.cpp
105
workspace.cpp
|
@ -30,6 +30,7 @@ static Client* clientFactory( Workspace *ws, WId w )
|
|||
}
|
||||
if ( s == "Kicker" ) {
|
||||
Client * c = new NoBorderClient( ws, w);
|
||||
c->setSticky( TRUE );
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,7 @@ Workspace::Workspace()
|
|||
grabKey(XK_Tab, ControlMask);
|
||||
grabKey(XK_Tab, ControlMask | ShiftMask);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Workspace::Workspace( WId rootwin )
|
||||
|
@ -85,7 +87,6 @@ Workspace::Workspace( WId rootwin )
|
|||
grabKey(XK_Tab, Mod1Mask | ShiftMask);
|
||||
grabKey(XK_Tab, ControlMask);
|
||||
grabKey(XK_Tab, ControlMask | ShiftMask);
|
||||
|
||||
}
|
||||
|
||||
void Workspace::init()
|
||||
|
@ -94,7 +95,10 @@ void Workspace::init()
|
|||
active_client = 0;
|
||||
should_get_focus = 0;
|
||||
desktop_client = 0;
|
||||
current_desktop = 1;
|
||||
current_desktop = 0;
|
||||
number_of_desktops = 0;
|
||||
setNumberOfDesktops( 4 ); // TODO options
|
||||
setCurrentDesktop( 1 );
|
||||
|
||||
unsigned int i, nwins;
|
||||
Window dw1, dw2, *wins;
|
||||
|
@ -126,6 +130,7 @@ void Workspace::init()
|
|||
XFree((void *) wins);
|
||||
XUngrabServer( qt_xdisplay() );
|
||||
popup = 0;
|
||||
propagateClients();
|
||||
}
|
||||
|
||||
Workspace::~Workspace()
|
||||
|
@ -184,6 +189,7 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
clients.append( c );
|
||||
if ( c != desktop_client )
|
||||
stacking_order.append( c );
|
||||
propagateClients();
|
||||
}
|
||||
bool result = c->windowEvent( e );
|
||||
if ( c == desktop_client )
|
||||
|
@ -238,6 +244,9 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
break;
|
||||
case FocusOut:
|
||||
break;
|
||||
case ClientMessage:
|
||||
return clientMessage(e->xclient);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -288,6 +297,7 @@ bool Workspace::destroyClient( Client* c)
|
|||
c->invalidateWindow();
|
||||
delete c;
|
||||
clientHidden( c );
|
||||
propagateClients();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -432,7 +442,7 @@ bool Workspace::keyRelease(XKeyEvent key)
|
|||
tab_box->hide();
|
||||
control_grab = False;
|
||||
if ( tab_box->currentDesktop() != -1 )
|
||||
switchDesktop( tab_box->currentDesktop() );
|
||||
setCurrentDesktop( tab_box->currentDesktop() );
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -556,7 +566,9 @@ void Workspace::grabKey(KeySym keysym, unsigned int mod){
|
|||
Informs the workspace about the active client, i.e. the client that
|
||||
has the focus (or None if no client has the focus). This functions
|
||||
is called by the client itself that gets focus. It has no other
|
||||
effect than fixing the focus chain and the return value of activeClient()
|
||||
effect than fixing the focus chain and the return value of
|
||||
activeClient(). And of course, to propagate the active client to the
|
||||
world.
|
||||
*/
|
||||
void Workspace::setActiveClient( Client* c )
|
||||
{
|
||||
|
@ -569,6 +581,11 @@ void Workspace::setActiveClient( Client* c )
|
|||
focus_chain.remove( c );
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -767,6 +784,8 @@ void Workspace::raiseClient( Client* c )
|
|||
|
||||
if ( c->transientFor() )
|
||||
raiseClient( findClient( c->transientFor() ) );
|
||||
|
||||
propagateClients( TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
@ -814,8 +833,15 @@ void Workspace::setDesktopClient( Client* c)
|
|||
}
|
||||
}
|
||||
|
||||
void Workspace::switchDesktop( int new_desktop ){
|
||||
if (new_desktop == current_desktop )
|
||||
|
||||
/*!
|
||||
Sets the current desktop to \a new_desktop
|
||||
|
||||
Shows/Hides windows according to the stacking order and finally
|
||||
propages the new desktop to the world
|
||||
*/
|
||||
void Workspace::setCurrentDesktop( int new_desktop ){
|
||||
if (new_desktop == current_desktop || new_desktop < 1 || new_desktop > number_of_desktops )
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -837,6 +863,11 @@ void Workspace::switchDesktop( int new_desktop ){
|
|||
}
|
||||
|
||||
current_desktop = new_desktop;
|
||||
|
||||
XChangeProperty(qt_xdisplay(), qt_xrootwin(),
|
||||
atoms->net_current_desktop, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char *)¤t_desktop, 1);
|
||||
KWM::switchToDesktop( current_desktop ); // ### compatibility
|
||||
}
|
||||
|
||||
|
||||
|
@ -880,3 +911,65 @@ QWidget* Workspace::desktopWidget()
|
|||
{
|
||||
return desktop_widget;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the number of virtual desktops to \a n
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*!
|
||||
Handles client messages sent to the workspace
|
||||
*/
|
||||
bool Workspace::clientMessage( XClientMessageEvent msg )
|
||||
{
|
||||
if ( msg.message_type == atoms->net_active_window ) {
|
||||
Client * c = findClient( msg.data.l[0] );
|
||||
if ( c ) {
|
||||
activateClient( c );
|
||||
return TRUE;
|
||||
}
|
||||
} else if ( msg.message_type == atoms->net_current_desktop ) {
|
||||
setCurrentDesktop( msg.data.l[0] );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*!
|
||||
Propagates the managed clients to the world
|
||||
*/
|
||||
void Workspace::propagateClients( bool onlyStacking )
|
||||
{
|
||||
WId* cl;
|
||||
int i;
|
||||
if ( !onlyStacking ) {
|
||||
WId* cl = new WId[ clients.count()];
|
||||
i = 0;
|
||||
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());
|
||||
delete [] cl;
|
||||
}
|
||||
|
||||
cl = new WId[ stacking_order.count()];
|
||||
i = 0;
|
||||
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());
|
||||
delete [] cl;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,9 @@ public:
|
|||
void clientHidden( Client* );
|
||||
|
||||
int currentDesktop() const;
|
||||
void setCurrentDesktop( int new_desktop );
|
||||
int numberOfDesktops() const;
|
||||
void setNumberOfDesktops( int n );
|
||||
|
||||
QWidget* desktopWidget();
|
||||
|
||||
|
@ -59,13 +61,13 @@ public:
|
|||
void showPopup( const QPoint&, Client* );
|
||||
|
||||
void setDesktopClient( Client* );
|
||||
void switchDesktop( int new_desktop );
|
||||
|
||||
void makeFullScreen( Client* );
|
||||
|
||||
protected:
|
||||
bool keyPress( XKeyEvent key );
|
||||
bool keyRelease( XKeyEvent key );
|
||||
bool clientMessage( XClientMessageEvent msg );
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
@ -87,12 +89,15 @@ private:
|
|||
void focusToNull();
|
||||
Client* desktop_client;
|
||||
int current_desktop;
|
||||
int number_of_desktops;
|
||||
|
||||
Client* popup_client;
|
||||
QWidget* desktop_widget;
|
||||
|
||||
//experimental
|
||||
void setDecoration( int deco );
|
||||
|
||||
void propagateClients( bool onlyStacking = FALSE);
|
||||
};
|
||||
|
||||
inline WId Workspace::rootWin() const
|
||||
|
|
Loading…
Reference in a new issue