update, usable with kicker now

svn path=/trunk/kdebase/kwin/; revision=33064
This commit is contained in:
Matthias Ettrich 1999-11-07 01:43:06 +00:00
parent 5b3d19e42d
commit 1884091309
9 changed files with 143 additions and 197 deletions

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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();
show();
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 );
}

View file

@ -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

View file

@ -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]);

View file

@ -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(": ");
}

View file

@ -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 *)&current_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;
}

View file

@ -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