20 #include <tdestartupinfo.h>
21 #include <tdeglobal.h>
22 #include <X11/extensions/shape.h>
24 #include "notifications.h"
28 namespace KWinInternal
38 XWindowAttributes attr;
39 if( !XGetWindowAttributes(tqt_xdisplay(), w, &attr))
45 postpone_geometry_updates = 1;
46 pending_geometry_update =
true;
48 embedClient( w, attr );
52 bool init_minimize =
false;
53 XWMHints * hints = XGetWMHints(tqt_xdisplay(), w );
54 if (hints && (hints->flags & StateHint) && hints->initial_state == IconicState)
59 init_minimize =
false;
61 unsigned long properties[ 2 ];
62 properties[ WinInfo::PROTOCOLS ] =
73 properties[ WinInfo::PROTOCOLS2 ] =
76 NET::WM2ExtendedStrut |
79 info =
new WinInfo(
this, tqt_xdisplay(), client, tqt_xrootwin(), properties, 2 );
84 if ( XGetClassHint( tqt_xdisplay(), client, &classHint ) )
88 resource_name = TQCString( classHint.res_name ).lower();
89 resource_class = TQCString( classHint.res_class ).lower();
90 XFree( classHint.res_name );
91 XFree( classHint.res_class );
93 ignore_focus_stealing = options->checkIgnoreFocusStealing(
this );
101 cap_normal = readName();
102 setupWindowRules(
false );
103 setCaption( cap_normal,
true );
109 modal = ( info->state() & NET::Modal ) != 0;
112 getWindowProtocols();
118 original_skip_taskbar = skip_taskbar = ( info->state() & NET::SkipTaskbar) != 0;
119 skip_pager = ( info->state() & NET::SkipPager) != 0;
121 TDEStartupInfoId asn_id;
122 TDEStartupInfoData asn_data;
123 bool asn_valid = workspace()->checkStartupNotification( window(), asn_id, asn_data );
125 workspace()->updateClientLayer(
this );
127 SessionInfo* session = workspace()->takeSessionInfo(
this );
131 if ( session->minimized )
132 init_minimize =
true;
133 if( session->userNoBorder )
134 setUserNoBorder(
true );
137 setShortcut( rules()->checkShortcut( session ? session->shortcut : TQString::null,
true ));
139 init_minimize = rules()->checkMinimize( init_minimize, !isMapped );
140 if( rules()->checkNoBorder(
false, !isMapped ))
141 setUserNoBorder(
true );
143 checkAndSetInitialRuledOpacity();
148 desk = session->desktop;
149 if( session->onAllDesktops )
150 desk = NET::OnAllDesktops;
159 ClientList mainclients = mainClients();
160 bool on_current =
false;
163 for( ClientList::ConstIterator it = mainclients.begin();
164 it != mainclients.end();
167 if( mainclients.count() > 1 && (*it)->isSpecialWindow())
170 if( (*it)->isOnCurrentDesktop())
174 desk = workspace()->currentDesktop();
175 else if( maincl != NULL )
178 if ( info->desktop() )
179 desk = info->desktop();
180 if(
desktop() == 0 && asn_valid && asn_data.desktop() != 0 )
181 desk = asn_data.desktop();
184 desk = workspace()->currentDesktop();
185 desk = rules()->checkDesktop( desk, !isMapped );
186 if( desk != NET::OnAllDesktops )
187 desk = KMAX( 1, KMIN( workspace()->numberOfDesktops(), desk ));
188 info->setDesktop( desk );
189 workspace()->updateOnAllDesktopsOfTransients(
this );
192 TQRect geom( attr.x, attr.y, attr.width, attr.height );
193 bool placementDone = FALSE;
196 geom = session->geometry;
199 bool partial_keep_in_area = isMapped || session;
200 if( isMapped || session )
201 area = workspace()->clientArea( FullArea, geom.center(),
desktop());
202 else if( options->xineramaPlacementEnabled )
204 int screen = options->xineramaPlacementScreen;
206 screen = asn_data.xinerama() == -1 ? workspace()->activeScreen() : asn_data.xinerama();
207 area = workspace()->clientArea( PlacementArea, workspace()->screenGeometry( screen ).center(),
desktop());
210 area = workspace()->clientArea( PlacementArea, TQCursor::pos(),
desktop());
212 if(
int type = checkFullScreenHack( geom ))
214 fullscreen_mode = FullScreenHack;
215 if( rules()->checkStrictGeometry(
false ))
218 ? workspace()->clientArea( FullArea, geom.center(),
desktop())
219 : workspace()->clientArea( ScreenArea, geom.center(),
desktop());
222 geom = workspace()->clientArea( FullScreenArea, geom.center(),
desktop());
223 placementDone =
true;
229 geom = workspace()->clientArea( FullArea, geom.center(),
desktop());
230 placementDone =
true;
233 bool usePosition =
false;
234 if ( isMapped || session || placementDone )
235 placementDone =
true;
236 else if( isTransient() && !isUtility() && !isDialog() && !isSplash())
238 else if( isTransient() && !hasNETSupport())
240 else if( isDialog() && hasNETSupport())
244 if( mainClients().count() >= 1 )
265 if( !rules()->checkIgnoreGeometry( !usePosition ))
267 bool ignorePPosition = ( options->ignorePositionClasses.contains(TQString::fromLatin1(resourceClass())));
269 if ( ( (xSizeHint.flags & PPosition) && !ignorePPosition ) ||
270 (xSizeHint.flags & USPosition) )
272 placementDone = TRUE;
274 area = workspace()->clientArea( PlacementArea, geom.center(),
desktop());
278 if ( (xSizeHint.flags & USSize) || (xSizeHint.flags & PSize) )
283 if (xSizeHint.flags & PMaxSize)
284 geom.setSize( geom.size().boundedTo(
285 rules()->checkMaxSize( TQSize(xSizeHint.max_width, xSizeHint.max_height ) ) ) );
286 if (xSizeHint.flags & PMinSize)
287 geom.setSize( geom.size().expandedTo(
288 rules()->checkMinSize( TQSize(xSizeHint.min_width, xSizeHint.min_height ) ) ) );
292 if( geom.x() > area.right() || geom.y() > area.bottom())
293 placementDone = FALSE;
297 move( geom.x(), geom.y() );
299 updateDecoration(
false );
301 plainResize( rules()->checkSize( sizeForClientSize( geom.size()), !isMapped ));
303 TQPoint forced_pos = rules()->checkPosition( invalidPoint, !isMapped );
304 if( forced_pos != invalidPoint )
307 placementDone =
true;
309 partial_keep_in_area =
true;
310 area = workspace()->clientArea( FullArea, geom.center(),
desktop());
314 workspace()->place(
this, area );
315 placementDone = TRUE;
318 if(( !isSpecialWindow() || isToolbar()) &&
isMovable())
319 keepInArea( area, partial_keep_in_area );
321 XShapeSelectInput( tqt_xdisplay(), window(), ShapeNotifyMask );
322 is_shape = Shape::hasShape( window());
328 if( init_minimize && isTransient())
330 ClientList mainclients = mainClients();
331 for( ClientList::ConstIterator it = mainclients.begin();
332 it != mainclients.end();
334 if( (*it)->isShown(
true ))
335 init_minimize =
false;
338 if( !init_minimize && isTransient() && mainClients().count() > 0 )
340 bool visible_parent =
false;
341 ClientList mainclients = mainClients();
342 for( ClientList::ConstIterator it = mainclients.begin();
343 it != mainclients.end();
345 if( (*it)->isShown(
true ))
346 visible_parent =
true;
347 if( !visible_parent )
349 init_minimize =
true;
359 bool doNotShow =
false;
360 if ( workspace()->isNotManaged(
caption() ) )
368 setKeepAbove( session->keepAbove );
369 setKeepBelow( session->keepBelow );
370 setSkipTaskbar( session->skipTaskbar,
true );
371 setSkipPager( session->skipPager );
372 setShade( session->shaded ? ShadeNormal : ShadeNone );
373 setShadowed( session->shadowed );
374 if( session->maximized != MaximizeRestore )
376 maximize( (MaximizeMode) session->maximized );
377 geom_restore = session->restore;
379 if( session->fullscreen == FullScreenHack )
381 else if( session->fullscreen != FullScreenNone )
383 setFullScreen(
true,
false );
384 geom_fs_restore = session->fsrestore;
389 geom_restore = geometry();
391 && ( width() >= area.width() || height() >= area.height() ) )
395 if ( width() >= area.width() && height() >= area.height() )
397 maximize( Client::MaximizeFull );
398 geom_restore = TQRect();
400 else if ( width() >= area.width() )
402 maximize( Client::MaximizeHorizontal );
403 geom_restore = TQRect();
404 geom_restore.setY( y());
405 geom_restore.setHeight( height());
407 else if ( height() >= area.height() )
409 maximize( Client::MaximizeVertical );
410 geom_restore = TQRect();
411 geom_restore.setX( x());
412 geom_restore.setWidth( width());
419 MaximizeMode maxmode =
static_cast< MaximizeMode
>
420 ((( info->state() & NET::MaxVert ) ? MaximizeVertical : 0 )
421 | (( info->state() & NET::MaxHoriz ) ? MaximizeHorizontal : 0 ));
422 MaximizeMode forced_maxmode = rules()->checkMaximize( maxmode, !isMapped );
425 if( forced_maxmode != MaximizeRestore || maxmode != MaximizeRestore )
426 maximize( forced_maxmode );
429 setShade( rules()->checkShade( info->state() & NET::Shaded ? ShadeNormal : ShadeNone, !isMapped ));
430 setKeepAbove( rules()->checkKeepAbove( info->state() & NET::KeepAbove, !isMapped ));
431 setKeepBelow( rules()->checkKeepBelow( info->state() & NET::KeepBelow, !isMapped ));
432 setSkipTaskbar( rules()->checkSkipTaskbar( info->state() & NET::SkipTaskbar, !isMapped ),
true );
433 setSkipPager( rules()->checkSkipPager( info->state() & NET::SkipPager, !isMapped ));
434 if( info->state() & NET::DemandsAttention )
436 if( info->state() & NET::Modal )
438 if( fullscreen_mode != FullScreenHack && isFullScreenable())
439 setFullScreen( rules()->checkFullScreen( info->state() & NET::FullScreen, !isMapped ),
false );
442 updateAllowedActions(
true );
447 XLowerWindow( tqt_xdisplay(), frameId());
450 user_time = readUserTimeMapTimestamp( asn_valid ? &asn_id : NULL, asn_valid ? &asn_data : NULL, session );
451 group()->updateUserTime( user_time );
456 if( isShown(
true ) && !doNotShow )
459 Notify::raise( Notify::TransNew );
460 if( isNormalWindow())
461 Notify::raise( Notify::New );
465 allow = session->active
466 && ( !workspace()->wasUserInteraction()
467 || workspace()->activeClient() == NULL || workspace()->activeClient()->isDesktop());
469 allow = workspace()->allowClientActivation(
this, userTime(),
false );
473 if( !isOnCurrentDesktop() && !isMapped && !session && ( allow || workspace()->sessionSaving()))
474 workspace()->setCurrentDesktop(
desktop());
476 bool belongs_to_desktop =
false;
477 for( ClientList::ConstIterator it = group()->members().begin();
478 it != group()->members().end();
480 if( (*it)->isDesktop())
482 belongs_to_desktop =
true;
485 if( !belongs_to_desktop && workspace()->showingDesktop())
486 workspace()->resetShowingDesktop( options->showDesktopIsMinimizeAll );
488 if( isOnCurrentDesktop() && !isMapped && !allow )
489 workspace()->restackClientUnderActive(
this );
491 workspace()->raiseClient(
this );
497 if( allow && isOnCurrentDesktop())
499 if( !isSpecialWindow())
500 if ( options->focusPolicyIsReasonable() && wantsTabFocus() )
501 workspace()->requestFocus(
this );
505 if( !session && !isSpecialWindow())
510 else if( !doNotShow )
517 setMappingState( IconicState );
519 assert( mappingState() != WithdrawnState );
521 if( user_time == CurrentTime || user_time == -1U )
523 user_time = get_tqt_x_time() - 1000000;
524 if( user_time == CurrentTime || user_time == -1U )
525 user_time = get_tqt_x_time() - 1000000 + 10;
528 updateWorkareaDiffs();
536 client_rules.discardTemporary();
538 workspace()->discardUsedWindowRules(
this,
false );
554 void Client::embedClient( Window w,
const XWindowAttributes &attr )
556 assert( client == None );
557 assert( frame == None );
558 assert( wrapper == None );
561 XAddToSaveSet( tqt_xdisplay(), client );
562 XSelectInput( tqt_xdisplay(), client, NoEventMask );
563 XUnmapWindow( tqt_xdisplay(), client );
566 XConfigureWindow( tqt_xdisplay(), client, CWBorderWidth, &wc );
568 XSetWindowAttributes swa;
569 swa.colormap = attr.colormap;
570 swa.background_pixmap = None;
571 swa.border_pixel = 0;
573 frame = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), 0, 0, 1, 1, 0,
574 attr.depth, InputOutput, attr.visual,
575 CWColormap | CWBackPixmap | CWBorderPixel, &swa );
576 wrapper = XCreateWindow( tqt_xdisplay(), frame, 0, 0, 1, 1, 0,
577 attr.depth, InputOutput, attr.visual,
578 CWColormap | CWBackPixmap | CWBorderPixel, &swa );
580 XDefineCursor( tqt_xdisplay(), frame, TQt::arrowCursor.handle());
582 XDefineCursor( tqt_xdisplay(), wrapper, TQt::arrowCursor.handle());
583 XReparentWindow( tqt_xdisplay(), client, wrapper, 0, 0 );
584 XSelectInput( tqt_xdisplay(), frame,
585 KeyPressMask | KeyReleaseMask |
586 ButtonPressMask | ButtonReleaseMask |
590 EnterWindowMask | LeaveWindowMask |
594 StructureNotifyMask | SubstructureRedirectMask );
595 XSelectInput( tqt_xdisplay(), wrapper, ClientWinMask | SubstructureNotifyMask );
596 XSelectInput( tqt_xdisplay(), client,
600 EnterWindowMask | LeaveWindowMask |
601 KeyPressMask | KeyReleaseMask
The Client class encapsulates a window decoration frame.
bool manage(Window w, bool isMapped)
void minimize(bool avoid_animation=false)
static TQCString staticWindowRole(WId)
TQString caption(bool full=true) const
void move(int x, int y, ForceGeometry_t force=NormalGeometrySet)