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