00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <stdlib.h>
00023
#include <unistd.h>
00024
00025
#ifdef HAVE_SYSENT_H
00026
#include <sysent.h>
00027
#endif
00028
00029
#include <kuniqueapplication.h>
00030
#include <qbitmap.h>
00031
#include <qimage.h>
00032
#include <qwhatsthis.h>
00033
#include <qcstring.h>
00034
#include <qdialog.h>
00035
00036
#include "config.h"
00037
#include "kwin.h"
00038
#include "kapplication.h"
00039
00040
#include <kglobal.h>
00041
#include <kiconloader.h>
00042
#include <kdebug.h>
00043
00044
#include <kdatastream.h>
00045
#include <klocale.h>
00046
#include <dcopclient.h>
00047
#include <dcopref.h>
00048
#ifdef Q_WS_X11
00049
#include <kstartupinfo.h>
00050
#include <kxerrorhandler.h>
00051
00052
#include <X11/Xlib.h>
00053
#include <X11/Xatom.h>
00054
#include <X11/Xutil.h>
00055
00056
#include "netwm.h"
00057
00058
static bool atoms_created =
false;
00059
extern Atom qt_wm_protocols;
00060
extern Time qt_x_time;
00061
extern Time qt_x_user_time;
00062
00063
static Atom net_wm_context_help;
00064
static Atom kde_wm_change_state;
00065
static Atom kde_wm_window_opacity;
00066
static Atom kde_wm_window_shadow;
00067
static void kwin_net_create_atoms() {
00068
if (!atoms_created){
00069
const int max = 20;
00070 Atom* atoms[max];
00071
const char* names[max];
00072 Atom atoms_return[max];
00073
int n = 0;
00074
00075 atoms[n] = &net_wm_context_help;
00076 names[n++] =
"_NET_WM_CONTEXT_HELP";
00077
00078 atoms[n] = &kde_wm_change_state;
00079 names[n++] =
"_KDE_WM_CHANGE_STATE";
00080
00081 atoms[n] = &kde_wm_window_opacity;
00082 names[n++] = (
char*)
"_KDE_WM_WINDOW_OPACITY";
00083
00084 atoms[n] = &kde_wm_window_shadow;
00085 names[n++] = (
char*)
"_KDE_WM_WINDOW_SHADOW";
00086
00087
00088 XInternAtoms( qt_xdisplay(), const_cast<char**>(names), n,
false, atoms_return );
00089
for (
int i = 0; i < n; i++ )
00090 *atoms[i] = atoms_return[i];
00091
00092 atoms_created = True;
00093 }
00094 }
00095
#endif
00096
00097
00098
00099
00100
#ifdef Q_WS_X11
00101
static void sendClientMessageToRoot(Window w, Atom a,
long x,
long y = 0,
long z = 0 ){
00102 XEvent ev;
00103
long mask;
00104
00105 memset(&ev, 0,
sizeof(ev));
00106 ev.xclient.type = ClientMessage;
00107 ev.xclient.window = w;
00108 ev.xclient.message_type = a;
00109 ev.xclient.format = 32;
00110 ev.xclient.data.l[0] = x;
00111 ev.xclient.data.l[1] = y;
00112 ev.xclient.data.l[2] = z;
00113 mask = SubstructureRedirectMask;
00114 XSendEvent(qt_xdisplay(), qt_xrootwin(), False, mask, &ev);
00115 }
00116
#endif
00117
00118
00119
00120
00121
#ifdef Q_WS_X11
00122
static void sendClientMessage(Window w, Atom a,
long x){
00123 XEvent ev;
00124
long mask;
00125
00126 memset(&ev, 0,
sizeof(ev));
00127 ev.xclient.type = ClientMessage;
00128 ev.xclient.window = w;
00129 ev.xclient.message_type = a;
00130 ev.xclient.format = 32;
00131 ev.xclient.data.l[0] = x;
00132 ev.xclient.data.l[1] = CurrentTime;
00133 mask = 0L;
00134
if (w == qt_xrootwin())
00135 mask = SubstructureRedirectMask;
00136 XSendEvent(qt_xdisplay(), w, False, mask, &ev);
00137 }
00138
#endif
00139
00140
#ifdef Q_WS_X11
00141
namespace
00142
{
00143
class ContextWidget :
public QWidget
00144 {
00145
public:
00146 ContextWidget();
00147
virtual bool x11Event( XEvent * ev);
00148 };
00149
00150 ContextWidget::ContextWidget()
00151 :
QWidget(0,0)
00152 {
00153 kwin_net_create_atoms();
00154 kapp->installX11EventFilter(
this );
00155 QWhatsThis::enterWhatsThisMode();
00156
QCursor c = *QApplication::overrideCursor();
00157 QWhatsThis::leaveWhatsThisMode();
00158 XGrabPointer( qt_xdisplay(), qt_xrootwin(),
true,
00159 (uint)( ButtonPressMask | ButtonReleaseMask |
00160 PointerMotionMask | EnterWindowMask |
00161 LeaveWindowMask ),
00162 GrabModeAsync, GrabModeAsync,
00163 None, c.handle(), CurrentTime );
00164 qApp->enter_loop();
00165 }
00166
00167
00168
bool ContextWidget::x11Event( XEvent * ev)
00169 {
00170
if ( ev->type == ButtonPress && ev->xbutton.button == Button1 ) {
00171 XUngrabPointer( qt_xdisplay(), ev->xbutton.time );
00172 Window root;
00173 Window child = qt_xrootwin();
00174
int root_x, root_y, lx, ly;
00175 uint state;
00176 Window w;
00177
do {
00178 w = child;
00179 XQueryPointer( qt_xdisplay(), w, &root, &child,
00180 &root_x, &root_y, &lx, &ly, &state );
00181 }
while ( child != None && child != w );
00182
00183 ::sendClientMessage(w, qt_wm_protocols, net_wm_context_help);
00184 XEvent e = *ev;
00185 e.xbutton.window = w;
00186 e.xbutton.subwindow = w;
00187 e.xbutton.x = lx;
00188 e.xbutton.y = ly;
00189 XSendEvent( qt_xdisplay(), w,
true, ButtonPressMask, &e );
00190 qApp->exit_loop();
00191
return true;
00192 }
00193
return false;
00194 }
00195 }
00196
#endif
00197
00198
void KWin::invokeContextHelp()
00199 {
00200
#ifdef Q_WS_X11
00201
ContextWidget w;
00202
#endif
00203
}
00204
00205
void KWin::setSystemTrayWindowFor( WId trayWin, WId forWin )
00206 {
00207
#ifdef Q_WS_X11
00208
NETWinInfo info( qt_xdisplay(), trayWin, qt_xrootwin(), 0 );
00209
if ( !forWin )
00210 forWin = qt_xrootwin();
00211 info.
setKDESystemTrayWinFor( forWin );
00212
NETRootInfo rootinfo( qt_xdisplay(), NET::Supported );
00213
if( !rootinfo.
isSupported( NET::WMKDESystemTrayWinFor )) {
00214
DCOPRef ref(
"kded",
"kded" );
00215
if( !ref.
send(
"loadModule",
QCString(
"kdetrayproxy" )))
00216 kdWarning( 176 ) <<
"Loading of kdetrayproxy failed." <<
endl;
00217 }
00218
#endif
00219
}
00220
00221
void KWin::activateWindow( WId win,
long time )
00222 {
00223
#ifdef Q_WS_X11
00224
NETRootInfo info( qt_xdisplay(), 0 );
00225
if( time == 0 )
00226 time = qt_x_user_time;
00227 info.
setActiveWindow( win, NET::FromApplication, time,
00228 kapp->activeWindow() ? kapp->activeWindow()->winId() : 0 );
00229
#endif // Q_WS_X11 ...
00230
KUniqueApplication::setHandleAutoStarted();
00231 }
00232
00233
void KWin::forceActiveWindow( WId win,
long time )
00234 {
00235
#ifdef Q_WS_X11
00236
NETRootInfo info( qt_xdisplay(), 0 );
00237
if( time == 0 )
00238 time = qt_x_time;
00239 info.
setActiveWindow( win, NET::FromTool, time, 0 );
00240
#endif // Q_WS_X11
00241
KUniqueApplication::setHandleAutoStarted();
00242 }
00243
00244
void KWin::setActiveWindow( WId win )
00245 {
00246
#ifdef Q_WS_X11
00247
NETRootInfo info( qt_xdisplay(), 0 );
00248 info.
setActiveWindow( win, NET::FromUnknown, 0, 0 );
00249
#endif
00250
KUniqueApplication::setHandleAutoStarted();
00251 }
00252
00253
void KWin::demandAttention( WId win,
bool set )
00254 {
00255
#ifdef Q_WS_X11
00256
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00257 info.
setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention );
00258
#endif
00259
}
00260
00261
void KWin::setUserTime( WId win,
long time )
00262 {
00263
#ifdef Q_WS_X11
00264
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00265 info.
setUserTime( time );
00266
#endif
00267
}
00268
00269 KWin::WindowInfo KWin::windowInfo( WId win,
unsigned long properties,
unsigned long properties2 )
00270 {
00271
return WindowInfo( win, properties, properties2 );
00272 }
00273
00274
00275 WId KWin::transientFor( WId win )
00276 {
00277
#ifdef Q_WS_X11
00278
KXErrorHandler handler;
00279 Window transient_for = None;
00280
if( XGetTransientForHint( qt_xdisplay(), win, &transient_for ))
00281
return transient_for;
00282
00283
return None;
00284
#else
00285
return 0L;
00286
#endif
00287
}
00288
00289
void KWin::setMainWindow(
QWidget* subwindow, WId mainwindow )
00290 {
00291
#ifdef Q_WS_X11
00292
if( mainwindow != 0 )
00293 {
00294
00295
00296
00297
if( qt_cast< QDialog* >( subwindow ) != NULL
00298 && subwindow->parentWidget() == NULL
00299 && kapp->mainWidget() != NULL )
00300 {
00301 kdWarning() <<
"KWin::setMainWindow(): There either mustn't be kapp->mainWidget(),"
00302
" or the dialog must have a non-NULL parent, otherwise Qt will reset the change. Bummer." <<
endl;
00303 }
00304 XSetTransientForHint( qt_xdisplay(), subwindow->winId(), mainwindow );
00305 }
00306
else
00307 XDeleteProperty( qt_xdisplay(), subwindow->winId(), XA_WM_TRANSIENT_FOR );
00308
#endif
00309
}
00310
00311 WId KWin::groupLeader( WId win )
00312 {
00313
#ifdef Q_WS_X11
00314
KXErrorHandler handler;
00315 XWMHints *hints = XGetWMHints( qt_xdisplay(), win );
00316 Window window_group = None;
00317
if ( hints )
00318 {
00319
if( hints->flags & WindowGroupHint )
00320 window_group = hints->window_group;
00321 XFree( reinterpret_cast< char* >( hints ));
00322 }
00323
00324
return window_group;
00325
#else
00326
return 0L;
00327
#endif
00328
}
00329
00330
00331 KWin::Info KWin::info( WId win )
00332 {
00333
Info w;
00334
#ifdef Q_WS_X11
00335
NETWinInfo inf( qt_xdisplay(), win, qt_xrootwin(),
00336 NET::WMState |
00337 NET::WMStrut |
00338 NET::WMWindowType |
00339 NET::WMName |
00340 NET::WMVisibleName |
00341 NET::WMDesktop |
00342 NET::WMPid |
00343 NET::WMKDEFrameStrut |
00344 NET::XAWMState
00345 );
00346
00347 w.win = win;
00348 w.state = inf.
state();
00349 w.mappingState = inf.
mappingState();
00350 w.strut = inf.
strut();
00351 w.windowType = inf.
windowType( -1U );
00352
if ( inf.
name() ) {
00353 w.name = QString::fromUtf8( inf.
name() );
00354 }
else {
00355
char* c = 0;
00356
if ( XFetchName( qt_xdisplay(), win, &c ) != 0 ) {
00357 w.name = QString::fromLocal8Bit( c );
00358 XFree( c );
00359 }
00360 }
00361
if ( inf.
visibleName() )
00362 w.visibleName = QString::fromUtf8( inf.
visibleName() );
00363
else
00364 w.visibleName = w.name;
00365
00366 w.desktop = inf.
desktop();
00367 w.onAllDesktops = inf.
desktop() ==
NETWinInfo::OnAllDesktops;
00368 w.pid = inf.
pid();
00369
NETRect frame, geom;
00370 inf.
kdeGeometry( frame, geom );
00371 w.geometry.setRect( geom.
pos.
x, geom.
pos.
y, geom.
size.
width, geom.
size.
height );
00372 w.frameGeometry.setRect( frame.
pos.
x, frame.
pos.
y, frame.
size.
width, frame.
size.
height );
00373
#endif
00374
return w;
00375 }
00376
00377
QPixmap KWin::icon( WId win,
int width,
int height,
bool scale )
00378 {
00379
return icon( win, width, height, scale, NETWM | WMHints | ClassHint | XApp );
00380 }
00381
00382
00383
QPixmap KWin::icon( WId win,
int width,
int height,
bool scale,
int flags )
00384 {
00385
#ifdef Q_WS_X11
00386
KXErrorHandler handler;
00387
#endif
00388
QPixmap result;
00389
#ifdef Q_WS_X11
00390
if( flags & NETWM ) {
00391
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMIcon );
00392
NETIcon ni = info.
icon( width, height );
00393
if ( ni.
data && ni.
size.
width > 0 && ni.
size.
height > 0 ) {
00394
QImage img( (uchar*) ni.
data, (
int) ni.
size.
width, (
int) ni.
size.
height, 32, 0, 0, QImage::IgnoreEndian );
00395 img.setAlphaBuffer(
true );
00396
if ( scale && width > 0 && height > 0 &&img.size() !=
QSize( width, height ) && !img.isNull() )
00397 img = img.smoothScale( width, height );
00398
if ( !img.isNull() )
00399 result.convertFromImage( img );
00400
return result;
00401 }
00402 }
00403
00404
if( flags & WMHints ) {
00405 Pixmap p = None;
00406 Pixmap p_mask = None;
00407
00408 XWMHints *hints = XGetWMHints(qt_xdisplay(), win );
00409
if (hints && (hints->flags & IconPixmapHint)){
00410 p = hints->icon_pixmap;
00411 }
00412
if (hints && (hints->flags & IconMaskHint)){
00413 p_mask = hints->icon_mask;
00414 }
00415
if (hints)
00416 XFree((
char*)hints);
00417
00418
if (p != None){
00419 Window root;
00420
int x, y;
00421
unsigned int w = 0;
00422
unsigned int h = 0;
00423
unsigned int border_w, depth;
00424 XGetGeometry(qt_xdisplay(), p, &root,
00425 &x, &y, &w, &h, &border_w, &depth);
00426
if (w > 0 && h > 0){
00427
QPixmap pm(w, h, depth);
00428
00429 pm.detach();
00430 XCopyArea(qt_xdisplay(), p, pm.handle(),
00431 qt_xget_temp_gc(qt_xscreen(), depth==1),
00432 0, 0, w, h, 0, 0);
00433
if (p_mask != None){
00434
QBitmap bm(w, h);
00435 XCopyArea(qt_xdisplay(), p_mask, bm.handle(),
00436 qt_xget_temp_gc(qt_xscreen(),
true),
00437 0, 0, w, h, 0, 0);
00438 pm.setMask(bm);
00439 }
00440
if ( scale && width > 0 && height > 0 && !pm.isNull() &&
00441 ( (
int) w != width || (
int) h != height) ){
00442 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) );
00443 }
else {
00444 result = pm;
00445 }
00446 }
00447 }
00448 }
00449
00450
00451
00452
00453
int iconWidth;
00454
if( width < 24 )
00455 iconWidth = 16;
00456
else if( width < 40 )
00457 iconWidth = 32;
00458
else
00459 iconWidth = 48;
00460
00461
if( flags & ClassHint ) {
00462
00463
00464
if( result.isNull() ) {
00465
00466 XClassHint hint;
00467
if( XGetClassHint( qt_xdisplay(), win, &hint ) ) {
00468
QString className = hint.res_class;
00469
00470
QPixmap pm =
KGlobal::instance()->
iconLoader()->
loadIcon( className.lower(),
KIcon::Small, iconWidth,
00471
KIcon::DefaultState, 0,
true );
00472
if( scale && !pm.isNull() )
00473 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) );
00474
else
00475 result = pm;
00476
00477 XFree( hint.res_name );
00478 XFree( hint.res_class );
00479 }
00480 }
00481 }
00482
00483
if( flags & XApp ) {
00484
00485
00486
if ( result.isNull() ) {
00487
QPixmap pm =
KGlobal::instance()->
iconLoader()->
loadIcon(
"xapp", KIcon::Small, iconWidth,
00488 KIcon::DefaultState, 0,
true );
00489
if( scale && !pm.isNull() )
00490 result.convertFromImage( pm.convertToImage().smoothScale( width, height ) );
00491
else
00492 result = pm;
00493 }
00494 }
00495
#endif
00496
return result;
00497 }
00498
00499
void KWin::setIcons( WId win,
const QPixmap& icon,
const QPixmap& miniIcon )
00500 {
00501
#ifdef Q_WS_X11
00502
if ( icon.isNull() )
00503
return;
00504
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00505
QImage img = icon.convertToImage().convertDepth( 32 );
00506
NETIcon ni;
00507 ni.
size.
width = img.size().width();
00508 ni.
size.
height = img.size().height();
00509 ni.
data = (
unsigned char *) img.bits();
00510 info.
setIcon( ni,
true );
00511
if ( miniIcon.isNull() )
00512
return;
00513 img = miniIcon.convertToImage().convertDepth( 32 );
00514 ni.
size.
width = img.size().width();
00515 ni.
size.
height = img.size().height();
00516 ni.
data = (
unsigned char *) img.bits();
00517 info.
setIcon( ni,
false );
00518
#endif
00519
}
00520
00521
void KWin::setType( WId win, NET::WindowType windowType )
00522 {
00523
#ifdef Q_WS_X11
00524
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00525 info.
setWindowType( windowType );
00526
#endif
00527
}
00528
00529
void KWin::setState( WId win,
unsigned long state )
00530 {
00531
#ifdef Q_WS_X11
00532
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMState );
00533 info.
setState( state, state );
00534
#endif
00535
}
00536
00537
void KWin::clearState( WId win,
unsigned long state )
00538 {
00539
#ifdef Q_WS_X11
00540
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMState );
00541 info.
setState( 0, state );
00542
#endif
00543
}
00544
00545
void KWin::setOpacity( WId win, uint percent )
00546 {
00547
#ifdef Q_WS_X11
00548
kwin_net_create_atoms();
00549
if (percent > 99)
00550 XDeleteProperty (qt_xdisplay(), win, kde_wm_window_opacity);
00551
else
00552 {
00553
long opacity = long(0xFFFFFFFF/100.0*percent);
00554 XChangeProperty(qt_xdisplay(), win, kde_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (
unsigned char *) &opacity, 1L);
00555 }
00556
#endif
00557
}
00558
00559
void KWin::setShadowSize( WId win, uint percent )
00560 {
00561
#ifdef Q_WS_X11
00562
kwin_net_create_atoms();
00563
long shadowSize = long(0xFFFFFFFF/100.0*percent);
00564 XChangeProperty(qt_xdisplay(), win, kde_wm_window_shadow, XA_CARDINAL, 32, PropModeReplace, (
unsigned char *) &shadowSize, 1L);
00565
#endif
00566
}
00567
00568
void KWin::setOnAllDesktops( WId win,
bool b )
00569 {
00570
#ifdef Q_WS_X11
00571
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMDesktop );
00572
if ( b )
00573 info.
setDesktop( NETWinInfo::OnAllDesktops );
00574
else if ( info.
desktop() ==
NETWinInfo::OnAllDesktops ) {
00575
NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop );
00576 info.
setDesktop( rinfo.
currentDesktop() );
00577 }
00578
#endif
00579
}
00580
00581
void KWin::setOnDesktop( WId win,
int desktop )
00582 {
00583
#ifdef Q_WS_X11
00584
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), NET::WMDesktop );
00585 info.
setDesktop( desktop );
00586
#endif
00587
}
00588
00589
void KWin::setExtendedStrut( WId win,
int left_width,
int left_start,
int left_end,
00590
int right_width,
int right_start,
int right_end,
int top_width,
int top_start,
int top_end,
00591
int bottom_width,
int bottom_start,
int bottom_end )
00592 {
00593
#ifdef Q_WS_X11
00594
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00595
NETExtendedStrut strut;
00596 strut.
left_width = left_width;
00597 strut.
right_width = right_width;
00598 strut.
top_width = top_width;
00599 strut.
bottom_width = bottom_width;
00600 strut.
left_start = left_start;
00601 strut.
left_end = left_end;
00602 strut.
right_start = right_start;
00603 strut.
right_end = right_end;
00604 strut.
top_start = top_start;
00605 strut.
top_end = top_end;
00606 strut.
bottom_start = bottom_start;
00607 strut.
bottom_end = bottom_end;
00608 info.
setExtendedStrut( strut );
00609
#endif
00610
}
00611
00612
void KWin::setStrut( WId win,
int left,
int right,
int top,
int bottom )
00613 {
00614
#ifdef Q_WS_X11
00615
NETWinInfo info( qt_xdisplay(), win, qt_xrootwin(), 0 );
00616
NETStrut strut;
00617 strut.
left = left;
00618 strut.
right = right;
00619 strut.
top = top;
00620 strut.
bottom = bottom;
00621 info.
setStrut( strut );
00622
#endif
00623
}
00624
00625
int KWin::currentDesktop()
00626 {
00627
#ifdef Q_WS_X11
00628
if (!qt_xdisplay())
00629
#endif
00630
return 1;
00631
#ifdef Q_WS_X11
00632
NETRootInfo info( qt_xdisplay(), NET::CurrentDesktop );
00633
return info.
currentDesktop();
00634
#endif
00635
}
00636
00637
int KWin::numberOfDesktops()
00638 {
00639
#ifdef Q_WS_X11
00640
if (!qt_xdisplay())
00641
#endif
00642
return 0;
00643
#ifdef Q_WS_X11
00644
NETRootInfo info( qt_xdisplay(), NET::NumberOfDesktops );
00645
return info.
numberOfDesktops();
00646
#endif
00647
}
00648
00649
void KWin::setCurrentDesktop(
int desktop )
00650 {
00651
#ifdef Q_WS_X11
00652
NETRootInfo info( qt_xdisplay(), NET::CurrentDesktop );
00653 info.
setCurrentDesktop( desktop );
00654
#endif
00655
}
00656
00657
00658
void KWin::iconifyWindow( WId win,
bool animation)
00659 {
00660
#ifdef Q_WS_X11
00661
if ( !animation )
00662 {
00663 kwin_net_create_atoms();
00664 sendClientMessageToRoot( win, kde_wm_change_state, IconicState, 1 );
00665 }
00666 XIconifyWindow( qt_xdisplay(), win, qt_xscreen() );
00667
#endif
00668
}
00669
00670
00671
void KWin::deIconifyWindow( WId win,
bool animation )
00672 {
00673
#ifdef Q_WS_X11
00674
if ( !animation )
00675 {
00676 kwin_net_create_atoms();
00677 sendClientMessageToRoot( win, kde_wm_change_state, NormalState, 1 );
00678 }
00679 XMapWindow( qt_xdisplay(), win );
00680
#endif
00681
}
00682
00683
void KWin::raiseWindow( WId win )
00684 {
00685
#ifdef Q_WS_X11
00686
NETRootInfo info( qt_xdisplay(), NET::Supported );
00687
if( info.
isSupported( NET::WM2RestackWindow ))
00688 info.
restackRequest( win, None, Above );
00689
else
00690 XRaiseWindow( qt_xdisplay(), win );
00691
#endif
00692
}
00693
00694
void KWin::lowerWindow( WId win )
00695 {
00696
#ifdef Q_WS_X11
00697
NETRootInfo info( qt_xdisplay(), NET::Supported );
00698
if( info.
isSupported( NET::WM2RestackWindow ))
00699 info.
restackRequest( win, None, Below );
00700
else
00701 XLowerWindow( qt_xdisplay(), win );
00702
#endif
00703
}
00704
00705
void KWin::appStarted()
00706 {
00707
#ifdef Q_WS_X11
00708
KStartupInfo::appStarted();
00709
#endif
00710
}
00711
00712
class KWin::WindowInfoPrivate
00713 {
00714
public:
00715 WindowInfoPrivate()
00716 #ifdef Q_WS_X11
00717 : info( NULL )
00718 #endif
00719 {}
00720
#ifdef Q_WS_X11
00721
~WindowInfoPrivate() {
delete info; }
00722
NETWinInfo* info;
00723
#endif
00724
WId win_;
00725
QString name_;
00726
QString iconic_name_;
00727
QRect geometry_;
00728
QRect frame_geometry_;
00729
int ref;
00730
bool valid;
00731
private:
00732 WindowInfoPrivate(
const WindowInfoPrivate& );
00733
void operator=(
const WindowInfoPrivate& );
00734 };
00735
00736
00737 KWin::WindowInfo::WindowInfo( WId win,
unsigned long properties,
unsigned long properties2 )
00738 {
00739
#ifdef Q_WS_X11
00740
KXErrorHandler handler;
00741 d =
new WindowInfoPrivate;
00742 d->ref = 1;
00743
if( properties == 0 )
00744 properties = NET::WMState |
00745 NET::WMStrut |
00746 NET::WMWindowType |
00747 NET::WMName |
00748 NET::WMVisibleName |
00749 NET::WMIconName |
00750 NET::WMVisibleIconName |
00751 NET::WMDesktop |
00752 NET::WMPid |
00753 NET::WMKDEFrameStrut |
00754 NET::XAWMState |
00755 NET::WMGeometry;
00756
if( properties & NET::WMVisibleIconName )
00757 properties |= NET::WMIconName | NET::WMVisibleName;
00758
if( properties & NET::WMVisibleName )
00759 properties |= NET::WMName;
00760
if( properties2 & NET::WM2ExtendedStrut )
00761 properties |= NET::WMStrut;
00762 properties |= NET::XAWMState;
00763
unsigned long props[ 2 ] = { properties, properties2 };
00764 d->info =
new NETWinInfo( qt_xdisplay(), win, qt_xrootwin(), props, 2 );
00765 d->win_ = win;
00766
if( properties & NET::WMName ) {
00767
if( d->info->name() && d->info->name()[ 0 ] !=
'\0' )
00768 d->name_ = QString::fromUtf8( d->info->name() );
00769
else
00770 d->name_ = readNameProperty( win, XA_WM_NAME );
00771 }
00772
if( properties & NET::WMIconName ) {
00773
if( d->info->iconName() && d->info->iconName()[ 0 ] !=
'\0' )
00774 d->iconic_name_ = QString::fromUtf8( d->info->iconName());
00775
else
00776 d->iconic_name_ = readNameProperty( win, XA_WM_ICON_NAME );
00777 }
00778
if( properties & ( NET::WMGeometry | NET::WMKDEFrameStrut )) {
00779
NETRect frame, geom;
00780 d->info->kdeGeometry( frame, geom );
00781 d->geometry_.setRect( geom.
pos.
x, geom.
pos.
y, geom.
size.
width, geom.
size.
height );
00782 d->frame_geometry_.setRect( frame.
pos.
x, frame.
pos.
y, frame.
size.
width, frame.
size.
height );
00783 }
00784 d->valid = !handler.
error(
false );
00785
#endif
00786
}
00787
00788
00789 KWin::WindowInfo::WindowInfo()
00790 : d( NULL )
00791 {
00792 }
00793
00794 KWin::WindowInfo::~WindowInfo()
00795 {
00796
if( d != NULL ) {
00797
if( --d->ref == 0 ) {
00798
delete d;
00799 }
00800 }
00801 }
00802
00803 KWin::WindowInfo::WindowInfo(
const WindowInfo& wininfo )
00804 : d( wininfo.d )
00805 {
00806
if( d != NULL )
00807 ++d->ref;
00808 }
00809
00810 KWin::WindowInfo& KWin::WindowInfo::operator=(
const WindowInfo& wininfo )
00811 {
00812
if( d != wininfo.d ) {
00813
if( d != NULL )
00814
if( --d->ref == 0 )
00815
delete d;
00816 d = wininfo.d;
00817
if( d != NULL )
00818 ++d->ref;
00819 }
00820
return *
this;
00821 }
00822
00823
bool KWin::WindowInfo::valid(
bool withdrawn_is_valid )
const
00824
{
00825
if( !d->valid )
00826
return false;
00827
if( !withdrawn_is_valid && mappingState() == NET::Withdrawn )
00828
return false;
00829
return true;
00830 }
00831
00832 WId KWin::WindowInfo::win()
const
00833
{
00834
return d->win_;
00835 }
00836
00837
unsigned long KWin::WindowInfo::state()
const
00838
{
00839
#ifdef Q_WS_X11
00840
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMState ) == 0, 176 )
00841 <<
"Pass NET::WMState to KWin::windowInfo()" <<
endl;
00842
return d->info->state();
00843
#else
00844
return 0;
00845
#endif
00846
}
00847
00848
NET::MappingState KWin::WindowInfo::mappingState()
const
00849
{
00850
#ifdef Q_WS_X11
00851
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::XAWMState ) == 0, 176 )
00852 <<
"Pass NET::XAWMState to KWin::windowInfo()" <<
endl;
00853
return d->info->mappingState();
00854
#else
00855
return NET::Visible;
00856
#endif
00857
}
00858
00859
NETExtendedStrut KWin::WindowInfo::extendedStrut()
const
00860
{
00861
#ifdef Q_WS_X11
00862
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut ) == 0, 176 )
00863 <<
"Pass NET::WM2ExtendedStrut to second argument of KWin::windowInfo()" <<
endl;
00864
NETExtendedStrut ext = d->info->extendedStrut();
00865
NETStrut str = d->info->strut();
00866
if( ext.
left_width == 0 && ext.
right_width == 0 && ext.
top_width == 0 && ext.
bottom_width == 0
00867 && ( str.
left != 0 || str.
right != 0 || str.
top != 0 || str.
bottom != 0 )) {
00868
00869
if( str.
left != 0 ) {
00870 ext.
left_width = str.
left;
00871 ext.
left_start = 0;
00872 ext.
left_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00873 }
00874
if( str.
right != 0 ) {
00875 ext.
right_width = str.
right;
00876 ext.
right_start = 0;
00877 ext.
right_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00878 }
00879
if( str.
top != 0 ) {
00880 ext.
top_width = str.
top;
00881 ext.
top_start = 0;
00882 ext.
top_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00883 }
00884
if( str.
bottom != 0 ) {
00885 ext.
bottom_width = str.
bottom;
00886 ext.
bottom_start = 0;
00887 ext.
bottom_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00888 }
00889 }
00890
return ext;
00891
#else
00892
NETExtendedStrut n;
00893
return n;
00894
#endif
00895
}
00896
00897
NETStrut KWin::WindowInfo::strut()
const
00898
{
00899
#ifdef Q_WS_X11
00900
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMStrut ) == 0, 176 )
00901 <<
"Pass NET::WMStrut to KWin::windowInfo()" <<
endl;
00902
return d->info->strut();
00903
#else
00904
NETStrut n;
00905
return n;
00906
#endif
00907
}
00908
00909
NET::WindowType KWin::WindowInfo::windowType(
int supported_types )
const
00910
{
00911
#ifdef Q_WS_X11
00912
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMWindowType ) == 0, 176 )
00913 <<
"Pass NET::WMWindowType to KWin::windowInfo()" <<
endl;
00914
return d->info->windowType( supported_types );
00915
#else
00916
return 0;
00917
#endif
00918
}
00919
00920
QString KWin::WindowInfo::visibleNameWithState()
const
00921
{
00922
QString s = visibleName();
00923
if ( isMinimized() ) {
00924 s.prepend(
'(');
00925 s.append(
')');
00926 }
00927
return s;
00928 }
00929
00930
QString KWin::Info::visibleNameWithState()
const
00931
{
00932
QString s = visibleName;
00933
if ( isMinimized() ) {
00934 s.prepend(
'(');
00935 s.append(
')');
00936 }
00937
return s;
00938 }
00939
00940
QString KWin::WindowInfo::visibleName()
const
00941
{
00942
#ifdef Q_WS_X11
00943
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleName ) == 0, 176 )
00944 <<
"Pass NET::WMVisibleName to KWin::windowInfo()" <<
endl;
00945
return d->info->visibleName() && d->info->visibleName()[ 0 ] !=
'\0'
00946 ? QString::fromUtf8(d->info->visibleName()) :
name();
00947
#else
00948
return QString(
"name");
00949
#endif
00950
}
00951
00952
QString KWin::WindowInfo::name()
const
00953
{
00954
#ifdef Q_WS_X11
00955
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMName ) == 0, 176 )
00956 <<
"Pass NET::WMName to KWin::windowInfo()" <<
endl;
00957
return d->name_;
00958
#else
00959
return QString();
00960
#endif
00961
}
00962
00963
QString KWin::WindowInfo::visibleIconNameWithState()
const
00964
{
00965
QString s = visibleIconName();
00966
if ( isMinimized() ) {
00967 s.prepend(
'(');
00968 s.append(
')');
00969 }
00970
return s;
00971 }
00972
00973
QString KWin::WindowInfo::visibleIconName()
const
00974
{
00975
#ifdef Q_WS_X11
00976
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleIconName ) == 0, 176 )
00977 <<
"Pass NET::WMVisibleIconName to KWin::windowInfo()" <<
endl;
00978
if( d->info->visibleIconName() && d->info->visibleIconName()[ 0 ] !=
'\0' )
00979
return QString::fromUtf8( d->info->visibleIconName());
00980
if( d->info->iconName() && d->info->iconName()[ 0 ] !=
'\0' )
00981
return QString::fromUtf8( d->info->iconName());
00982
if( !d->iconic_name_.isEmpty())
00983
return d->iconic_name_;
00984
#endif
00985
return visibleName();
00986 }
00987
00988
QString KWin::WindowInfo::iconName()
const
00989
{
00990
#ifdef Q_WS_X11
00991
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMIconName ) == 0, 176 )
00992 <<
"Pass NET::WMIconName to KWin::windowInfo()" <<
endl;
00993
if( d->info->iconName() && d->info->iconName()[ 0 ] !=
'\0' )
00994
return QString::fromUtf8( d->info->iconName());
00995
if( !d->iconic_name_.isEmpty())
00996
return d->iconic_name_;
00997
#endif
00998
return name();
00999 }
01000
01001
bool KWin::WindowInfo::isOnCurrentDesktop()
const
01002
{
01003
#ifdef Q_WS_X11
01004
return isOnDesktop( KWin::currentDesktop());
01005
#else
01006
return false;
01007
#endif
01008
}
01009
01010
bool KWin::WindowInfo::isOnDesktop(
int desktop )
const
01011
{
01012
#ifdef Q_WS_X11
01013
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
01014 <<
"Pass NET::WMDesktop to KWin::windowInfo()" <<
endl;
01015
return d->info->desktop() == desktop || d->info->desktop() == NET::OnAllDesktops;
01016
#else
01017
return false;
01018
#endif
01019
}
01020
01021
bool KWin::WindowInfo::onAllDesktops()
const
01022
{
01023
#ifdef Q_WS_X11
01024
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
01025 <<
"Pass NET::WMDesktop to KWin::windowInfo()" <<
endl;
01026
return d->info->desktop() == NET::OnAllDesktops;
01027
#else
01028
return false;
01029
#endif
01030
}
01031
01032
int KWin::WindowInfo::desktop()
const
01033
{
01034
#ifdef Q_WS_X11
01035
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
01036 <<
"Pass NET::WMDesktop to KWin::windowInfo()" <<
endl;
01037
return d->info->desktop();
01038
#else
01039
return 1;
01040
#endif
01041
}
01042
01043
QRect KWin::WindowInfo::geometry()
const
01044
{
01045
#ifdef Q_WS_X11
01046
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMGeometry ) == 0, 176 )
01047 <<
"Pass NET::WMGeometry to KWin::windowInfo()" <<
endl;
01048
return d->geometry_;
01049
#else
01050
return QRect( 100, 100, 200, 200 );
01051
#endif
01052
}
01053
01054
QRect KWin::WindowInfo::frameGeometry()
const
01055
{
01056
#ifdef Q_WS_X11
01057
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMKDEFrameStrut ) == 0, 176 )
01058 <<
"Pass NET::WMKDEFrameStrut to KWin::windowInfo()" <<
endl;
01059
return d->frame_geometry_;
01060
#else
01061
return QRect();
01062
#endif
01063
}
01064
01065 WId KWin::WindowInfo::transientFor()
const
01066
{
01067
#ifdef Q_WS_X11
01068
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor ) == 0, 176 )
01069 <<
"Pass NET::WM2TransientFor to KWin::windowInfo()" <<
endl;
01070
return d->info->transientFor();
01071
#else
01072
return 0;
01073
#endif
01074
}
01075
01076 WId KWin::WindowInfo::groupLeader()
const
01077
{
01078
#ifdef Q_WS_X11
01079
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader ) == 0, 176 )
01080 <<
"Pass NET::WM2GroupLeader to KWin::windowInfo()" <<
endl;
01081
return d->info->groupLeader();
01082
#else
01083
return 0;
01084
#endif
01085
}
01086
01087
QCString KWin::WindowInfo::windowClassClass()
const
01088
{
01089
#ifdef Q_WS_X11
01090
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] &
NET::WM2WindowClass ) == 0, 176 )
01091 <<
"Pass NET::WM2WindowClass to KWin::windowInfo()" <<
endl;
01092
return d->info->windowClassClass();
01093
#else
01094
return 0;
01095
#endif
01096
}
01097
01098
QCString KWin::WindowInfo::windowClassName()
const
01099
{
01100
#ifdef Q_WS_X11
01101
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] &
NET::WM2WindowClass ) == 0, 176 )
01102 <<
"Pass NET::WM2WindowClass to KWin::windowInfo()" <<
endl;
01103
return d->info->windowClassName();
01104
#else
01105
return 0;
01106
#endif
01107
}
01108
01109
QCString KWin::WindowInfo::windowRole()
const
01110
{
01111
#ifdef Q_WS_X11
01112
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] &
NET::WM2WindowRole ) == 0, 176 )
01113 <<
"Pass NET::WM2WindowRole to KWin::windowInfo()" <<
endl;
01114
return d->info->windowRole();
01115
#else
01116
return 0;
01117
#endif
01118
}
01119
01120
QCString KWin::WindowInfo::clientMachine()
const
01121
{
01122
#ifdef Q_WS_X11
01123
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] &
NET::WM2ClientMachine ) == 0, 176 )
01124 <<
"Pass NET::WM2ClientMachine to KWin::windowInfo()" <<
endl;
01125
return d->info->clientMachine();
01126
#else
01127
return 0;
01128
#endif
01129
}
01130
01131
bool KWin::WindowInfo::actionSupported( NET::Action action )
const
01132
{
01133
#ifdef Q_WS_X11
01134
kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions ) == 0, 176 )
01135 <<
"Pass NET::WM2AllowedActions to KWin::windowInfo()" <<
endl;
01136
if( allowedActionsSupported())
01137
return d->info->allowedActions() &
action;
01138
else
01139
#endif
01140
return true;
01141 }
01142
01143
01144
bool KWin::WindowInfo::isMinimized()
const
01145
{
01146
#ifdef Q_WS_X11
01147
if( mappingState() != NET::Iconic )
01148
return false;
01149
01150
if(( state() &
NET::Hidden ) != 0
01151 && ( state() & NET::Shaded ) == 0 )
01152
return true;
01153
01154
01155
return icccmCompliantMappingState() ?
false :
true;
01156
#else
01157
return false;
01158
#endif
01159
}
01160
01161
bool KWin::Info::isMinimized()
const
01162
{
01163
#ifdef Q_WS_X11
01164
if( mappingState != NET::Iconic )
01165
return false;
01166
01167
if(( state &
NET::Hidden ) != 0
01168 && ( state & NET::Shaded ) == 0 )
01169
return true;
01170
01171
01172
return icccmCompliantMappingState() ?
false :
true;
01173
#else
01174
return false;
01175
#endif
01176
}
01177
01178
bool KWin::Info::isIconified()
const
01179
{
01180
return isMinimized();
01181 }
01182
01183
bool KWin::icccmCompliantMappingState()
01184 {
01185
#ifdef Q_WS_X11
01186
static enum { noidea, yes, no } wm_is_1_2_compliant = noidea;
01187
if( wm_is_1_2_compliant == noidea ) {
01188
NETRootInfo info( qt_xdisplay(), NET::Supported );
01189 wm_is_1_2_compliant = info.
isSupported( NET::Hidden ) ? yes : no;
01190 }
01191
return wm_is_1_2_compliant == yes;
01192
#else
01193
return false;
01194
#endif
01195
}
01196
01197
bool KWin::allowedActionsSupported()
01198 {
01199
#ifdef Q_WS_X11
01200
static enum { noidea, yes, no } wm_supports_allowed_actions = noidea;
01201
if( wm_supports_allowed_actions == noidea ) {
01202
NETRootInfo info( qt_xdisplay(), NET::Supported );
01203 wm_supports_allowed_actions = info.
isSupported( NET::WM2AllowedActions ) ? yes : no;
01204 }
01205
return wm_supports_allowed_actions == yes;
01206
#else
01207
return false;
01208
#endif
01209
}
01210
01211
QString KWin::readNameProperty( WId win,
unsigned long atom )
01212 {
01213
#ifdef Q_WS_X11
01214
XTextProperty tp;
01215
char **text = NULL;
01216
int count;
01217
#endif
01218
QString result;
01219
#ifdef Q_WS_X11
01220
if ( XGetTextProperty( qt_xdisplay(), win, &tp, atom ) != 0 && tp.value != NULL ) {
01221
if ( XmbTextPropertyToTextList( qt_xdisplay(), &tp, &text, &count) == Success &&
01222 text != NULL && count > 0 ) {
01223 result = QString::fromLocal8Bit( text[0] );
01224 }
else if ( tp.encoding == XA_STRING )
01225 result = QString::fromLocal8Bit( (
const char*) tp.value );
01226
if( text != NULL )
01227 XFreeStringList( text );
01228 XFree( tp.value );
01229 }
01230
#endif
01231
return result;
01232 }
01233
01234