diff --git a/activation.cpp b/activation.cpp index 4f426f02d..44e5b004e 100644 --- a/activation.cpp +++ b/activation.cpp @@ -1,880 +1,916 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 1999, 2000 Matthias Ettrich Copyright (C) 2003 Lubos Lunak You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ /* This file contains things relevant to window activation and focus stealing prevention. */ #include "client.h" #include "workspace.h" #include #include #include #include +#include +#include #include "notifications.h" #include "atoms.h" #include "group.h" #include "rules.h" extern Time qt_x_time; namespace KWinInternal { /* Prevention of focus stealing: KWin tries to prevent unwanted changes of focus, that would result from mapping a new window. Also, some nasty applications may try to force focus change even in cases when ICCCM 4.2.7 doesn't allow it (e.g. they may try to activate their main window because the user definitely "needs" to see something happened - misusing of QWidget::setActiveWindow() may be such case). There are 4 ways how a window may become active: - the user changes the active window (e.g. focus follows mouse, clicking on some window's titlebar) - the change of focus will be done by KWin, so there's nothing to solve in this case - the change of active window will be requested using the _NET_ACTIVE_WINDOW message (handled in RootInfo::changeActiveWindow()) - such requests will be obeyed, because this request is meant mainly for e.g. taskbar asking the WM to change the active window as a result of some user action. Normal applications should use this request only rarely in special cases. See also below the discussion of _NET_ACTIVE_WINDOW_TRANSFER. - the change of active window will be done by performing XSetInputFocus() on a window that's not currently active. ICCCM 4.2.7 describes when the application may perform change of input focus. In order to handle misbehaving applications, KWin will try to detect focus changes to windows that don't belong to currently active application, and restore focus back to the currently active window, instead of activating the window that got focus (unfortunately there's no way to FocusChangeRedirect similar to e.g. SubstructureRedirect, so there will be short time when the focus will be changed). The check itself that's done is Workspace::allowClientActivation() (see below). - a new window will be mapped - this is the most complicated case. If the new window belongs to the currently active application, it may be safely mapped on top and activated. The same if there's no active window, or the active window is the desktop. These checks are done by Workspace::allowClientActivation(). Following checks need to compare times. One time is the timestamp of last user action in the currently active window, the other time is the timestamp of the action that originally caused mapping of the new window (e.g. when the application was started). If the first time is newer than the second one, the window will not be activated, as that indicates futher user actions took place after the action leading to this new mapped window. This check is done by Workspace::allowClientActivation(). There are several ways how to get the timestamp of action that caused the new mapped window (done in Client::readUserTimeMapTimestamp()) : - the window may have the _NET_WM_USER_TIME property. This way the application may either explicitly request that the window is not activated (by using 0 timestamp), or the property contains the time of last user action in the application. - KWin itself tries to detect time of last user action in every window, by watching KeyPress and ButtonPress events on windows. This way some events may be missed (if they don't propagate to the toplevel window), but it's good as a fallback for applications that don't provide _NET_WM_USER_TIME, and missing some events may at most lead to unwanted focus stealing. - the timestamp may come from application startup notification. Application startup notification, if it exists for the new mapped window, should include time of the user action that caused it. - if there's no timestamp available, it's checked whether the new window belongs to some already running application - if yes, the timestamp will be 0 (i.e. refuse activation) - if the window is from session restored window, the timestamp will be 0 too, unless this application was the active one at the time when the session was saved, in which case the window will be activated if there wasn't any user interaction since the time KWin was started. - as the last resort, the _KDE_NET_USER_CREATION_TIME timestamp is used. For every toplevel window that is created (see CreateNotify handling), this property is set to the at that time current time. Since at this time it's known that the new window doesn't belong to any existing application (better said, the application doesn't have any other window mapped), it is either the very first window of the application, or its the only window of the application that was hidden before. The latter case is handled by removing the property from windows before withdrawing them, making the timestamp empty for next mapping of the window. In the sooner case, the timestamp will be used. This helps in case when an application is launched without application startup notification, it creates its mainwindow, and starts its initialization (that may possibly take long time). The timestamp used will be older than any user action done after launching this application. - if no timestamp is found at all, the window is activated. The check whether two windows belong to the same application (same process) is done in Client::belongToSameApplication(). Not 100% reliable, but hopefully 99,99% reliable. As a somewhat special case, window activation is always enabled when session saving is in progress. When session saving, the session manager allows only one application to interact with the user. Not allowing window activation in such case would result in e.g. dialogs not becoming active, so focus stealing prevention would cause here more harm than good. Windows that attempted to become active but KWin prevented this will be marked as demanding user attention. They'll get the _NET_WM_STATE_DEMANDS_ATTENTION state, and the taskbar should mark them specially (blink, etc.). The state will be reset when the window eventually really becomes active. There are one more ways how a window can become obstrusive, window stealing focus: By showing above the active window, by either raising itself, or by moving itself on the active desktop. - KWin will refuse raising non-active window above the active one, unless they belong to the same application. Applications shouldn't raise their windows anyway (unless the app wants to raise one of its windows above another of its windows). - KWin activates windows moved to the current desktop (as that seems logical from the user's point of view, after sending the window there directly from KWin, or e.g. using pager). This means applications shouldn't send their windows to another desktop (SELI TODO - but what if they do?) Special cases I can think of: - konqueror reusing, i.e. kfmclient tells running Konqueror instance to open new window - without focus stealing prevention - no problem - with ASN (application startup notification) - ASN is forwarded, and because it's newer than the instance's user timestamp, it takes precedence - without ASN - user timestamp needs to be reset, otherwise it would be used, and it's old; moreover this new window mustn't be detected as window belonging to already running application, or it wouldn't be activated - see Client::sameAppWindowRoleMatch() for the (rather ugly) hack - konqueror preloading, i.e. window is created in advance, and kfmclient tells this Konqueror instance to show it later - without focus stealing prevention - no problem - with ASN - ASN is forwarded, and because it's newer than the instance's user timestamp, it takes precedence - without ASN - user timestamp needs to be reset, otherwise it would be used, and it's old; also, creation timestamp is changed to the time the instance starts (re-)initializing the window, this ensures creation timestamp will still work somewhat even in this case - KUniqueApplication - when the window is already visible, and the new instance wants it to activate - without focus stealing prevention - _NET_ACTIVE_WINDOW - no problem - with ASN - ASN is forwarded, and set on the already visible window, KWin treats the window as new with that ASN - without ASN - _NET_ACTIVE_WINDOW as application request is used, and there's no really usable timestamp, only timestamp from the time the (new) application instance was started, so KWin will activate the window *sigh* - the bad thing here is that there's absolutely no chance to recognize the case of starting this KUniqueApp from Konsole (and thus wanting the already visible window to become active) from the case when something started this KUniqueApp without ASN (in which case the already visible window shouldn't become active) - the only solution is using ASN for starting applications, at least silent (i.e. without feedback) - when one application wants to activate another application's window (e.g. KMail activating already running KAddressBook window ?) - without focus stealing prevention - _NET_ACTIVE_WINDOW - no problem - with ASN - can't be here, it's the KUniqueApp case then - without ASN - _NET_ACTIVE_WINDOW as application request should be used, KWin will activate the new window depending on the timestamp and whether it belongs to the currently active application _NET_ACTIVE_WINDOW usage: data.l[0]= 1 ->app request = 2 ->pager request = 0 - backwards compatibility data.l[1]= timestamp */ //**************************************** // Workspace //**************************************** /*! 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(). And of course, to propagate the active client to the world. */ void Workspace::setActiveClient( Client* c, allowed_t ) { if ( active_client == c ) return; if( active_popup && active_popup_client != c && set_active_client_recursion == 0 ) closeActivePopup(); StackingUpdatesBlocker blocker( this ); ++set_active_client_recursion; if( active_client != NULL ) { // note that this may call setActiveClient( NULL ), therefore the recursion counter active_client->setActive( false, !c || !c->isModal() || c != active_client->transientFor() ); } active_client = c; Q_ASSERT( c == NULL || c->isActive()); if( active_client != NULL ) last_active_client = active_client; if ( active_client ) { focus_chain.remove( c ); if ( c->wantsTabFocus() ) focus_chain.append( c ); active_client->demandAttention( false ); } pending_take_activity = NULL; updateCurrentTopMenu(); updateToolWindows( false ); updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active rootInfo->setActiveWindow( active_client? active_client->window() : 0 ); updateColormap(); --set_active_client_recursion; } /*! Tries to activate the client \a c. This function performs what you expect when clicking the respective entry in a taskbar: showing and raising the client (this may imply switching to the another virtual desktop) and putting the focus onto it. Once X really gave focus to the client window as requested, the client itself will call setActiveClient() and the operation is complete. This may not happen with certain focus policies, though. \sa stActiveClient(), requestFocus() */ void Workspace::activateClient( Client* c, bool force ) { if( c == NULL ) { setActiveClient( NULL, Allowed ); return; } raiseClient( c ); if (!c->isOnDesktop(currentDesktop()) ) { ++block_focus; setCurrentDesktop( c->desktop() ); --block_focus; } if( c->isMinimized()) c->unminimize(); // TODO force should perhaps allow this only if the window already contains the mouse if( options->focusPolicyIsReasonable() || force ) requestFocus( c, force ); // Don't update user time for clients that have focus stealing workaround. // As they usually belong to the current active window but fail to provide // this information, updating their user time would make the user time // of the currently active window old, and reject further activation for it. // E.g. typing URL in minicli which will show kio_uiserver dialog (with workaround), // and then kdesktop shows dialog about SSL certificate. // This needs also avoiding user creation time in Client::readUserTimeMapTimestamp(). if( !c->ignoreFocusStealing()) c->updateUserTime(); } /*! Tries to activate the client by asking X for the input focus. This function does not perform any show, raise or desktop switching. See Workspace::activateClient() instead. \sa Workspace::activateClient() */ void Workspace::requestFocus( Client* c, bool force ) { takeActivity( c, ActivityFocus | ( force ? ActivityFocusForce : 0 ), false); } void Workspace::takeActivity( Client* c, int flags, bool handled ) { // the 'if( c == active_client ) return;' optimization mustn't be done here if (!focusChangeEnabled() && ( c != active_client) ) flags &= ~ActivityFocus; if ( !c ) { focusToNull(); return; } if( flags & ActivityFocus ) { Client* modal = c->findModal(); if( modal != NULL && modal != c ) { if( !modal->isOnDesktop( c->desktop())) { modal->setDesktop( c->desktop()); if( modal->desktop() != c->desktop()) // forced desktop activateClient( modal ); } // if the click was inside the window (i.e. handled is set), // but it has a modal, there's no need to use handled mode, because // the modal doesn't get the click anyway // raising of the original window needs to be still done if( flags & ActivityRaise ) raiseClient( c ); c = modal; handled = false; } cancelDelayFocus(); } if ( !( flags & ActivityFocusForce ) && ( c->isTopMenu() || c->isDock() || c->isSplash()) ) flags &= ~ActivityFocus; // toplevel menus and dock windows don't take focus if not forced if( c->isShade()) { if( c->wantsInput() && ( flags & ActivityFocus )) { // client cannot accept focus, but at least the window should be active (window menu, et. al. ) c->setActive( true ); focusToNull(); } flags &= ~ActivityFocus; handled = false; // no point, can't get clicks } if( !c->isShown( true )) // shouldn't happen, call activateClient() if needed { kdWarning( 1212 ) << "takeActivity: not shown" << endl; return; } c->takeActivity( flags, handled, Allowed ); } void Workspace::handleTakeActivity( Client* c, Time /*timestamp*/, int flags ) { if( pending_take_activity != c ) // pending_take_activity is reset when doing restack or activation return; if(( flags & ActivityRaise ) != 0 ) raiseClient( c ); if(( flags & ActivityFocus ) != 0 && c->isShown( false )) c->takeFocus( Allowed ); pending_take_activity = NULL; } /*! Informs the workspace that the client \a c has been hidden. If it was the active client (or to-become the active client), the workspace activates another one. \a c may already be destroyed */ void Workspace::clientHidden( Client* c ) { assert( !c->isShown( true ) || !c->isOnCurrentDesktop()); activateNextClient( c ); } // deactivates 'c' and activates next client bool Workspace::activateNextClient( Client* c ) { // if 'c' is not the active or the to-become active one, do nothing if( !( c == active_client || ( should_get_focus.count() > 0 && c == should_get_focus.last()))) return false; closeActivePopup(); if( c != NULL ) { if( c == active_client ) setActiveClient( NULL, Allowed ); should_get_focus.remove( c ); } if( focusChangeEnabled()) { if ( c != NULL && c->wantsTabFocus() && focus_chain.contains( c ) ) { focus_chain.remove( c ); focus_chain.prepend( c ); } if ( options->focusPolicyIsReasonable()) { // search the focus_chain for a client to transfer focus to // if 'c' is transient, transfer focus to the first suitable mainwindow Client* get_focus = NULL; const ClientList mainwindows = ( c != NULL ? c->mainClients() : ClientList()); for( ClientList::ConstIterator it = focus_chain.fromLast(); it != focus_chain.end(); --it ) { if( !(*it)->isShown( false ) || !(*it)->isOnCurrentDesktop()) continue; if( mainwindows.contains( *it )) { get_focus = *it; break; } if( get_focus == NULL ) get_focus = *it; } if( get_focus == NULL ) get_focus = findDesktop( true, currentDesktop()); if( get_focus != NULL ) requestFocus( get_focus ); else focusToNull(); } else return false; } else // if blocking focus, move focus to the desktop later if needed // in order to avoid flickering focusToNull(); return true; } void Workspace::gotFocusIn( const Client* c ) { if( should_get_focus.contains( const_cast< Client* >( c ))) { // remove also all sooner elements that should have got FocusIn, // but didn't for some reason (and also won't anymore, because they were sooner) while( should_get_focus.first() != c ) should_get_focus.pop_front(); should_get_focus.pop_front(); // remove 'c' } } void Workspace::setShouldGetFocus( Client* c ) { should_get_focus.append( c ); updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active } // focus_in -> the window got FocusIn event // session_active -> the window was active when saving session bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in ) { // options->focusStealingPreventionLevel : // 0 - none - old KWin behaviour, new windows always get focus // 1 - low - focus stealing prevention is applied normally, when unsure, activation is allowed // 2 - normal - focus stealing prevention is applied normally, when unsure, activation is not allowed, // this is the default // 3 - high - new window gets focus only if it belongs to the active application, // or when no window is currently active // 4 - extreme - no window gets focus without user intervention if( time == -1U ) time = c->userTime(); int level = c->rules()->checkFSP( options->focusStealingPreventionLevel ); if( session_saving && level <= 2 ) // <= normal { return true; } Client* ac = mostRecentlyActivatedClient(); if( focus_in ) { if( should_get_focus.contains( const_cast< Client* >( c ))) return true; // FocusIn was result of KWin's action // Before getting FocusIn, the active Client already // got FocusOut, and therefore got deactivated. ac = last_active_client; } if( time == 0 ) // explicitly asked not to get focus return false; if( level == 0 ) // none return true; if( level == 4 ) // extreme return false; if( !c->isOnCurrentDesktop()) return false; // allow only with level == 0 if( c->ignoreFocusStealing()) return true; if( ac == NULL || ac->isDesktop()) { kdDebug( 1212 ) << "Activation: No client active, allowing" << endl; return true; // no active client -> always allow } // TODO window urgency -> return true? if( Client::belongToSameApplication( c, ac, true )) { kdDebug( 1212 ) << "Activation: Belongs to active application" << endl; return true; } if( level == 3 ) // high return false; if( time == -1U ) // no time known { kdDebug( 1212 ) << "Activation: No timestamp at all" << endl; if( level == 1 ) // low return true; // no timestamp at all, don't activate - because there's also creation timestamp // done on CreateNotify, this case should happen only in case application // maps again already used window, i.e. this won't happen after app startup return false; } // level == 2 // normal Time user_time = ac->userTime(); kdDebug( 1212 ) << "Activation, compared:" << c << ":" << time << ":" << user_time << ":" << ( timestampCompare( time, user_time ) >= 0 ) << endl; return timestampCompare( time, user_time ) >= 0; // time >= user_time } // basically the same like allowClientActivation(), this time allowing // a window to be fully raised upon its own request (XRaiseWindow), // if refused, it will be raised only on top of windows belonging // to the same application bool Workspace::allowFullClientRaising( const Client* c, Time time ) { int level = c->rules()->checkFSP( options->focusStealingPreventionLevel ); if( session_saving && level <= 2 ) // <= normal { return true; } Client* ac = mostRecentlyActivatedClient(); if( level == 0 ) // none return true; if( level == 4 ) // extreme return false; if( ac == NULL || ac->isDesktop()) { kdDebug( 1212 ) << "Raising: No client active, allowing" << endl; return true; // no active client -> always allow } if( c->ignoreFocusStealing()) return true; // TODO window urgency -> return true? if( Client::belongToSameApplication( c, ac, true )) { kdDebug( 1212 ) << "Raising: Belongs to active application" << endl; return true; } if( level == 3 ) // high return false; Time user_time = ac->userTime(); kdDebug( 1212 ) << "Raising, compared:" << time << ":" << user_time << ":" << ( timestampCompare( time, user_time ) >= 0 ) << endl; return timestampCompare( time, user_time ) >= 0; // time >= user_time } // called from Client after FocusIn that wasn't initiated by KWin and the client // wasn't allowed to activate void Workspace::restoreFocus() { // this updateXTime() is necessary - as FocusIn events don't have // a timestamp *sigh*, kwin's timestamp would be older than the timestamp // that was used by whoever caused the focus change, and therefore // the attempt to restore the focus would fail due to old timestamp updateXTime(); if( should_get_focus.count() > 0 ) requestFocus( should_get_focus.last()); else if( last_active_client ) requestFocus( last_active_client ); } void Workspace::clientAttentionChanged( Client* c, bool set ) { if( set ) { attention_chain.remove( c ); attention_chain.prepend( c ); } else attention_chain.remove( c ); } // This is used when a client should be shown active immediately after requestFocus(), // without waiting for the matching FocusIn that will really make the window the active one. // Used only in special cases, e.g. for MouseActivateRaiseandMove with transparent windows, bool Workspace::fakeRequestedActivity( Client* c ) { if( should_get_focus.count() > 0 && should_get_focus.last() == c ) { if( c->isActive()) return false; c->setActive( true ); return true; } return false; } void Workspace::unfakeActivity( Client* c ) { if( should_get_focus.count() > 0 && should_get_focus.last() == c ) { // TODO this will cause flicker, and probably is not needed if( last_active_client != NULL ) last_active_client->setActive( true ); else c->setActive( false ); } } //******************************************** // Client //******************************************** /*! Updates the user time (time of last action in the active window). This is called inside kwin for every action with the window that qualifies for user interaction (clicking on it, activate it externally, etc.). */ void Client::updateUserTime( Time time ) { // copied in Group::updateUserTime if( time == CurrentTime ) time = qt_x_time; if( time != -1U && ( user_time == CurrentTime || timestampCompare( time, user_time ) > 0 )) // time > user_time user_time = time; } Time Client::readUserCreationTime() const { long result = -1; // Time == -1 means none Atom type; int format, status; unsigned long nitems = 0; unsigned long extra = 0; unsigned char *data = 0; KXErrorHandler handler; // ignore errors? status = XGetWindowProperty( qt_xdisplay(), window(), atoms->kde_net_wm_user_creation_time, 0, 10000, FALSE, XA_CARDINAL, &type, &format, &nitems, &extra, &data ); if (status == Success ) { if (data && nitems > 0) result = *((long*) data); XFree(data); } return result; } void Client::demandAttention( bool set ) { if( isActive()) set = false; - info->setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention ); + if( demands_attention == set ) + return; + demands_attention = set; + if( demands_attention ) + { + // Demand attention flag is often set right from manage(), when focus stealing prevention + // steps in. At that time the window has no taskbar entry yet, so KNotify cannot place + // e.g. the passive popup next to it. So wait up to 1 second for the icon geometry + // to be set. + // Delayed call to KNotify also solves the problem of having X server grab in manage(), + // which may deadlock when KNotify (or KLauncher when launching KNotify) need to access X. + Notify::Event e = isOnCurrentDesktop() ? Notify::DemandAttentionCurrent : Notify::DemandAttentionOther; + // Setting the demands attention state needs to be done directly in KWin, because + // KNotify would try to set it, resulting in a call to KNotify again, etc. + if( Notify::makeDemandAttention( e )) + info->setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention ); + + if( demandAttentionKNotifyTimer == NULL ) + { + demandAttentionKNotifyTimer = new QTimer( this ); + connect( demandAttentionKNotifyTimer, SIGNAL( timeout()), SLOT( demandAttentionKNotify())); + } + demandAttentionKNotifyTimer->start( 1000, true ); + } + else + info->setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention ); workspace()->clientAttentionChanged( this, set ); } +void Client::demandAttentionKNotify() + { + Notify::Event e = isOnCurrentDesktop() ? Notify::DemandAttentionCurrent : Notify::DemandAttentionOther; + Notify::raise( e, i18n( "Window '%1' demands attention." ).arg( KStringHandler::csqueeze(caption())), this ); + demandAttentionKNotifyTimer->stop(); + demandAttentionKNotifyTimer->deleteLater(); + demandAttentionKNotifyTimer = NULL; + } + // TODO I probably shouldn't be lazy here and do it without the macro, so that people can read it KWIN_COMPARE_PREDICATE( SameApplicationActiveHackPredicate, const Client*, // ignore already existing splashes, toolbars, utilities, menus and topmenus, // as the app may show those before the main window !cl->isSplash() && !cl->isToolbar() && !cl->isTopMenu() && !cl->isUtility() && !cl->isMenu() && Client::belongToSameApplication( cl, value, true ) && cl != value); Time Client::readUserTimeMapTimestamp( const KStartupInfoId* asn_id, const KStartupInfoData* asn_data, bool session ) const { Time time = info->userTime(); kdDebug( 1212 ) << "User timestamp, initial:" << time << endl; // newer ASN timestamp always replaces user timestamp, unless user timestamp is 0 // helps e.g. with konqy reusing if( asn_data != NULL && time != 0 ) { // prefer timestamp from ASN id (timestamp from data is obsolete way) if( asn_id->timestamp() != 0 && ( time == -1U || timestampCompare( asn_id->timestamp(), time ) > 0 )) { time = asn_id->timestamp(); } else if( asn_data->timestamp() != -1U && ( time == -1U || timestampCompare( asn_data->timestamp(), time ) > 0 )) { time = asn_data->timestamp(); } } kdDebug( 1212 ) << "User timestamp, ASN:" << time << endl; if( time == -1U ) { // The window doesn't have any timestamp. // If it's the first window for its application // (i.e. there's no other window from the same app), // use the _KDE_NET_WM_USER_CREATION_TIME trick. // Otherwise, refuse activation of a window // from already running application if this application // is not the active one (unless focus stealing prevention is turned off). Client* act = workspace()->mostRecentlyActivatedClient(); if( act != NULL && !belongToSameApplication( act, this, true )) { bool first_window = true; if( isTransient()) { if( act->hasTransient( this, true )) ; // is transient for currently active window, even though it's not // the same app (e.g. kcookiejar dialog) -> allow activation else if( groupTransient() && findClientInList( mainClients(), SameApplicationActiveHackPredicate( this )) == NULL ) ; // standalone transient else first_window = false; } else { if( workspace()->findClient( SameApplicationActiveHackPredicate( this ))) first_window = false; } // don't refuse if focus stealing prevention is turned off if( !first_window && rules()->checkFSP( options->focusStealingPreventionLevel ) > 0 ) { kdDebug( 1212 ) << "User timestamp, already exists:" << 0 << endl; return 0; // refuse activation } } // Creation time would just mess things up during session startup, // as possibly many apps are started up at the same time. // If there's no active window yet, no timestamp will be needed, // as plain Workspace::allowClientActivation() will return true // in such case. And if there's already active window, // it's better not to activate the new one. // Unless it was the active window at the time // of session saving and there was no user interaction yet, // this check will be done in manage(). if( session ) return -1U; if( ignoreFocusStealing() && act != NULL ) time = act->userTime(); else time = readUserCreationTime(); } kdDebug( 1212 ) << "User timestamp, final:" << this << ":" << time << endl; return time; } Time Client::userTime() const { Time time = user_time; if( time == 0 ) // doesn't want focus after showing return 0; assert( group() != NULL ); if( time == -1U || ( group()->userTime() != -1U && timestampCompare( group()->userTime(), time ) > 0 )) time = group()->userTime(); return time; } /*! Sets the client's active state to \a act. This function does only change the visual appearance of the client, it does not change the focus setting. Use Workspace::activateClient() or Workspace::requestFocus() instead. If a client receives or looses the focus, it calls setActive() on its own. */ void Client::setActive( bool act, bool updateOpacity_) { if ( active == act ) return; active = act; workspace()->setActiveClient( act ? this : NULL, Allowed ); if (updateOpacity_) updateOpacity(); if (isModal() && transientFor()) { if (!act) transientFor()->updateOpacity(); else if (!transientFor()->custom_opacity) transientFor()->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity); } updateShadowSize(); if ( active ) Notify::raise( Notify::Activate ); if( !active ) cancelAutoRaise(); if( !active && shade_mode == ShadeActivated ) setShade( ShadeNormal ); StackingUpdatesBlocker blocker( workspace()); workspace()->updateClientLayer( this ); // active windows may get different layer // TODO optimize? mainClients() may be a bit expensive ClientList mainclients = mainClients(); for( ClientList::ConstIterator it = mainclients.begin(); it != mainclients.end(); ++it ) if( (*it)->isFullScreen()) // fullscreens go high even if their transient is active workspace()->updateClientLayer( *it ); if( decoration != NULL ) decoration->activeChange(); updateMouseGrab(); updateUrgency(); // demand attention again if it's still urgent } void Client::startupIdChanged() { KStartupInfoId asn_id; KStartupInfoData asn_data; bool asn_valid = workspace()->checkStartupNotification( window(), asn_id, asn_data ); if( !asn_valid ) return; if( asn_data.desktop() != 0 ) workspace()->sendClientToDesktop( this, asn_data.desktop(), true ); Time timestamp = asn_id.timestamp(); if( timestamp == 0 && asn_data.timestamp() != -1U ) timestamp = asn_data.timestamp(); if( timestamp != 0 ) { bool activate = workspace()->allowClientActivation( this, timestamp ); if( asn_data.desktop() != 0 && !isOnCurrentDesktop()) activate = false; // it was started on different desktop than current one if( activate ) workspace()->activateClient( this ); else demandAttention(); } } void Client::updateUrgency() { if( urgency ) demandAttention(); } void Client::shortcutActivated() { workspace()->activateClient( this, true ); // force } //**************************************** // Group //**************************************** void Group::startupIdChanged() { KStartupInfoId asn_id; KStartupInfoData asn_data; bool asn_valid = workspace()->checkStartupNotification( leader_wid, asn_id, asn_data ); if( !asn_valid ) return; if( asn_id.timestamp() != 0 && user_time != -1U && timestampCompare( asn_id.timestamp(), user_time ) > 0 ) { user_time = asn_id.timestamp(); } else if( asn_data.timestamp() != -1U && user_time != -1U && timestampCompare( asn_data.timestamp(), user_time ) > 0 ) { user_time = asn_data.timestamp(); } } void Group::updateUserTime( Time time ) { // copy of Client::updateUserTime if( time == CurrentTime ) time = qt_x_time; if( time != -1U && ( user_time == CurrentTime || timestampCompare( time, user_time ) > 0 )) // time > user_time user_time = time; } } // namespace diff --git a/client.cpp b/client.cpp index f91cdd6fd..fa82c59ae 100644 --- a/client.cpp +++ b/client.cpp @@ -1,2087 +1,2089 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 1999, 2000 Matthias Ettrich Copyright (C) 2003 Lubos Lunak You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #include "client.h" #include #include #include #include #include #include #include #include #include #include #include "bridge.h" #include "group.h" #include "workspace.h" #include "atoms.h" #include "notifications.h" #include "rules.h" #include // put all externs before the namespace statement to allow the linker // to resolve them properly extern Atom qt_wm_state; extern Time qt_x_time; extern Atom qt_window_role; extern Atom qt_sm_client_id; namespace KWinInternal { /* Creating a client: - only by calling Workspace::createClient() - it creates a new client and calls manage() for it Destroying a client: - destroyClient() - only when the window itself has been destroyed - releaseWindow() - the window is kept, only the client itself is destroyed */ /*! \class Client client.h \brief The Client class encapsulates a window decoration frame. */ /*! This ctor is "dumb" - it only initializes data. All the real initialization is done in manage(). */ Client::Client( Workspace *ws ) : QObject( NULL ), client( None ), wrapper( None ), frame( None ), decoration( NULL ), wspace( ws ), bridge( new Bridge( this )), move_faked_activity( false ), move_resize_grab_window( None ), transient_for( NULL ), transient_for_id( None ), original_transient_for_id( None ), in_group( NULL ), window_group( None ), in_layer( UnknownLayer ), ping_timer( NULL ), process_killer( NULL ), user_time( CurrentTime ), // not known yet allowed_actions( 0 ), block_geometry( 0 ), shade_geometry_change( false ), border_left( 0 ), border_right( 0 ), border_top( 0 ), - border_bottom( 0 ) + border_bottom( 0 ), + demandAttentionKNotifyTimer( NULL ) // SELI do all as initialization { autoRaiseTimer = 0; shadeHoverTimer = 0; // set the initial mapping state mapping_state = WithdrawnState; desk = 0; // no desktop yet mode = PositionCenter; buttonDown = FALSE; moveResizeMode = FALSE; info = NULL; shade_mode = ShadeNone; active = FALSE; deleting = false; keep_above = FALSE; keep_below = FALSE; is_shape = FALSE; motif_noborder = false; motif_may_move = TRUE; motif_may_resize = TRUE; motif_may_close = TRUE; fullscreen_mode = FullScreenNone; skip_taskbar = FALSE; original_skip_taskbar = false; minimized = false; hidden = false; modal = false; noborder = false; user_noborder = false; not_obscured = false; urgency = false; ignore_focus_stealing = false; + demands_attention = false; check_active_modal = false; Pdeletewindow = 0; Ptakefocus = 0; Ptakeactivity = 0; Pcontexthelp = 0; Pping = 0; input = FALSE; skip_pager = FALSE; max_mode = MaximizeRestore; cmap = None; frame_geometry = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0) client_size = QSize( 100, 100 ); custom_opacity = false; rule_opacity_active = 0;; //translucency rules rule_opacity_inactive = 0; //dito. // SELI initialize xsizehints?? } /*! "Dumb" destructor. */ Client::~Client() { assert(!moveResizeMode); assert( client == None ); assert( frame == None && wrapper == None ); assert( decoration == NULL ); assert( block_geometry == 0 ); assert( !check_active_modal ); delete info; delete bridge; } // use destroyClient() or releaseWindow(), Client instances cannot be deleted directly void Client::deleteClient( Client* c, allowed_t ) { delete c; } /*! Releases the window. The client has done its job and the window is still existing. */ void Client::releaseWindow( bool on_shutdown ) { assert( !deleting ); deleting = true; StackingUpdatesBlocker blocker( workspace()); if (!custom_opacity) setOpacity(FALSE); if (moveResizeMode) leaveMoveResize(); finishWindowRules(); ++block_geometry; setMappingState( WithdrawnState ); setModal( false ); // otherwise its mainwindow wouldn't get focus hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags) if( !on_shutdown ) workspace()->clientHidden( this ); XUnmapWindow( qt_xdisplay(), frameId()); // destroying decoration would cause ugly visual effect destroyDecoration(); cleanGrouping(); if( !on_shutdown ) { workspace()->removeClient( this, Allowed ); // only when the window is being unmapped, not when closing down KWin // (NETWM sections 5.5,5.7) info->setDesktop( 0 ); desk = 0; info->setState( 0, info->state()); // reset all state flags } XDeleteProperty( qt_xdisplay(), client, atoms->kde_net_wm_user_creation_time); // TODO remove KDEFrameStrut property XReparentWindow( qt_xdisplay(), client, workspace()->rootWin(), x(), y()); XRemoveFromSaveSet( qt_xdisplay(), client ); XSelectInput( qt_xdisplay(), client, NoEventMask ); if( on_shutdown ) { // map the window, so it can be found after another WM is started XMapWindow( qt_xdisplay(), client ); // TODO preserve minimized, shaded etc. state? } else { // Make sure it's not mapped if the app unmapped it (#65279). The app // may do map+unmap before we initially map the window by calling rawShow() from manage(). XUnmapWindow( qt_xdisplay(), client ); } client = None; XDestroyWindow( qt_xdisplay(), wrapper ); wrapper = None; XDestroyWindow( qt_xdisplay(), frame ); frame = None; --block_geometry; deleteClient( this, Allowed ); } // like releaseWindow(), but this one is called when the window has been already destroyed // (e.g. the application closed it) void Client::destroyClient() { assert( !deleting ); deleting = true; StackingUpdatesBlocker blocker( workspace()); if (moveResizeMode) leaveMoveResize(); finishWindowRules(); ++block_geometry; setModal( false ); hidden = true; // so that it's not considered visible anymore workspace()->clientHidden( this ); destroyDecoration(); cleanGrouping(); workspace()->removeClient( this, Allowed ); client = None; // invalidate XDestroyWindow( qt_xdisplay(), wrapper ); wrapper = None; XDestroyWindow( qt_xdisplay(), frame ); frame = None; --block_geometry; deleteClient( this, Allowed ); } void Client::updateDecoration( bool check_workspace_pos, bool force ) { if( !force && (( decoration == NULL && noBorder()) || ( decoration != NULL && !noBorder()))) return; bool do_show = false; ++block_geometry; if( force ) destroyDecoration(); if( !noBorder()) { decoration = workspace()->createDecoration( bridge ); // TODO check decoration's minimum size? decoration->init(); decoration->widget()->installEventFilter( this ); XReparentWindow( qt_xdisplay(), decoration->widget()->winId(), frameId(), 0, 0 ); decoration->widget()->lower(); decoration->borders( border_left, border_right, border_top, border_bottom ); setXTitleHeightProperty(border_top); int save_workarea_diff_x = workarea_diff_x; int save_workarea_diff_y = workarea_diff_y; move( calculateGravitation( false )); if( !isShade()) plainResize( sizeForClientSize( clientSize()), ForceGeometrySet ); else plainResize( sizeForClientSize( QSize( clientSize().width(), 0 ), SizemodeShaded ), ForceGeometrySet ); workarea_diff_x = save_workarea_diff_x; workarea_diff_y = save_workarea_diff_y; do_show = true; } else destroyDecoration(); if( check_workspace_pos ) checkWorkspacePosition(); --block_geometry; setGeometry( geometry(), ForceGeometrySet ); if( do_show ) decoration->widget()->show(); updateFrameStrut(); } void Client::destroyDecoration() { if( decoration != NULL ) { delete decoration; decoration = NULL; QPoint grav = calculateGravitation( true ); border_left = border_right = border_top = border_bottom = 0; setMask( QRegion()); // reset shape mask int save_workarea_diff_x = workarea_diff_x; int save_workarea_diff_y = workarea_diff_y; if( !isShade()) plainResize( sizeForClientSize( clientSize()), ForceGeometrySet ); else plainResize( sizeForClientSize( QSize( clientSize().width(), 0 ), SizemodeShaded ), ForceGeometrySet ); move( grav ); workarea_diff_x = save_workarea_diff_x; workarea_diff_y = save_workarea_diff_y; } } void Client::checkBorderSizes() { if( decoration == NULL ) return; int new_left, new_right, new_top, new_bottom; decoration->borders( new_left, new_right, new_top, new_bottom ); if( new_left == border_left && new_right == border_right && new_top == border_top && new_bottom == border_bottom ) return; ++block_geometry; move( calculateGravitation( true )); border_left = new_left; border_right = new_right; if (border_top != new_top) setXTitleHeightProperty(new_top); border_top = new_top; border_bottom = new_bottom; move( calculateGravitation( false )); plainResize( sizeForClientSize( clientSize()), ForceGeometrySet ); checkWorkspacePosition(); --block_geometry; setGeometry( geometry(), ForceGeometrySet ); } void Client::detectNoBorder() { if( Shape::hasShape( window())) { noborder = true; return; } switch( windowType()) { case NET::Desktop : case NET::Dock : case NET::TopMenu : case NET::Splash : noborder = true; break; case NET::Unknown : case NET::Normal : case NET::Toolbar : case NET::Menu : case NET::Dialog : case NET::Utility : noborder = false; setShapable(FALSE); break; default: assert( false ); } // NET::Override is some strange beast without clear definition, usually // just meaning "noborder", so let's treat it only as such flag, and ignore it as // a window type otherwise (SUPPORTED_WINDOW_TYPES_MASK doesn't include it) if( info->windowType( SUPPORTED_WINDOW_TYPES_MASK | NET::OverrideMask ) == NET::Override ) noborder = true; } void Client::updateFrameStrut() { // TODO KDEFrameStrut je ale pitome jmeno NETStrut strut; strut.left = border_left; strut.right = border_right; strut.top = border_top; strut.bottom = border_bottom; info->setKDEFrameStrut( strut ); } // Resizes the decoration, and makes sure the decoration widget gets resize event // even if the size hasn't changed. This is needed to make sure the decoration // re-layouts (e.g. when options()->moveResizeMaximizedWindows() changes, // the decoration may turn on/off some borders, but the actual size // of the decoration stays the same). void Client::resizeDecoration( const QSize& s ) { if( decoration == NULL ) return; QSize oldsize = decoration->widget()->size(); decoration->resize( s ); if( oldsize == s ) { QResizeEvent e( s, oldsize ); QApplication::sendEvent( decoration->widget(), &e ); } } bool Client::noBorder() const { return noborder || isFullScreen() || user_noborder || motif_noborder; } bool Client::userCanSetNoBorder() const { return !noborder && !isFullScreen() && !isShade(); } bool Client::isUserNoBorder() const { return user_noborder; } void Client::setUserNoBorder( bool set ) { if( !userCanSetNoBorder()) return; set = rules()->checkNoBorder( set ); if( user_noborder == set ) return; user_noborder = set; updateDecoration( true, false ); updateWindowRules(); } void Client::updateShape() { setShapable(TRUE); if ( shape() ) { XShapeCombineShape(qt_xdisplay(), frameId(), ShapeBounding, clientPos().x(), clientPos().y(), window(), ShapeBounding, ShapeSet); } else { XShapeCombineMask( qt_xdisplay(), frameId(), ShapeBounding, 0, 0, None, ShapeSet); } // workaround for #19644 - shaped windows shouldn't have decoration if( shape() && !noBorder()) { noborder = true; updateDecoration( true ); } } void Client::setMask( const QRegion& reg, int mode ) { _mask = reg; if( reg.isNull()) XShapeCombineMask( qt_xdisplay(), frameId(), ShapeBounding, 0, 0, None, ShapeSet ); else if( mode == X::Unsorted ) XShapeCombineRegion( qt_xdisplay(), frameId(), ShapeBounding, 0, 0, reg.handle(), ShapeSet ); else { QMemArray< QRect > rects = reg.rects(); XRectangle* xrects = new XRectangle[ rects.count() ]; for( unsigned int i = 0; i < rects.count(); ++i ) { xrects[ i ].x = rects[ i ].x(); xrects[ i ].y = rects[ i ].y(); xrects[ i ].width = rects[ i ].width(); xrects[ i ].height = rects[ i ].height(); } XShapeCombineRectangles( qt_xdisplay(), frameId(), ShapeBounding, 0, 0, xrects, rects.count(), ShapeSet, mode ); delete[] xrects; } } QRegion Client::mask() const { if( _mask.isEmpty()) return QRegion( 0, 0, width(), height()); return _mask; } void Client::setShapable(bool b) { long tmp = b?1:0; XChangeProperty(qt_xdisplay(), frameId(), atoms->net_wm_window_shapable, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &tmp, 1L); } void Client::hideClient( bool hide ) { if( hidden == hide ) return; hidden = hide; updateVisibility(); } /* Returns whether the window is minimizable or not */ bool Client::isMinimizable() const { if( isSpecialWindow()) return false; if( isTransient()) { // #66868 - let other xmms windows be minimized when the mainwindow is minimized bool shown_mainwindow = false; ClientList mainclients = mainClients(); for( ClientList::ConstIterator it = mainclients.begin(); it != mainclients.end(); ++it ) { if( (*it)->isShown( true )) shown_mainwindow = true; } if( !shown_mainwindow ) return true; } // this is here because kicker's taskbar doesn't provide separate entries // for windows with an explicitly given parent // TODO perhaps this should be redone if( transientFor() != NULL ) return false; if( !wantsTabFocus()) // SELI - NET::Utility? why wantsTabFocus() - skiptaskbar? ? return false; return true; } /*! Minimizes this client plus its transients */ void Client::minimize( bool avoid_animation ) { if ( !isMinimizable() || isMinimized()) return; minimized = true; Notify::raise( Notify::Minimize ); // SELI mainClients().isEmpty() ??? - and in unminimize() too if ( mainClients().isEmpty() && isOnCurrentDesktop() && isShown( true ) && !avoid_animation ) animateMinimizeOrUnminimize( true ); // was visible or shaded updateVisibility(); updateAllowedActions(); workspace()->updateMinimizedOfTransients( this ); updateWindowRules(); } void Client::unminimize( bool avoid_animation ) { if( !isMinimized()) return; Notify::raise( Notify::UnMinimize ); minimized = false; if( isOnCurrentDesktop() && isShown( true )) { if( mainClients().isEmpty() && !avoid_animation ) animateMinimizeOrUnminimize( FALSE ); } updateVisibility(); updateAllowedActions(); workspace()->updateMinimizedOfTransients( this ); updateWindowRules(); } extern bool blockAnimation; void Client::animateMinimizeOrUnminimize( bool minimize ) { if ( blockAnimation ) return; if ( !options->animateMinimize ) return; if( decoration != NULL && decoration->animateMinimize( minimize )) return; // decoration did it // the function is a bit tricky since it will ensure that an // animation action needs always the same time regardless of the // performance of the machine or the X-Server. float lf,rf,tf,bf,step; int speed = options->animateMinimizeSpeed; if ( speed > 10 ) speed = 10; if ( speed < 0 ) speed = 0; step = 40. * (11 - speed ); NETRect r = info->iconGeometry(); QRect icongeom( r.pos.x, r.pos.y, r.size.width, r.size.height ); if ( !icongeom.isValid() ) return; QPixmap pm = animationPixmap( minimize ? width() : icongeom.width() ); QRect before, after; if ( minimize ) { before = QRect( x(), y(), width(), pm.height() ); after = QRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() ); } else { before = QRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() ); after = QRect( x(), y(), width(), pm.height() ); } lf = (after.left() - before.left())/step; rf = (after.right() - before.right())/step; tf = (after.top() - before.top())/step; bf = (after.bottom() - before.bottom())/step; grabXServer(); QRect area = before; QRect area2; QPixmap pm2; QTime t; t.start(); float diff; QPainter p ( workspace()->desktopWidget() ); bool need_to_clear = FALSE; QPixmap pm3; do { if (area2 != area) { pm = animationPixmap( area.width() ); pm2 = QPixmap::grabWindow( qt_xrootwin(), area.x(), area.y(), area.width(), area.height() ); p.drawPixmap( area.x(), area.y(), pm ); if ( need_to_clear ) { p.drawPixmap( area2.x(), area2.y(), pm3 ); need_to_clear = FALSE; } area2 = area; } XFlush(qt_xdisplay()); XSync( qt_xdisplay(), FALSE ); diff = t.elapsed(); if (diff > step) diff = step; area.setLeft(before.left() + int(diff*lf)); area.setRight(before.right() + int(diff*rf)); area.setTop(before.top() + int(diff*tf)); area.setBottom(before.bottom() + int(diff*bf)); if (area2 != area ) { if ( area2.intersects( area ) ) p.drawPixmap( area2.x(), area2.y(), pm2 ); else { // no overlap, we can clear later to avoid flicker pm3 = pm2; need_to_clear = TRUE; } } } while ( t.elapsed() < step); if (area2 == area || need_to_clear ) p.drawPixmap( area2.x(), area2.y(), pm2 ); p.end(); ungrabXServer(); } /*! The pixmap shown during (un)minimalization animation */ QPixmap Client::animationPixmap( int w ) { QFont font = options->font(isActive()); QFontMetrics fm( font ); QPixmap pm( w, fm.lineSpacing() ); pm.fill( options->color(Options::ColorTitleBar, isActive() || isMinimized() ) ); QPainter p( &pm ); p.setPen(options->color(Options::ColorFont, isActive() || isMinimized() )); p.setFont(options->font(isActive())); p.drawText( pm.rect(), AlignLeft|AlignVCenter|SingleLine, caption() ); return pm; } bool Client::isShadeable() const { return !isSpecialWindow() && !noBorder(); } void Client::setShade( ShadeMode mode ) { if( !isShadeable()) return; mode = rules()->checkShade( mode ); if( shade_mode == mode ) return; bool was_shade = isShade(); ShadeMode was_shade_mode = shade_mode; shade_mode = mode; if( was_shade == isShade()) { if( decoration != NULL ) // decoration may want to update after e.g. hover-shade changes decoration->shadeChange(); return; // no real change in shaded state } if( shade_mode == ShadeNormal ) { if ( isShown( true ) && isOnCurrentDesktop()) Notify::raise( Notify::ShadeUp ); } else if( shade_mode == ShadeNone ) { if( isShown( true ) && isOnCurrentDesktop()) Notify::raise( Notify::ShadeDown ); } assert( decoration != NULL ); // noborder windows can't be shaded ++block_geometry; // decorations may turn off some borders when shaded decoration->borders( border_left, border_right, border_top, border_bottom ); int as = options->animateShade? 10 : 1; // TODO all this unmapping, resizing etc. feels too much duplicated from elsewhere if ( isShade()) { // shade_mode == ShadeNormal // we're about to shade, texx xcompmgr to prepare long _shade = 1; XChangeProperty(qt_xdisplay(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L); // shade int h = height(); shade_geometry_change = true; QSize s( sizeForClientSize( QSize( clientSize().width(), 0), SizemodeShaded ) ); XSelectInput( qt_xdisplay(), wrapper, ClientWinMask ); // avoid getting UnmapNotify XUnmapWindow( qt_xdisplay(), wrapper ); XUnmapWindow( qt_xdisplay(), client ); XSelectInput( qt_xdisplay(), wrapper, ClientWinMask | SubstructureNotifyMask ); //as we hid the unmap event, xcompmgr didn't recognize the client wid has vanished, so we'll extra inform it //done xcompmgr workaround // FRAME repaint( FALSE ); // bool wasStaticContents = testWFlags( WStaticContents ); // setWFlags( WStaticContents ); int step = QMAX( 4, QABS( h - s.height() ) / as )+1; do { h -= step; XResizeWindow( qt_xdisplay(), frameId(), s.width(), h ); resizeDecoration( QSize( s.width(), h )); QApplication::syncX(); } while ( h > s.height() + step ); // if ( !wasStaticContents ) // clearWFlags( WStaticContents ); shade_geometry_change = false; plainResize( s ); if( isActive()) { if( was_shade_mode == ShadeHover ) workspace()->activateNextClient( this ); else workspace()->focusToNull(); } // tell xcompmgr shade's done _shade = 2; XChangeProperty(qt_xdisplay(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L); } else { int h = height(); shade_geometry_change = true; QSize s( sizeForClientSize( clientSize(), SizemodeShaded )); // FRAME bool wasStaticContents = testWFlags( WStaticContents ); // setWFlags( WStaticContents ); int step = QMAX( 4, QABS( h - s.height() ) / as )+1; do { h += step; XResizeWindow( qt_xdisplay(), frameId(), s.width(), h ); resizeDecoration( QSize( s.width(), h )); // assume a border // we do not have time to wait for X to send us paint events // FRAME repaint( 0, h - step-5, width(), step+5, TRUE); QApplication::syncX(); } while ( h < s.height() - step ); // if ( !wasStaticContents ) // clearWFlags( WStaticContents ); shade_geometry_change = false; plainResize( s ); if( shade_mode == ShadeHover || shade_mode == ShadeActivated ) setActive( TRUE ); XMapWindow( qt_xdisplay(), wrapperId()); XMapWindow( qt_xdisplay(), window()); XDeleteProperty (qt_xdisplay(), client, atoms->net_wm_window_shade); if ( isActive() ) workspace()->requestFocus( this ); } checkMaximizeGeometry(); --block_geometry; setGeometry( geometry(), ForceGeometrySet ); info->setState( isShade() ? NET::Shaded : 0, NET::Shaded ); info->setState( isShown( false ) ? 0 : NET::Hidden, NET::Hidden ); updateVisibility(); updateAllowedActions(); workspace()->updateMinimizedOfTransients( this ); decoration->shadeChange(); updateWindowRules(); } void Client::shadeHover() { setShade( ShadeHover ); cancelShadeHover(); } void Client::cancelShadeHover() { delete shadeHoverTimer; shadeHoverTimer = 0; } void Client::toggleShade() { // if the mode is ShadeHover or ShadeActive, cancel shade too setShade( shade_mode == ShadeNone ? ShadeNormal : ShadeNone ); } void Client::updateVisibility() { if( deleting ) return; bool show = true; if( hidden ) { setMappingState( IconicState ); info->setState( NET::Hidden, NET::Hidden ); setSkipTaskbar( true, false ); // also hide from taskbar rawHide(); show = false; } else { setSkipTaskbar( original_skip_taskbar, false ); } if( minimized ) { setMappingState( IconicState ); info->setState( NET::Hidden, NET::Hidden ); rawHide(); show = false; } if( show ) info->setState( 0, NET::Hidden ); if( !isOnCurrentDesktop()) { setMappingState( IconicState ); rawHide(); show = false; } if( show ) { if( workspace()->showingDesktop()) workspace()->resetShowingDesktop( true ); if( isShade()) setMappingState( IconicState ); else setMappingState( NormalState ); rawShow(); } } /*! Sets the client window's mapping state. Possible values are WithdrawnState, IconicState, NormalState. */ void Client::setMappingState(int s) { assert( client != None ); assert( !deleting || s == WithdrawnState ); if( mapping_state == s ) return; bool was_unmanaged = ( mapping_state == WithdrawnState ); mapping_state = s; if( mapping_state == WithdrawnState ) { XDeleteProperty( qt_xdisplay(), window(), qt_wm_state ); return; } assert( s == NormalState || s == IconicState ); unsigned long data[2]; data[0] = (unsigned long) s; data[1] = (unsigned long) None; XChangeProperty(qt_xdisplay(), window(), qt_wm_state, qt_wm_state, 32, PropModeReplace, (unsigned char *)data, 2); if( was_unmanaged ) // force setting the geometry, manage() did block_geometry = 1 { assert( block_geometry == 1 ); --block_geometry; setGeometry( frame_geometry, ForceGeometrySet ); } } /*! Reimplemented to map the managed window in the window wrapper. Proper mapping state should be set before showing the client. */ void Client::rawShow() { if( decoration != NULL ) decoration->widget()->show(); // not really necessary, but let it know the state XMapWindow( qt_xdisplay(), frame ); if( !isShade()) { XMapWindow( qt_xdisplay(), wrapper ); XMapWindow( qt_xdisplay(), client ); } } /*! Reimplemented to unmap the managed window in the window wrapper. Also informs the workspace. Proper mapping state should be set before hiding the client. */ void Client::rawHide() { // Here it may look like a race condition, as some other client might try to unmap // the window between these two XSelectInput() calls. However, they're supposed to // use XWithdrawWindow(), which also sends a synthetic event to the root window, // which won't be missed, so this shouldn't be a problem. The chance the real UnmapNotify // will be missed is also very minimal, so I don't think it's needed to grab the server // here. XSelectInput( qt_xdisplay(), wrapper, ClientWinMask ); // avoid getting UnmapNotify XUnmapWindow( qt_xdisplay(), frame ); XUnmapWindow( qt_xdisplay(), wrapper ); XUnmapWindow( qt_xdisplay(), client ); XSelectInput( qt_xdisplay(), wrapper, ClientWinMask | SubstructureNotifyMask ); if( decoration != NULL ) decoration->widget()->hide(); // not really necessary, but let it know the state workspace()->clientHidden( this ); } void Client::sendClientMessage(Window w, Atom a, Atom protocol, long data1, long data2, long data3) { XEvent ev; long mask; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = a; ev.xclient.format = 32; ev.xclient.data.l[0] = protocol; ev.xclient.data.l[1] = qt_x_time; ev.xclient.data.l[2] = data1; ev.xclient.data.l[3] = data2; ev.xclient.data.l[4] = data3; mask = 0L; if (w == qt_xrootwin()) mask = SubstructureRedirectMask; /* magic! */ XSendEvent(qt_xdisplay(), w, False, mask, &ev); } /* Returns whether the window may be closed (have a close button) */ bool Client::isCloseable() const { return rules()->checkCloseable( motif_may_close && !isSpecialWindow()); } /*! Closes the window by either sending a delete_window message or using XKill. */ void Client::closeWindow() { if( !isCloseable()) return; // Update user time, needed for whole group, because the window may create a confirming dialog, // and this window's user time wouldn't apply to it // This is needed even for apps without support for user timestamp (e.g. nedit), so updating // user timestamp in apps on WM_DELETE_WINDOW is not an option (and I'm not sure if it would be right) group()->updateUserTime(); if ( Pdeletewindow ) { Notify::raise( Notify::Close ); sendClientMessage( window(), atoms->wm_protocols, atoms->wm_delete_window); pingWindow(); } else { // client will not react on wm_delete_window. We have not choice // but destroy his connection to the XServer. killWindow(); } } /*! Kills the window via XKill */ void Client::killWindow() { kdDebug( 1212 ) << "Client::killWindow():" << caption() << endl; // not sure if we need an Notify::Kill or not.. until then, use // Notify::Close Notify::raise( Notify::Close ); if( isDialog()) Notify::raise( Notify::TransDelete ); if( isNormalWindow()) Notify::raise( Notify::Delete ); killProcess( false ); // always kill this client at the server XKillClient(qt_xdisplay(), window() ); destroyClient(); } // send a ping to the window using _NET_WM_PING if possible // if it doesn't respond within a reasonable time, it will be // killed void Client::pingWindow() { if( !Pping ) return; // can't ping :( if( options->killPingTimeout == 0 ) return; // turned off if( ping_timer != NULL ) return; // pinging already ping_timer = new QTimer( this ); connect( ping_timer, SIGNAL( timeout()), SLOT( pingTimeout())); ping_timer->start( options->killPingTimeout, true ); ping_timestamp = qt_x_time; workspace()->sendPingToWindow( window(), ping_timestamp ); } void Client::gotPing( Time timestamp ) { if( timestamp != ping_timestamp ) return; delete ping_timer; ping_timer = NULL; if( process_killer != NULL ) { process_killer->kill(); delete process_killer; process_killer = NULL; } } void Client::pingTimeout() { kdDebug( 1212 ) << "Ping timeout:" << caption() << endl; delete ping_timer; ping_timer = NULL; killProcess( true, ping_timestamp ); } void Client::killProcess( bool ask, Time timestamp ) { if( process_killer != NULL ) return; Q_ASSERT( !ask || timestamp != CurrentTime ); QCString machine = wmClientMachine( true ); pid_t pid = info->pid(); if( pid <= 0 || machine.isEmpty()) // needed properties missing return; kdDebug( 1212 ) << "Kill process:" << pid << "(" << machine << ")" << endl; if( !ask ) { if( machine != "localhost" ) { KProcess proc; proc << "xon" << machine << "kill" << pid; proc.start( KProcess::DontCare ); } else ::kill( pid, SIGTERM ); } else { // SELI TODO handle the window created by handler specially (on top,urgent?) process_killer = new KProcess( this ); *process_killer << KStandardDirs::findExe( "kwin_killer_helper" ) << "--pid" << QCString().setNum( pid ) << "--hostname" << machine << "--windowname" << caption().utf8() << "--applicationname" << resourceClass() << "--wid" << QCString().setNum( window()) << "--timestamp" << QCString().setNum( timestamp ); connect( process_killer, SIGNAL( processExited( KProcess* )), SLOT( processKillerExited())); if( !process_killer->start( KProcess::NotifyOnExit )) { delete process_killer; process_killer = NULL; return; } } } void Client::processKillerExited() { kdDebug( 1212 ) << "Killer exited" << endl; delete process_killer; process_killer = NULL; } void Client::setSkipTaskbar( bool b, bool from_outside ) { if( from_outside ) { b = rules()->checkSkipTaskbar( b ); original_skip_taskbar = b; } if ( b == skipTaskbar() ) return; skip_taskbar = b; info->setState( b?NET::SkipTaskbar:0, NET::SkipTaskbar ); updateWindowRules(); } void Client::setSkipPager( bool b ) { b = rules()->checkSkipPager( b ); if ( b == skipPager() ) return; skip_pager = b; info->setState( b?NET::SkipPager:0, NET::SkipPager ); updateWindowRules(); } void Client::setModal( bool m ) { // Qt-3.2 can have even modal normal windows :( if( modal == m ) return; modal = m; if( !modal ) return; // changing modality for a mapped window is weird (?) // _NET_WM_STATE_MODAL should possibly rather be _NET_WM_WINDOW_TYPE_MODAL_DIALOG } void Client::setDesktop( int desktop ) { if( desktop != NET::OnAllDesktops ) // do range check desktop = KMAX( 1, KMIN( workspace()->numberOfDesktops(), desktop )); desktop = rules()->checkDesktop( desktop ); if( desk == desktop ) return; int was_desk = desk; desk = desktop; info->setDesktop( desktop ); if(( was_desk == NET::OnAllDesktops ) != ( desktop == NET::OnAllDesktops )) { // onAllDesktops changed if ( isShown( true )) Notify::raise( isOnAllDesktops() ? Notify::OnAllDesktops : Notify::NotOnAllDesktops ); workspace()->updateOnAllDesktopsOfTransients( this ); } if( decoration != NULL ) decoration->desktopChange(); updateVisibility(); updateWindowRules(); } void Client::setOnAllDesktops( bool b ) { if(( b && isOnAllDesktops()) || ( !b && !isOnAllDesktops())) return; if( b ) setDesktop( NET::OnAllDesktops ); else setDesktop( workspace()->currentDesktop()); } bool Client::isOnCurrentDesktop() const { return isOnDesktop( workspace()->currentDesktop()); } // performs activation and/or raising of the window void Client::takeActivity( int flags, bool handled, allowed_t ) { if( !handled || !Ptakeactivity ) { if( flags & ActivityFocus ) takeFocus( Allowed ); if( flags & ActivityRaise ) workspace()->raiseClient( this ); return; } #ifndef NDEBUG static Time previous_activity_timestamp; static Client* previous_client; if( previous_activity_timestamp == qt_x_time && previous_client != this ) { kdWarning( 1212 ) << "Repeated use of the same X timestamp for activity" << endl; kdDebug( 1212 ) << kdBacktrace() << endl; } previous_activity_timestamp = qt_x_time; previous_client = this; #endif workspace()->sendTakeActivity( this, qt_x_time, flags ); } // performs the actual focusing of the window using XSetInputFocus and WM_TAKE_FOCUS void Client::takeFocus( allowed_t ) { #ifndef NDEBUG static Time previous_focus_timestamp; static Client* previous_client; if( previous_focus_timestamp == qt_x_time && previous_client != this ) { kdWarning( 1212 ) << "Repeated use of the same X timestamp for focus" << endl; kdDebug( 1212 ) << kdBacktrace() << endl; } previous_focus_timestamp = qt_x_time; previous_client = this; #endif if ( rules()->checkAcceptFocus( input )) { XSetInputFocus( qt_xdisplay(), window(), RevertToPointerRoot, qt_x_time ); } if ( Ptakefocus ) sendClientMessage(window(), atoms->wm_protocols, atoms->wm_take_focus); workspace()->setShouldGetFocus( this ); } /*! Returns whether the window provides context help or not. If it does, you should show a help menu item or a help button like '?' and call contextHelp() if this is invoked. \sa contextHelp() */ bool Client::providesContextHelp() const { return Pcontexthelp; } /*! Invokes context help on the window. Only works if the window actually provides context help. \sa providesContextHelp() */ void Client::showContextHelp() { if ( Pcontexthelp ) { sendClientMessage(window(), atoms->wm_protocols, atoms->net_wm_context_help); QWhatsThis::enterWhatsThisMode(); // SELI? } } /*! Fetches the window's caption (WM_NAME property). It will be stored in the client's caption(). */ void Client::fetchName() { setCaption( readName()); } QString Client::readName() const { if ( info->name() && info->name()[ 0 ] != '\0' ) return QString::fromUtf8( info->name() ); else return KWin::readNameProperty( window(), XA_WM_NAME ); } KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption()); void Client::setCaption( const QString& s, bool force ) { if ( s != cap_normal || force ) { bool reset_name = force; for( unsigned int i = 0; i < s.length(); ++i ) if( !s[ i ].isPrint()) s[ i ] = ' '; cap_normal = s; bool was_suffix = ( !cap_suffix.isEmpty()); QString machine_suffix; if( wmClientMachine( false ) != "localhost" && !isLocalMachine( wmClientMachine( false ))) machine_suffix = " <@" + wmClientMachine( true ) + ">"; QString shortcut_suffix = !shortcut().isNull() ? ( " {" + shortcut().toString() + "}" ) : ""; cap_suffix = machine_suffix + shortcut_suffix; if ( ( !isSpecialWindow() || isToolbar()) && workspace()->findClient( FetchNameInternalPredicate( this ))) { int i = 2; do { cap_suffix = machine_suffix + " <" + QString::number(i) + ">" + shortcut_suffix; i++; } while ( workspace()->findClient( FetchNameInternalPredicate( this ))); info->setVisibleName( caption().utf8() ); reset_name = false; } if(( was_suffix && cap_suffix.isEmpty() || reset_name )) // if it was new window, it may have old value still set, if the window is reused { info->setVisibleName( "" ); // remove info->setVisibleIconName( "" ); // remove } else if( !cap_suffix.isEmpty() && !cap_iconic.isEmpty()) // keep the same suffix in iconic name if it's set info->setVisibleIconName( ( cap_iconic + cap_suffix ).utf8() ); if( isManaged() && decoration != NULL ) decoration->captionChange(); } } void Client::updateCaption() { setCaption( cap_normal, true ); } void Client::fetchIconicName() { QString s; if ( info->iconName() && info->iconName()[ 0 ] != '\0' ) s = QString::fromUtf8( info->iconName() ); else s = KWin::readNameProperty( window(), XA_WM_ICON_NAME ); if ( s != cap_iconic ) { bool was_set = !cap_iconic.isEmpty(); cap_iconic = s; if( !cap_suffix.isEmpty()) { if( !cap_iconic.isEmpty()) // keep the same suffix in iconic name if it's set info->setVisibleIconName( ( s + cap_suffix ).utf8() ); else if( was_set ) info->setVisibleIconName( "" ); //remove } } } /*!\reimp */ QString Client::caption( bool full ) const { return full ? cap_normal + cap_suffix : cap_normal; } void Client::getWMHints() { XWMHints *hints = XGetWMHints(qt_xdisplay(), window() ); input = true; window_group = None; urgency = false; if ( hints ) { if( hints->flags & InputHint ) input = hints->input; if( hints->flags & WindowGroupHint ) window_group = hints->window_group; urgency = ( hints->flags & UrgencyHint ) ? true : false; // true/false needed, it's uint bitfield XFree( (char*)hints ); } checkGroup(); updateUrgency(); updateAllowedActions(); // group affects isMinimizable() } void Client::getMotifHints() { bool mnoborder, mresize, mmove, mminimize, mmaximize, mclose; Motif::readFlags( client, mnoborder, mresize, mmove, mminimize, mmaximize, mclose ); motif_noborder = mnoborder; if( !hasNETSupport()) // NETWM apps should set type and size constraints { motif_may_resize = mresize; // this should be set using minsize==maxsize, but oh well motif_may_move = mmove; } // mminimize; - ignore, bogus - e.g. shading or sending to another desktop is "minimizing" too // mmaximize; - ignore, bogus - maximizing is basically just resizing motif_may_close = mclose; // motif apps like to crash when they set this hint and WM closes them anyway if( isManaged()) updateDecoration( true ); // check if noborder state has changed } void Client::readIcons( Window win, QPixmap* icon, QPixmap* miniicon ) { // get the icons, allow scaling if( icon != NULL ) *icon = KWin::icon( win, 32, 32, TRUE, KWin::NETWM | KWin::WMHints ); if( miniicon != NULL ) if( icon == NULL || !icon->isNull()) *miniicon = KWin::icon( win, 16, 16, TRUE, KWin::NETWM | KWin::WMHints ); else *miniicon = QPixmap(); } void Client::getIcons() { // first read icons from the window itself readIcons( window(), &icon_pix, &miniicon_pix ); if( icon_pix.isNull()) { // then try window group icon_pix = group()->icon(); miniicon_pix = group()->miniIcon(); } if( icon_pix.isNull() && isTransient()) { // then mainclients ClientList mainclients = mainClients(); for( ClientList::ConstIterator it = mainclients.begin(); it != mainclients.end() && icon_pix.isNull(); ++it ) { icon_pix = (*it)->icon(); miniicon_pix = (*it)->miniIcon(); } } if( icon_pix.isNull()) { // and if nothing else, load icon from classhint or xapp icon icon_pix = KWin::icon( window(), 32, 32, TRUE, KWin::ClassHint | KWin::XApp ); miniicon_pix = KWin::icon( window(), 16, 16, TRUE, KWin::ClassHint | KWin::XApp ); } if( isManaged() && decoration != NULL ) decoration->iconChange(); } void Client::getWindowProtocols() { Atom *p; int i,n; Pdeletewindow = 0; Ptakefocus = 0; Ptakeactivity = 0; Pcontexthelp = 0; Pping = 0; if (XGetWMProtocols(qt_xdisplay(), window(), &p, &n)) { for (i = 0; i < n; i++) if (p[i] == atoms->wm_delete_window) Pdeletewindow = 1; else if (p[i] == atoms->wm_take_focus) Ptakefocus = 1; else if (p[i] == atoms->net_wm_take_activity) Ptakeactivity = 1; else if (p[i] == atoms->net_wm_context_help) Pcontexthelp = 1; else if (p[i] == atoms->net_wm_ping) Pping = 1; if (n>0) XFree(p); } } static int nullErrorHandler(Display *, XErrorEvent *) { return 0; } /*! Returns WM_WINDOW_ROLE property for a given window. */ QCString Client::staticWindowRole(WId w) { return getStringProperty(w, qt_window_role).lower(); } /*! Returns SM_CLIENT_ID property for a given window. */ QCString Client::staticSessionId(WId w) { return getStringProperty(w, qt_sm_client_id); } /*! Returns WM_COMMAND property for a given window. */ QCString Client::staticWmCommand(WId w) { return getStringProperty(w, XA_WM_COMMAND, ' '); } /*! Returns WM_CLIENT_LEADER property for a given window. */ Window Client::staticWmClientLeader(WId w) { Atom type; int format, status; unsigned long nitems = 0; unsigned long extra = 0; unsigned char *data = 0; Window result = w; XErrorHandler oldHandler = XSetErrorHandler(nullErrorHandler); status = XGetWindowProperty( qt_xdisplay(), w, atoms->wm_client_leader, 0, 10000, FALSE, XA_WINDOW, &type, &format, &nitems, &extra, &data ); XSetErrorHandler(oldHandler); if (status == Success ) { if (data && nitems > 0) result = *((Window*) data); XFree(data); } return result; } void Client::getWmClientLeader() { wmClientLeaderWin = staticWmClientLeader(window()); } /*! Returns sessionId for this client, taken either from its window or from the leader window. */ QCString Client::sessionId() { QCString result = staticSessionId(window()); if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window()) result = staticSessionId(wmClientLeaderWin); return result; } /*! Returns command property for this client, taken either from its window or from the leader window. */ QCString Client::wmCommand() { QCString result = staticWmCommand(window()); if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window()) result = staticWmCommand(wmClientLeaderWin); return result; } void Client::getWmClientMachine() { client_machine = getStringProperty(window(), XA_WM_CLIENT_MACHINE); if( client_machine.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window()) client_machine = getStringProperty(wmClientLeaderWin, XA_WM_CLIENT_MACHINE); if( client_machine.isEmpty()) client_machine = "localhost"; } /*! Returns client machine for this client, taken either from its window or from the leader window. */ QCString Client::wmClientMachine( bool use_localhost ) const { QCString result = client_machine; if( use_localhost ) { // special name for the local machine (localhost) if( result != "localhost" && isLocalMachine( result )) result = "localhost"; } return result; } /*! Returns client leader window for this client. Returns the client window itself if no leader window is defined. */ Window Client::wmClientLeader() const { if (wmClientLeaderWin) return wmClientLeaderWin; return window(); } bool Client::wantsTabFocus() const { return ( isNormalWindow() || isDialog()) && wantsInput(); } bool Client::wantsInput() const { return rules()->checkAcceptFocus( input || Ptakefocus ); } bool Client::isDesktop() const { return windowType() == NET::Desktop; } bool Client::isDock() const { return windowType() == NET::Dock; } bool Client::isTopMenu() const { return windowType() == NET::TopMenu; } bool Client::isMenu() const { return windowType() == NET::Menu && !isTopMenu(); // because of backwards comp. } bool Client::isToolbar() const { return windowType() == NET::Toolbar; } bool Client::isSplash() const { return windowType() == NET::Splash; } bool Client::isUtility() const { return windowType() == NET::Utility; } bool Client::isDialog() const { return windowType() == NET::Dialog; } bool Client::isNormalWindow() const { return windowType() == NET::Normal; } bool Client::isSpecialWindow() const { return isDesktop() || isDock() || isSplash() || isTopMenu() || isToolbar(); // TODO } NET::WindowType Client::windowType( bool direct, int supported_types ) const { NET::WindowType wt = info->windowType( supported_types ); if( direct ) return wt; NET::WindowType wt2 = rules()->checkType( wt ); if( wt != wt2 ) { wt = wt2; info->setWindowType( wt ); // force hint change } // hacks here if( wt == NET::Menu ) { // ugly hack to support the times when NET::Menu meant NET::TopMenu // if it's as wide as the screen, not very high and has its upper-left // corner a bit above the screen's upper-left cornet, it's a topmenu if( x() == 0 && y() < 0 && y() > -10 && height() < 100 && abs( width() - workspace()->clientArea( FullArea, this ).width()) < 10 ) wt = NET::TopMenu; } // TODO change this to rule const char* const oo_prefix = "openoffice.org"; // QCString has no startsWith() // oo_prefix is lowercase, because resourceClass() is forced to be lowercase if( qstrncmp( resourceClass(), oo_prefix, strlen( oo_prefix )) == 0 && wt == NET::Dialog ) wt = NET::Normal; // see bug #66065 if( wt == NET::Unknown ) // this is more or less suggested in NETWM spec wt = isTransient() ? NET::Dialog : NET::Normal; return wt; } /*! Sets an appropriate cursor shape for the logical mouse position \a m */ void Client::setCursor( Position m ) { if( !isResizable() || isShade()) { m = PositionCenter; } switch ( m ) { case PositionTopLeft: case PositionBottomRight: setCursor( sizeFDiagCursor ); break; case PositionBottomLeft: case PositionTopRight: setCursor( sizeBDiagCursor ); break; case PositionTop: case PositionBottom: setCursor( sizeVerCursor ); break; case PositionLeft: case PositionRight: setCursor( sizeHorCursor ); break; default: if( buttonDown && isMovable()) setCursor( sizeAllCursor ); else setCursor( arrowCursor ); break; } } // TODO mit nejake checkCursor(), ktere se zavola v manage() a pri vecech, kdy by se kurzor mohl zmenit? void Client::setCursor( const QCursor& c ) { if( c.handle() == cursor.handle()) return; cursor = c; if( decoration != NULL ) decoration->widget()->setCursor( cursor ); XDefineCursor( qt_xdisplay(), frameId(), cursor.handle()); } Client::Position Client::mousePosition( const QPoint& p ) const { if( decoration != NULL ) return decoration->mousePosition( p ); return PositionCenter; } void Client::updateAllowedActions( bool force ) { if( !isManaged() && !force ) return; unsigned long old_allowed_actions = allowed_actions; allowed_actions = 0; if( isMovable()) allowed_actions |= NET::ActionMove; if( isResizable()) allowed_actions |= NET::ActionResize; if( isMinimizable()) allowed_actions |= NET::ActionMinimize; if( isShadeable()) allowed_actions |= NET::ActionShade; // sticky state not supported if( isMaximizable()) allowed_actions |= NET::ActionMax; if( userCanSetFullScreen()) allowed_actions |= NET::ActionFullScreen; allowed_actions |= NET::ActionChangeDesktop; // always (pagers shouldn't show Docks etc.) if( isCloseable()) allowed_actions |= NET::ActionClose; if( old_allowed_actions == allowed_actions ) return; // TODO this could be delayed and compressed - it's only for pagers etc. anyway info->setAllowedActions( allowed_actions ); // TODO this should also tell the decoration, so that it can update the buttons } void Client::autoRaise() { workspace()->raiseClient( this ); cancelAutoRaise(); } void Client::cancelAutoRaise() { delete autoRaiseTimer; autoRaiseTimer = 0; } void Client::setOpacity(bool translucent, uint opacity) { if (isDesktop()) return; // xcompmgr does not like non solid desktops and the user could set it accidently by mouse scrolling // qWarning("setting opacity for %d",qt_xdisplay()); //rule out activated translulcency with 100% opacity if (!translucent || opacity == 0xFFFFFFFF) { opacity_ = 0xFFFFFFFF; XDeleteProperty (qt_xdisplay(), frameId(), atoms->net_wm_window_opacity); XDeleteProperty (qt_xdisplay(), window(), atoms->net_wm_window_opacity); // ??? frameId() is necessary for visible changes, window() is the winId() that would be set by apps - we set both to be sure the app knows what's currently displayd } else{ if(opacity == opacity_) return; opacity_ = opacity; long data = opacity; // 32bit XChangeProperty needs long XChangeProperty(qt_xdisplay(), frameId(), atoms->net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L); XChangeProperty(qt_xdisplay(), window(), atoms->net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L); } } void Client::setShadowSize(uint shadowSize) { // ignoring all individual settings - if we control a window, we control it's shadow // TODO somehow handle individual settings for docks (besides custom sizes) long data = shadowSize; XChangeProperty(qt_xdisplay(), frameId(), atoms->net_wm_window_shadow, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L); } void Client::updateOpacity() // extra syncscreen flag allows to avoid double syncs when active state changes (as it will usually change for two windows) { if (!(isNormalWindow() || isDialog() || isUtility() )|| custom_opacity) return; if (isActive()) { if( ruleOpacityActive() ) setOpacity(rule_opacity_active < 0xFFFFFFFF, rule_opacity_active); else setOpacity(options->translucentActiveWindows, options->activeWindowOpacity); if (isBMP()) // beep-media-player, only undecorated windows (gtk2 xmms, xmms doesn't work with compmgr at all - s.e.p. :P ) { ClientList tmpGroupMembers = group()->members(); ClientList activeGroupMembers; activeGroupMembers.append(this); tmpGroupMembers.remove(this); ClientList::Iterator it = tmpGroupMembers.begin(); while (it != tmpGroupMembers.end()) // search for next attached and not activated client and repeat if found { if ((*it) != this && (*it)->isBMP()) // potential "to activate" client found { // qWarning("client found"); if ((*it)->touches(this)) // first test, if the new client touches the just activated one { // qWarning("found client touches me"); if( ruleOpacityActive() ) (*it)->setOpacity(rule_opacity_active < 0xFFFFFFFF, rule_opacity_active); else (*it)->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity); // qWarning("activated, search restarted (1)"); (*it)->setShadowSize(options->activeWindowShadowSize); activeGroupMembers.append(*it); tmpGroupMembers.remove(it); it = tmpGroupMembers.begin(); // restart, search next client continue; } else { // pot. client does not touch c, so we have to search if it touches some other activated client bool found = false; for( ClientList::ConstIterator it2 = activeGroupMembers.begin(); it2 != activeGroupMembers.end(); it2++ ) { if ((*it2) != this && (*it2) != (*it) && (*it)->touches(*it2)) { // qWarning("found client touches other active client"); if( ruleOpacityActive() ) (*it)->setOpacity(rule_opacity_active < 0xFFFFFFFF, rule_opacity_active); else (*it)->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity); (*it)->setShadowSize(options->activeWindowShadowSize); activeGroupMembers.append(*it); tmpGroupMembers.remove(it); it = tmpGroupMembers.begin(); // reset potential client search found = true; // qWarning("activated, search restarted (2)"); break; // skip this loop } } if (found) continue; } } it++; } } else if (isNormalWindow()) // activate dependend minor windows as well { for( ClientList::ConstIterator it = group()->members().begin(); it != group()->members().end(); it++ ) if ((*it)->isDialog() || (*it)->isUtility()) if( (*it)->ruleOpacityActive() ) (*it)->setOpacity((*it)->ruleOpacityActive() < 0xFFFFFFFF, (*it)->ruleOpacityActive()); else (*it)->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity); } } else { if( ruleOpacityInactive() ) setOpacity(rule_opacity_inactive < 0xFFFFFFFF, rule_opacity_inactive); else setOpacity(options->translucentInactiveWindows && !(keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity); // deactivate dependend minor windows as well if (isBMP()) // beep-media-player, only undecorated windows (gtk2 xmms, xmms doesn't work with compmgr at all - s.e.p. :P ) { ClientList tmpGroupMembers = group()->members(); ClientList inactiveGroupMembers; inactiveGroupMembers.append(this); tmpGroupMembers.remove(this); ClientList::Iterator it = tmpGroupMembers.begin(); while ( it != tmpGroupMembers.end() ) // search for next attached and not activated client and repeat if found { if ((*it) != this && (*it)->isBMP()) // potential "to activate" client found { // qWarning("client found"); if ((*it)->touches(this)) // first test, if the new client touches the just activated one { // qWarning("found client touches me"); if( (*it)->ruleOpacityInactive() ) (*it)->setOpacity((*it)->ruleOpacityInactive() < 0xFFFFFFFF, (*it)->ruleOpacityInactive()); else (*it)->setOpacity(options->translucentInactiveWindows && !((*it)->keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity); (*it)->setShadowSize(options->inactiveWindowShadowSize); // qWarning("deactivated, search restarted (1)"); inactiveGroupMembers.append(*it); tmpGroupMembers.remove(it); it = tmpGroupMembers.begin(); // restart, search next client continue; } else // pot. client does not touch c, so we have to search if it touches some other activated client { bool found = false; for( ClientList::ConstIterator it2 = inactiveGroupMembers.begin(); it2 != inactiveGroupMembers.end(); it2++ ) { if ((*it2) != this && (*it2) != (*it) && (*it)->touches(*it2)) { // qWarning("found client touches other inactive client"); if( (*it)->ruleOpacityInactive() ) (*it)->setOpacity((*it)->ruleOpacityInactive() < 0xFFFFFFFF, (*it)->ruleOpacityInactive()); else (*it)->setOpacity(options->translucentInactiveWindows && !((*it)->keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity); (*it)->setShadowSize(options->inactiveWindowShadowSize); // qWarning("deactivated, search restarted (2)"); inactiveGroupMembers.append(*it); tmpGroupMembers.remove(it); it = tmpGroupMembers.begin(); // reset potential client search found = true; break; // skip this loop } } if (found) continue; } } it++; } } else if (isNormalWindow()) { for( ClientList::ConstIterator it = group()->members().begin(); it != group()->members().end(); it++ ) if ((*it)->isUtility()) //don't deactivate dialogs... if( (*it)->ruleOpacityInactive() ) (*it)->setOpacity((*it)->ruleOpacityInactive() < 0xFFFFFFFF, (*it)->ruleOpacityInactive()); else (*it)->setOpacity(options->translucentInactiveWindows && !((*it)->keepAbove() && options->keepAboveAsActive), options->inactiveWindowOpacity); } } } void Client::updateShadowSize() // extra syncscreen flag allows to avoid double syncs when active state changes (as it will usually change for two windows) { if (!(isNormalWindow() || isDialog() || isUtility() )) return; if (isActive()) setShadowSize(options->activeWindowShadowSize); else setShadowSize(options->inactiveWindowShadowSize); } uint Client::ruleOpacityInactive() { return rule_opacity_inactive;// != 0 ; } uint Client::ruleOpacityActive() { return rule_opacity_active;// != 0; } bool Client::getWindowOpacity() //query translucency settings from X, returns true if window opacity is set { unsigned char *data = 0; Atom actual; int format, result; unsigned long n, left; result = XGetWindowProperty(qt_xdisplay(), window(), atoms->net_wm_window_opacity, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, /*(unsigned char **)*/ &data); if (result == Success && data != None && format == 32 ) { opacity_ = *reinterpret_cast< long* >( data ); custom_opacity = true; // setOpacity(opacity_ < 0xFFFFFFFF, opacity_); return TRUE; } return FALSE; } void Client::setCustomOpacityFlag(bool custom) { custom_opacity = custom; } uint Client::opacity() { return opacity_; } int Client::opacityPercentage() { return int(100*((double)opacity_/0xffffffff)); } bool Client::touches(const Client* c) // checks if this client borders c, needed to test beep media player window state { if (y() == c->y() + c->height()) // this bottom to c return TRUE; if (y() + height() == c->y()) // this top to c return TRUE; if (x() == c->x() + c->width()) // this right to c return TRUE; if (x() + width() == c->x()) // this left to c return TRUE; return FALSE; } void Client::setXTitleHeightProperty(int titleHeight) { long data = titleHeight; XChangeProperty(qt_xdisplay(), frameId(), atoms->net_wm_window_titleheight, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1L); } #ifndef NDEBUG kdbgstream& operator<<( kdbgstream& stream, const Client* cl ) { if( cl == NULL ) return stream << "\'NULL_CLIENT\'"; return stream << "\'ID:" << cl->window() << ";WMCLASS:" << cl->resourceClass() << ":" << cl->resourceName() << ";Caption:" << cl->caption() << "\'"; } kdbgstream& operator<<( kdbgstream& stream, const ClientList& list ) { stream << "LIST:("; bool first = true; for( ClientList::ConstIterator it = list.begin(); it != list.end(); ++it ) { if( !first ) stream << ":"; first = false; stream << *it; } stream << ")"; return stream; } kdbgstream& operator<<( kdbgstream& stream, const ConstClientList& list ) { stream << "LIST:("; bool first = true; for( ConstClientList::ConstIterator it = list.begin(); it != list.end(); ++it ) { if( !first ) stream << ":"; first = false; stream << *it; } stream << ")"; return stream; } #endif QPixmap * kwin_get_menu_pix_hack() { static QPixmap p; if ( p.isNull() ) p = SmallIcon( "bx2" ); return &p; } } // namespace #include "client.moc" diff --git a/client.h b/client.h index d4f15d26a..a4a3ae0c4 100644 --- a/client.h +++ b/client.h @@ -1,911 +1,913 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 1999, 2000 Matthias Ettrich Copyright (C) 2003 Lubos Lunak You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #ifndef KWIN_CLIENT_H #define KWIN_CLIENT_H #include #include #include #include #include #include #include #include #include #include #include #include "utils.h" #include "options.h" #include "workspace.h" #include "kdecoration.h" #include "rules.h" class QTimer; class KProcess; class KStartupInfoData; namespace KWinInternal { class Workspace; class Client; class WinInfo; class SessionInfo; class Bridge; class Client : public QObject, public KDecorationDefines { Q_OBJECT public: Client( Workspace *ws ); Window window() const; Window frameId() const; Window wrapperId() const; Window decorationId() const; Workspace* workspace() const; const Client* transientFor() const; Client* transientFor(); bool isTransient() const; bool groupTransient() const; bool wasOriginallyGroupTransient() const; ClientList mainClients() const; // call once before loop , is not indirect bool hasTransient( const Client* c, bool indirect ) const; const ClientList& transients() const; // is not indirect void checkTransient( Window w ); Client* findModal(); const Group* group() const; Group* group(); void checkGroup( Group* gr = NULL, bool force = false ); // prefer isXXX() instead NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const; const WindowRules* rules() const; QRect geometry() const; QSize size() const; QSize minSize() const; QSize maxSize() const; QPoint pos() const; QRect rect() const; int x() const; int y() const; int width() const; int height() const; QPoint clientPos() const; // inside of geometry() QSize clientSize() const; bool windowEvent( XEvent* e ); virtual bool eventFilter( QObject* o, QEvent* e ); bool manage( Window w, bool isMapped ); void releaseWindow( bool on_shutdown = false ); enum Sizemode // how to resize the window in order to obey constains (mainly aspect ratios) { SizemodeAny, SizemodeFixedW, // try not to affect width SizemodeFixedH, // try not to affect height SizemodeMax, // try not to make it larger in either direction SizemodeShaded // shaded - height == 0 }; QSize adjustedSize( const QSize&, Sizemode mode = SizemodeAny ) const; QPixmap icon() const; QPixmap miniIcon() const; bool isActive() const; void setActive( bool, bool updateOpacity = true ); int desktop() const; void setDesktop( int ); bool isOnDesktop( int d ) const; bool isOnCurrentDesktop() const; bool isOnAllDesktops() const; void setOnAllDesktops( bool set ); // !isMinimized() && not hidden, i.e. normally visible on some virtual desktop bool isShown( bool shaded_is_shown ) const; bool isShade() const; // true only for ShadeNormal ShadeMode shadeMode() const; // prefer isShade() void setShade( ShadeMode mode ); bool isShadeable() const; bool isMinimized() const; bool isMaximizable() const; QRect geometryRestore() const; MaximizeMode maximizeMode() const; bool isMinimizable() const; void setMaximize( bool vertically, bool horizontally ); void setFullScreen( bool set, bool user ); bool isFullScreen() const; bool isFullScreenable( bool fullscreen_hack = false ) const; bool userCanSetFullScreen() const; QRect geometryFSRestore() const { return geom_fs_restore; } // only for session saving int fullScreenMode() const { return fullscreen_mode; } // only for session saving bool isUserNoBorder() const; void setUserNoBorder( bool set ); bool userCanSetNoBorder() const; bool noBorder() const; bool skipTaskbar( bool from_outside = false ) const; void setSkipTaskbar( bool set, bool from_outside ); bool skipPager() const; void setSkipPager( bool ); bool keepAbove() const; void setKeepAbove( bool ); bool keepBelow() const; void setKeepBelow( bool ); Layer layer() const; Layer belongsToLayer() const; void invalidateLayer(); void setModal( bool modal ); bool isModal() const; // auxiliary functions, depend on the windowType bool wantsTabFocus() const; bool wantsInput() const; bool hasNETSupport() const; bool isMovable() const; bool isDesktop() const; bool isDock() const; bool isToolbar() const; bool isTopMenu() const; bool isMenu() const; bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient' bool isDialog() const; bool isSplash() const; bool isUtility() const; // returns true for "special" windows and false for windows which are "normal" // (normal=window which has a border, can be moved by the user, can be closed, etc.) // true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now) // false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO bool isSpecialWindow() const; bool isResizable() const; bool isCloseable() const; // may be closed by the user (may have a close button) void takeActivity( int flags, bool handled, allowed_t ); // takes ActivityFlags as arg (in utils.h) void takeFocus( allowed_t ); void demandAttention( bool set = true ); void setMask( const QRegion& r, int mode = X::Unsorted ); QRegion mask() const; void updateDecoration( bool check_workspace_pos, bool force = false ); void checkBorderSizes(); // shape extensions bool shape() const; void updateShape(); void setGeometry( int x, int y, int w, int h, ForceGeometry_t force = NormalGeometrySet ); void setGeometry( const QRect& r, ForceGeometry_t force = NormalGeometrySet ); void move( int x, int y, ForceGeometry_t force = NormalGeometrySet ); void move( const QPoint & p, ForceGeometry_t force = NormalGeometrySet ); // plainResize() simply resizes void plainResize( int w, int h, ForceGeometry_t force = NormalGeometrySet ); void plainResize( const QSize& s, ForceGeometry_t force = NormalGeometrySet ); void keepInArea( QRect area, bool partial = false ); void growHorizontal(); void shrinkHorizontal(); void growVertical(); void shrinkVertical(); bool providesContextHelp() const; KShortcut shortcut() const; void setShortcut( const QString& cut ); bool performMouseCommand( Options::MouseCommand, QPoint globalPos, bool handled = false ); QCString windowRole() const; QCString sessionId(); QCString resourceName() const; QCString resourceClass() const; QCString wmCommand(); QCString wmClientMachine( bool use_localhost ) const; Window wmClientLeader() const; pid_t pid() const; QRect adjustedClientArea( const QRect& desktop, const QRect& area ) const; Colormap colormap() const; // updates visibility depending on being shaded, virtual desktop, etc. void updateVisibility(); // hides a client - basically like minimize, but without effects, it's simply hidden void hideClient( bool hide ); QString caption( bool full = true ) const; void updateCaption(); void keyPressEvent( uint key_code ); // FRAME ?? void updateMouseGrab(); Window moveResizeGrabWindow() const; const QPoint calculateGravitation( bool invert, int gravity = 0 ) const; // FRAME public? void NETMoveResize( int x_root, int y_root, NET::Direction direction ); void NETMoveResizeWindow( int flags, int x, int y, int width, int height ); void restackWindow( Window above, int detail, NET::RequestSource source, Time timestamp, bool send_event = false ); void gotPing( Time timestamp ); static QCString staticWindowRole(WId); static QCString staticSessionId(WId); static QCString staticWmCommand(WId); static QCString staticWmClientMachine(WId); static Window staticWmClientLeader(WId); void checkWorkspacePosition(); void updateUserTime( Time time = CurrentTime ); Time userTime() const; bool hasUserTimeSupport() const; bool ignoreFocusStealing() const; // does 'delete c;' static void deleteClient( Client* c, allowed_t ); static bool resourceMatch( const Client* c1, const Client* c2 ); static bool belongToSameApplication( const Client* c1, const Client* c2, bool active_hack = false ); static void readIcons( Window win, QPixmap* icon, QPixmap* miniicon ); void minimize( bool avoid_animation = false ); void unminimize( bool avoid_animation = false ); void closeWindow(); void killWindow(); void maximize( MaximizeMode ); void toggleShade(); void showContextHelp(); void cancelShadeHover(); void cancelAutoRaise(); void destroyClient(); void checkActiveModal(); void setOpacity(bool translucent, uint opacity = 0); void setShadowSize(uint shadowSize); void updateOpacity(); void updateShadowSize(); bool hasCustomOpacity(){return custom_opacity;} void setCustomOpacityFlag(bool custom = true); bool getWindowOpacity(); int opacityPercentage(); void checkAndSetInitialRuledOpacity(); uint ruleOpacityInactive(); uint ruleOpacityActive(); unsigned int opacity(); bool isBMP(); void setBMP(bool b); bool touches(const Client* c); void setShapable(bool b); private slots: void autoRaise(); void shadeHover(); void shortcutActivated(); private: friend class Bridge; // FRAME virtual void processMousePressEvent( QMouseEvent* e ); private: // TODO cleanup the order of things in the .h file // use Workspace::createClient() virtual ~Client(); // use destroyClient() or releaseWindow() Position mousePosition( const QPoint& ) const; void setCursor( Position m ); void setCursor( const QCursor& c ); void animateMinimizeOrUnminimize( bool minimize ); QPixmap animationPixmap( int w ); // transparent stuff void drawbound( const QRect& geom ); void clearbound(); void doDrawbound( const QRect& geom, bool clear ); // handlers for X11 events bool mapRequestEvent( XMapRequestEvent* e ); void unmapNotifyEvent( XUnmapEvent*e ); void destroyNotifyEvent( XDestroyWindowEvent*e ); void configureRequestEvent( XConfigureRequestEvent* e ); void propertyNotifyEvent( XPropertyEvent* e ); void clientMessageEvent( XClientMessageEvent* e ); void enterNotifyEvent( XCrossingEvent* e ); void leaveNotifyEvent( XCrossingEvent* e ); void visibilityNotifyEvent( XVisibilityEvent* e ); void focusInEvent( XFocusInEvent* e ); void focusOutEvent( XFocusOutEvent* e ); bool buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root ); bool buttonReleaseEvent( Window w, int button, int state, int x, int y, int x_root, int y_root ); bool motionNotifyEvent( Window w, int state, int x, int y, int x_root, int y_root ); void processDecorationButtonPress( int button, int state, int x, int y, int x_root, int y_root ); private slots: void pingTimeout(); void processKillerExited(); + void demandAttentionKNotify(); private: // ICCCM 4.1.3.1, 4.1.4 , NETWM 2.5.1 void setMappingState( int s ); int mappingState() const; bool isIconicState() const; bool isNormalState() const; bool isManaged() const; // returns false if this client is not yet managed void updateAllowedActions( bool force = false ); QSize sizeForClientSize( const QSize&, Sizemode mode = SizemodeAny, bool noframe = false ) const; void changeMaximize( bool horizontal, bool vertical, bool adjust ); void checkMaximizeGeometry(); bool checkFullScreenHack( const QRect& geom ) const; void updateFullScreenHack( const QRect& geom ); void getWmNormalHints(); void getMotifHints(); void getIcons(); void getWmClientLeader(); void getWmClientMachine(); void fetchName(); void fetchIconicName(); QString readName() const; void setCaption( const QString& s, bool force = false ); bool hasTransientInternal( const Client* c, bool indirect, ConstClientList& set ) const; void setupWindowRules( bool ignore_temporary ); void updateWindowRules(); void finishWindowRules(); void setShortcutInternal( const KShortcut& cut ); void updateWorkareaDiffs(); void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area ); static int computeWorkareaDiff( int left, int right, int a_left, int a_right ); void configureRequest( int value_mask, int rx, int ry, int rw, int rh, int gravity, bool from_tool ); // resizeWithChecks() resizes according to gravity, and checks workarea position void resizeWithChecks( int w, int h, ForceGeometry_t force = NormalGeometrySet ); void resizeWithChecks( const QSize& s, ForceGeometry_t force = NormalGeometrySet ); NETExtendedStrut strut() const; bool hasStrut() const; int checkShadeGeometry( int w, int h ); bool startMoveResize(); void finishMoveResize( bool cancel ); void leaveMoveResize(); void checkUnrestrictedMoveResize(); void handleMoveResize( int x, int y, int x_root, int y_root ); void positionGeometryTip(); void grabButton( int mod ); void ungrabButton( int mod ); void resetMaximize(); void resizeDecoration( const QSize& s ); void setXTitleHeightProperty(int titleHeight); void pingWindow(); void killProcess( bool ask, Time timestamp = CurrentTime ); void updateUrgency(); static void sendClientMessage( Window w, Atom a, Atom protocol, long data1 = 0, long data2 = 0, long data3 = 0 ); void embedClient( Window w, const XWindowAttributes &attr ); void detectNoBorder(); void destroyDecoration(); void updateFrameStrut(); void rawShow(); // just shows it void rawHide(); // just hides it Time readUserTimeMapTimestamp( const KStartupInfoId* asn_id, const KStartupInfoData* asn_data, bool session ) const; Time readUserCreationTime() const; static bool sameAppWindowRoleMatch( const Client* c1, const Client* c2, bool active_hack ); void startupIdChanged(); Window client; Window wrapper; Window frame; KDecoration* decoration; Workspace* wspace; Bridge* bridge; int desk; bool buttonDown; bool moveResizeMode; bool move_faked_activity; Window move_resize_grab_window; bool unrestrictedMoveResize; bool isMove() const { return moveResizeMode && mode == PositionCenter; } bool isResize() const { return moveResizeMode && mode != PositionCenter; } Position mode; QPoint moveOffset; QPoint invertedMoveOffset; QRect moveResizeGeom; QRect initialMoveResizeGeom; XSizeHints xSizeHint; void sendSyntheticConfigureNotify(); int mapping_state; void readTransient(); Window verifyTransientFor( Window transient_for, bool set ); void addTransient( Client* cl ); void removeTransient( Client* cl ); void removeFromMainClients(); void cleanGrouping(); void checkGroupTransients(); void setTransient( Window new_transient_for_id ); Client* transient_for; Window transient_for_id; Window original_transient_for_id; ClientList transients_list; // SELI make this ordered in stacking order? ShadeMode shade_mode; uint active :1; uint deleting : 1; // true when doing cleanup and destroying the client uint keep_above : 1; // NET::KeepAbove (was stays_on_top) uint is_shape :1; uint skip_taskbar :1; uint original_skip_taskbar :1; // unaffected by KWin uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol? uint Ptakefocus :1;// does the window understand the TakeFocus protocol? uint Ptakeactivity : 1; // does it support _NET_WM_TAKE_ACTIVITY uint Pcontexthelp : 1; // does the window understand the ContextHelp protocol? uint Pping : 1; // does it support _NET_WM_PING? uint input :1; // does the window want input in its wm_hints uint skip_pager : 1; uint motif_noborder : 1; uint motif_may_resize : 1; uint motif_may_move :1; uint motif_may_close : 1; uint keep_below : 1; // NET::KeepBelow uint minimized : 1; uint hidden : 1; // forcibly hidden by calling hide() uint modal : 1; // NET::Modal uint noborder : 1; uint user_noborder : 1; uint not_obscured : 1; uint urgency : 1; // XWMHints, UrgencyHint uint ignore_focus_stealing : 1; // don't apply focus stealing prevention to this client + uint demands_attention : 1; WindowRules client_rules; void getWMHints(); void readIcons(); void getWindowProtocols(); QPixmap icon_pix; QPixmap miniicon_pix; QCursor cursor; // FullScreenHack - non-NETWM fullscreen (noborder,size of desktop) // DON'T reorder - saved to config files !!! enum FullScreenMode { FullScreenNone, FullScreenNormal, FullScreenHack }; FullScreenMode fullscreen_mode; MaximizeMode max_mode; QRect geom_restore; QRect geom_fs_restore; int workarea_diff_x, workarea_diff_y; WinInfo* info; QTimer* autoRaiseTimer; QTimer* shadeHoverTimer; Colormap cmap; QCString resource_name; QCString resource_class; QCString client_machine; QString cap_normal, cap_iconic, cap_suffix; WId wmClientLeaderWin; QCString window_role; Group* in_group; Window window_group; Layer in_layer; QTimer* ping_timer; KProcess* process_killer; Time ping_timestamp; Time user_time; unsigned long allowed_actions; QRect frame_geometry; QSize client_size; int block_geometry; // >0 - new geometry is remembered, but not actually set bool shade_geometry_change; int border_left, border_right, border_top, border_bottom; QRegion _mask; static bool check_active_modal; // see Client::checkActiveModal() KShortcut _shortcut; friend struct FetchNameInternalPredicate; friend struct CheckIgnoreFocusStealingProcedure; friend struct ResetupRulesProcedure; void show() { assert( false ); } // SELI remove after Client is no longer QWidget void hide() { assert( false ); } uint opacity_; uint savedOpacity_; bool custom_opacity; uint rule_opacity_active; //translucency rules uint rule_opacity_inactive; //dto. //int shadeOriginalHeight; bool isBMP_; - + QTimer* demandAttentionKNotifyTimer; }; // NET WM Protocol handler class class WinInfo : public NETWinInfo { private: typedef KWinInternal::Client Client; // because of NET::Client public: WinInfo( Client* c, Display * display, Window window, Window rwin, const unsigned long pr[], int pr_size ); virtual void changeDesktop(int desktop); virtual void changeState( unsigned long state, unsigned long mask ); private: Client * m_client; }; inline Window Client::window() const { return client; } inline Window Client::frameId() const { return frame; } inline Window Client::wrapperId() const { return wrapper; } inline Window Client::decorationId() const { return decoration != NULL ? decoration->widget()->winId() : None; } inline Workspace* Client::workspace() const { return wspace; } inline const Client* Client::transientFor() const { return transient_for; } inline Client* Client::transientFor() { return transient_for; } inline bool Client::groupTransient() const { return transient_for_id == workspace()->rootWin(); } // needed because verifyTransientFor() may set transient_for_id to root window, // if the original value has a problem (window doesn't exist, etc.) inline bool Client::wasOriginallyGroupTransient() const { return original_transient_for_id == workspace()->rootWin(); } inline bool Client::isTransient() const { return transient_for_id != None; } inline const ClientList& Client::transients() const { return transients_list; } inline const Group* Client::group() const { return in_group; } inline Group* Client::group() { return in_group; } inline int Client::mappingState() const { return mapping_state; } inline QCString Client::resourceName() const { return resource_name; // it is always lowercase } inline QCString Client::resourceClass() const { return resource_class; // it is always lowercase } inline bool Client::isMinimized() const { return minimized; } inline bool Client::isActive() const { return active; } /*! Returns the virtual desktop within the workspace() the client window is located in, 0 if it isn't located on any special desktop (not mapped yet), or NET::OnAllDesktops. Do not use desktop() directly, use isOnDesktop() instead. */ inline int Client::desktop() const { return desk; } inline bool Client::isOnAllDesktops() const { return desk == NET::OnAllDesktops; } /*! Returns whether the client is on the virtual desktop \a d. This is always TRUE for onAllDesktops clients. */ inline bool Client::isOnDesktop( int d ) const { return desk == d || /*desk == 0 ||*/ isOnAllDesktops(); } inline bool Client::isShown( bool shaded_is_shown ) const { return !isMinimized() && ( !isShade() || shaded_is_shown ) && !hidden; } inline bool Client::isShade() const { return shade_mode == ShadeNormal; } inline ShadeMode Client::shadeMode() const { return shade_mode; } inline QPixmap Client::icon() const { return icon_pix; } inline QPixmap Client::miniIcon() const { return miniicon_pix; } inline QRect Client::geometryRestore() const { return geom_restore; } inline Client::MaximizeMode Client::maximizeMode() const { return max_mode; } inline bool Client::skipTaskbar( bool from_outside ) const { return from_outside ? original_skip_taskbar : skip_taskbar; } inline bool Client::skipPager() const { return skip_pager; } inline bool Client::keepAbove() const { return keep_above; } inline bool Client::keepBelow() const { return keep_below; } inline bool Client::shape() const { return is_shape; } inline bool Client::isFullScreen() const { return fullscreen_mode != FullScreenNone; } inline bool Client::isModal() const { return modal; } inline bool Client::hasNETSupport() const { return info->hasNETSupport(); } inline Colormap Client::colormap() const { return cmap; } inline pid_t Client::pid() const { return info->pid(); } inline void Client::invalidateLayer() { in_layer = UnknownLayer; } inline bool Client::isIconicState() const { return mapping_state == IconicState; } inline bool Client::isNormalState() const { return mapping_state == NormalState; } inline bool Client::isManaged() const { return mapping_state != WithdrawnState; } inline QCString Client::windowRole() const { return window_role; } inline QRect Client::geometry() const { return frame_geometry; } inline QSize Client::size() const { return frame_geometry.size(); } inline QPoint Client::pos() const { return frame_geometry.topLeft(); } inline int Client::x() const { return frame_geometry.x(); } inline int Client::y() const { return frame_geometry.y(); } inline int Client::width() const { return frame_geometry.width(); } inline int Client::height() const { return frame_geometry.height(); } inline QRect Client::rect() const { return QRect( 0, 0, width(), height()); } inline QPoint Client::clientPos() const { return QPoint( border_left, border_top ); } inline QSize Client::clientSize() const { return client_size; } inline void Client::setGeometry( const QRect& r, ForceGeometry_t force ) { setGeometry( r.x(), r.y(), r.width(), r.height(), force ); } inline void Client::move( const QPoint & p, ForceGeometry_t force ) { move( p.x(), p.y(), force ); } inline void Client::plainResize( const QSize& s, ForceGeometry_t force ) { plainResize( s.width(), s.height(), force ); } inline void Client::resizeWithChecks( const QSize& s, ForceGeometry_t force ) { resizeWithChecks( s.width(), s.height(), force ); } inline bool Client::hasUserTimeSupport() const { return info->userTime() != -1U; } inline bool Client::ignoreFocusStealing() const { return ignore_focus_stealing; } inline const WindowRules* Client::rules() const { return &client_rules; } KWIN_PROCEDURE( CheckIgnoreFocusStealingProcedure, cl->ignore_focus_stealing = options->checkIgnoreFocusStealing( cl )); inline Window Client::moveResizeGrabWindow() const { return move_resize_grab_window; } inline KShortcut Client::shortcut() const { return _shortcut; } inline bool Client::isBMP() { return isBMP_; } inline void Client::setBMP(bool b) { isBMP_ = b; } #ifdef NDEBUG inline kndbgstream& operator<<( kndbgstream& stream, const Client* ) { return stream; } inline kndbgstream& operator<<( kndbgstream& stream, const ClientList& ) { return stream; } inline kndbgstream& operator<<( kndbgstream& stream, const ConstClientList& ) { return stream; } #else kdbgstream& operator<<( kdbgstream& stream, const Client* ); kdbgstream& operator<<( kdbgstream& stream, const ClientList& ); kdbgstream& operator<<( kdbgstream& stream, const ConstClientList& ); #endif KWIN_COMPARE_PREDICATE( WindowMatchPredicate, Window, cl->window() == value ); KWIN_COMPARE_PREDICATE( FrameIdMatchPredicate, Window, cl->frameId() == value ); KWIN_COMPARE_PREDICATE( WrapperIdMatchPredicate, Window, cl->wrapperId() == value ); } // namespace #endif diff --git a/events.cpp b/events.cpp index b8eb51e35..b52e8dc58 100644 --- a/events.cpp +++ b/events.cpp @@ -1,1557 +1,1562 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 1999, 2000 Matthias Ettrich Copyright (C) 2003 Lubos Lunak You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ /* This file contains things relevant to handling incoming events. */ #include "client.h" #include "workspace.h" #include "atoms.h" #include "tabbox.h" #include "group.h" #include "rules.h" #include #include #include #include #include extern Time qt_x_time; extern Atom qt_window_role; namespace KWinInternal { // **************************************** // WinInfo // **************************************** WinInfo::WinInfo( Client * c, Display * display, Window window, Window rwin, const unsigned long pr[], int pr_size ) : NETWinInfo( display, window, rwin, pr, pr_size, NET::WindowManager ), m_client( c ) { } void WinInfo::changeDesktop(int desktop) { m_client->workspace()->sendClientToDesktop( m_client, desktop, true ); } void WinInfo::changeState( unsigned long state, unsigned long mask ) { mask &= ~NET::Sticky; // KWin doesn't support large desktops, ignore mask &= ~NET::Hidden; // clients are not allowed to change this directly state &= mask; // for safety, clear all other bits if(( mask & NET::FullScreen ) != 0 && ( state & NET::FullScreen ) == 0 ) m_client->setFullScreen( false, false ); if ( (mask & NET::Max) == NET::Max ) m_client->setMaximize( state & NET::MaxVert, state & NET::MaxHoriz ); else if ( mask & NET::MaxVert ) m_client->setMaximize( state & NET::MaxVert, m_client->maximizeMode() & Client::MaximizeHorizontal ); else if ( mask & NET::MaxHoriz ) m_client->setMaximize( m_client->maximizeMode() & Client::MaximizeVertical, state & NET::MaxHoriz ); if ( mask & NET::Shaded ) m_client->setShade( state & NET::Shaded ? ShadeNormal : ShadeNone ); if ( mask & NET::KeepAbove) m_client->setKeepAbove( (state & NET::KeepAbove) != 0 ); if ( mask & NET::KeepBelow) m_client->setKeepBelow( (state & NET::KeepBelow) != 0 ); if( mask & NET::SkipTaskbar ) m_client->setSkipTaskbar( ( state & NET::SkipTaskbar ) != 0, true ); if( mask & NET::SkipPager ) m_client->setSkipPager( ( state & NET::SkipPager ) != 0 ); if( mask & NET::DemandsAttention ) m_client->demandAttention(( state & NET::DemandsAttention ) != 0 ); if( mask & NET::Modal ) m_client->setModal( ( state & NET::Modal ) != 0 ); // unsetting fullscreen first, setting it last (because e.g. maximize works only for !isFullScreen() ) if(( mask & NET::FullScreen ) != 0 && ( state & NET::FullScreen ) != 0 ) m_client->setFullScreen( true, false ); } // **************************************** // RootInfo // **************************************** RootInfo::RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr ) : NETRootInfo4( dpy, w, name, pr, pr_num, scr ) { workspace = ws; } void RootInfo::changeNumberOfDesktops(int n) { workspace->setNumberOfDesktops( n ); } void RootInfo::changeCurrentDesktop(int d) { workspace->setCurrentDesktop( d ); } void RootInfo::changeActiveWindow( Window w, NET::RequestSource src, Time timestamp, Window active_window ) { if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) { if( timestamp == CurrentTime ) timestamp = c->userTime(); if( src != NET::FromApplication && src != FromTool ) src = NET::FromTool; if( src == NET::FromTool ) workspace->activateClient( c, true ); // force else // NET::FromApplication { Client* c2; if( workspace->allowClientActivation( c, timestamp )) workspace->activateClient( c ); // if activation of the requestor's window would be allowed, allow activation too else if( active_window != None && ( c2 = workspace->findClient( WindowMatchPredicate( active_window ))) != NULL && workspace->allowClientActivation( c2, timestampCompare( timestamp, c2->userTime() > 0 ? timestamp : c2->userTime()))) workspace->activateClient( c ); else c->demandAttention(); } } } void RootInfo::restackWindow( Window w, RequestSource src, Window above, int detail, Time timestamp ) { if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) { if( timestamp == CurrentTime ) timestamp = c->userTime(); if( src != NET::FromApplication && src != FromTool ) src = NET::FromTool; c->restackWindow( above, detail, src, timestamp, true ); } } void RootInfo::gotTakeActivity( Window w, Time timestamp, long flags ) { if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) workspace->handleTakeActivity( c, timestamp, flags ); } void RootInfo::closeWindow(Window w) { Client* c = workspace->findClient( WindowMatchPredicate( w )); if ( c ) c->closeWindow(); } void RootInfo::moveResize(Window w, int x_root, int y_root, unsigned long direction) { Client* c = workspace->findClient( WindowMatchPredicate( w )); if ( c ) { updateXTime(); // otherwise grabbing may have old timestamp - this message should include timestamp c->NETMoveResize( x_root, y_root, (Direction)direction); } } void RootInfo::moveResizeWindow(Window w, int flags, int x, int y, int width, int height ) { Client* c = workspace->findClient( WindowMatchPredicate( w )); if ( c ) c->NETMoveResizeWindow( flags, x, y, width, height ); } void RootInfo::gotPing( Window w, Time timestamp ) { if( Client* c = workspace->findClient( WindowMatchPredicate( w ))) c->gotPing( timestamp ); } void RootInfo::changeShowingDesktop( bool showing ) { workspace->setShowingDesktop( showing ); } // **************************************** // Workspace // **************************************** /*! Handles workspace specific XEvents */ bool Workspace::workspaceEvent( XEvent * e ) { if ( mouse_emulation && (e->type == ButtonPress || e->type == ButtonRelease ) ) { mouse_emulation = FALSE; XUngrabKeyboard( qt_xdisplay(), qt_x_time ); } if ( e->type == PropertyNotify || e->type == ClientMessage ) { if ( netCheck( e ) ) return TRUE; } // events that should be handled before Clients can get them switch (e->type) { case ButtonPress: case ButtonRelease: was_user_interaction = true; // fallthrough case MotionNotify: if ( tab_grab || control_grab ) { tab_box->handleMouseEvent( e ); return TRUE; } break; case KeyPress: { was_user_interaction = true; KKeyNative keyX( (XEvent*)e ); uint keyQt = keyX.keyCodeQt(); kdDebug(125) << "Workspace::keyPress( " << keyX.key().toString() << " )" << endl; if (movingClient) { movingClient->keyPressEvent(keyQt); return true; } if( tab_grab || control_grab ) { tabBoxKeyPress( keyX ); return true; } break; } case KeyRelease: was_user_interaction = true; if( tab_grab || control_grab ) { tabBoxKeyRelease( e->xkey ); return true; } break; }; if( Client* c = findClient( WindowMatchPredicate( e->xany.window ))) { if( c->windowEvent( e )) return true; } else if( Client* c = findClient( WrapperIdMatchPredicate( e->xany.window ))) { if( c->windowEvent( e )) return true; } else if( Client* c = findClient( FrameIdMatchPredicate( e->xany.window ))) { if( c->windowEvent( e )) return true; } else { Window special = findSpecialEventWindow( e ); if( special != None ) if( Client* c = findClient( WindowMatchPredicate( special ))) { if( c->windowEvent( e )) return true; } } if( movingClient != NULL && movingClient->moveResizeGrabWindow() == e->xany.window && ( e->type == MotionNotify || e->type == ButtonPress || e->type == ButtonRelease )) { if( movingClient->windowEvent( e )) return true; } switch (e->type) { case CreateNotify: if ( e->xcreatewindow.parent == root && !QWidget::find( e->xcreatewindow.window) && !e->xcreatewindow.override_redirect ) { // see comments for allowClientActivation() XChangeProperty(qt_xdisplay(), e->xcreatewindow.window, atoms->kde_net_wm_user_creation_time, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&qt_x_time, 1); } break; case UnmapNotify: { // check for system tray windows if ( removeSystemTrayWin( e->xunmap.window, true ) ) { // If the system tray gets destroyed, the system tray // icons automatically get unmapped, reparented and mapped // again to the closest non-client ancestor due to // QXEmbed's SaveSet feature. Unfortunatly with kicker // this closest ancestor is not the root window, but our // decoration, so we reparent explicitely back to the root // window. XEvent ev; WId w = e->xunmap.window; if ( XCheckTypedWindowEvent (qt_xdisplay(), w, ReparentNotify, &ev) ) { if ( ev.xreparent.parent != root ) { XReparentWindow( qt_xdisplay(), w, root, 0, 0 ); addSystemTrayWin( w ); } } return TRUE; } return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt } case MapNotify: return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt case ReparentNotify: { //do not confuse Qt with these events. After all, _we_ are the //window manager who does the reparenting. return TRUE; } case DestroyNotify: { if ( removeSystemTrayWin( e->xdestroywindow.window, false ) ) return TRUE; return false; } case MapRequest: { updateXTime(); // e->xmaprequest.window is different from e->xany.window // TODO this shouldn't be necessary now Client* c = findClient( WindowMatchPredicate( e->xmaprequest.window )); if ( !c ) { // don't check for the parent being the root window, this breaks when some app unmaps // a window, changes something and immediately maps it back, without giving KWin // a chance to reparent it back to root // since KWin can get MapRequest only for root window children and // children of WindowWrapper (=clients), the check is AFAIK useless anyway // Note: Now the save-set support in Client::mapRequestEvent() actually requires that // this code doesn't check the parent to be root. // if ( e->xmaprequest.parent == root ) { //###TODO store previously destroyed client ids if ( addSystemTrayWin( e->xmaprequest.window ) ) return TRUE; c = createClient( e->xmaprequest.window, false ); if ( c != NULL && root != qt_xrootwin() ) { // TODO what is this? // TODO may use QWidget::create XReparentWindow( qt_xdisplay(), c->frameId(), root, 0, 0 ); } if( c == NULL ) // refused to manage, simply map it (most probably override redirect) XMapRaised( qt_xdisplay(), e->xmaprequest.window ); return true; } if ( c ) { c->windowEvent( e ); if ( !c->wantsTabFocus()) focus_chain.remove( c ); // TODO move focus_chain changes to functions return true; } break; } case EnterNotify: { if ( QWhatsThis::inWhatsThisMode() ) { QWidget* w = QWidget::find( e->xcrossing.window ); if ( w ) QWhatsThis::leaveWhatsThisMode(); } if( electricBorder(e)) return true; break; } case LeaveNotify: { if ( !QWhatsThis::inWhatsThisMode() ) break; // TODO is this cliente ever found, given that client events are searched above? Client* c = findClient( FrameIdMatchPredicate( e->xcrossing.window )); if ( c && e->xcrossing.detail != NotifyInferior ) QWhatsThis::leaveWhatsThisMode(); break; } case ConfigureRequest: { if ( e->xconfigurerequest.parent == root ) { XWindowChanges wc; unsigned int value_mask = 0; wc.border_width = 0; wc.x = e->xconfigurerequest.x; wc.y = e->xconfigurerequest.y; wc.width = e->xconfigurerequest.width; wc.height = e->xconfigurerequest.height; wc.sibling = None; wc.stack_mode = Above; value_mask = e->xconfigurerequest.value_mask | CWBorderWidth; XConfigureWindow( qt_xdisplay(), e->xconfigurerequest.window, value_mask, &wc ); return true; } break; } case KeyPress: if ( mouse_emulation ) return keyPressMouseEmulation( e->xkey ); break; case KeyRelease: if ( mouse_emulation ) return FALSE; break; case FocusIn: if( e->xfocus.window == rootWin() && ( e->xfocus.detail == NotifyDetailNone || e->xfocus.detail == NotifyPointerRoot )) { updateXTime(); // focusToNull() uses qt_x_time, which is old now (FocusIn has no timestamp) Window focus; int revert; XGetInputFocus( qt_xdisplay(), &focus, &revert ); if( focus == None || focus == PointerRoot ) { //kdWarning( 1212 ) << "X focus set to None/PointerRoot, reseting focus" << endl; Client *c = mostRecentlyActivatedClient(); if( c != NULL ) requestFocus( c, true ); else if( activateNextClient( NULL )) ; // ok, activated else focusToNull(); } } // fall through case FocusOut: return true; // always eat these, they would tell Qt that KWin is the active app case ClientMessage: if( electricBorder( e )) return true; break; default: break; } return FALSE; } // Some events don't have the actual window which caused the event // as e->xany.window (e.g. ConfigureRequest), but as some other // field in the XEvent structure. Window Workspace::findSpecialEventWindow( XEvent* e ) { switch( e->type ) { case CreateNotify: return e->xcreatewindow.window; case DestroyNotify: return e->xdestroywindow.window; case UnmapNotify: return e->xunmap.window; case MapNotify: return e->xmap.window; case MapRequest: return e->xmaprequest.window; case ReparentNotify: return e->xreparent.window; case ConfigureNotify: return e->xconfigure.window; case GravityNotify: return e->xgravity.window; case ConfigureRequest: return e->xconfigurerequest.window; case CirculateNotify: return e->xcirculate.window; case CirculateRequest: return e->xcirculaterequest.window; default: return None; }; } /*! Handles client messages sent to the workspace */ bool Workspace::netCheck( XEvent* e ) { unsigned int dirty = rootInfo->event( e ); if ( dirty & NET::DesktopNames ) saveDesktopSettings(); return dirty != 0; } // **************************************** // Client // **************************************** /*! General handler for XEvents concerning the client window */ bool Client::windowEvent( XEvent* e ) { if( e->xany.window == window()) // avoid doing stuff on frame or wrapper { unsigned long dirty[ 2 ]; info->event( e, dirty, 2 ); // pass through the NET stuff if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMName ) != 0 ) fetchName(); if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMIconName ) != 0 ) fetchIconicName(); if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMStrut ) != 0 || ( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut ) != 0 ) { if( isTopMenu()) // the fallback mode of KMenuBar may alter the strut checkWorkspacePosition(); // restore it workspace()->updateClientArea(); } if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMIcon) != 0 ) getIcons(); // Note there's a difference between userTime() and info->userTime() // info->userTime() is the value of the property, userTime() also includes // updates of the time done by KWin (ButtonPress on windowrapper etc.). if(( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2UserTime ) != 0 ) { workspace()->setWasUserInteraction(); updateUserTime( info->userTime()); } if(( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2StartupId ) != 0 ) startupIdChanged(); + if( dirty[ WinInfo::PROTOCOLS ] & NET::WMIconGeometry ) + { + if( demandAttentionKNotifyTimer != NULL ) + demandAttentionKNotify(); + } } // TODO move all focus handling stuff to separate file? switch (e->type) { case UnmapNotify: unmapNotifyEvent( &e->xunmap ); break; case DestroyNotify: destroyNotifyEvent( &e->xdestroywindow ); break; case MapRequest: // this one may pass the event to workspace return mapRequestEvent( &e->xmaprequest ); case ConfigureRequest: configureRequestEvent( &e->xconfigurerequest ); break; case PropertyNotify: propertyNotifyEvent( &e->xproperty ); break; case KeyPress: updateUserTime(); workspace()->setWasUserInteraction(); break; case ButtonPress: updateUserTime(); workspace()->setWasUserInteraction(); buttonPressEvent( e->xbutton.window, e->xbutton.button, e->xbutton.state, e->xbutton.x, e->xbutton.y, e->xbutton.x_root, e->xbutton.y_root ); break; case KeyRelease: // don't update user time on releases // e.g. if the user presses Alt+F2, the Alt release // would appear as user input to the currently active window break; case ButtonRelease: // don't update user time on releases // e.g. if the user presses Alt+F2, the Alt release // would appear as user input to the currently active window buttonReleaseEvent( e->xbutton.window, e->xbutton.button, e->xbutton.state, e->xbutton.x, e->xbutton.y, e->xbutton.x_root, e->xbutton.y_root ); break; case MotionNotify: motionNotifyEvent( e->xmotion.window, e->xmotion.state, e->xmotion.x, e->xmotion.y, e->xmotion.x_root, e->xmotion.y_root ); break; case EnterNotify: enterNotifyEvent( &e->xcrossing ); // MotionNotify is guaranteed to be generated only if the mouse // move start and ends in the window; for cases when it only // starts or only ends there, Enter/LeaveNotify are generated. // Fake a MotionEvent in such cases to make handle of mouse // events simpler (Qt does that too). motionNotifyEvent( e->xcrossing.window, e->xcrossing.state, e->xcrossing.x, e->xcrossing.y, e->xcrossing.x_root, e->xcrossing.y_root ); break; case LeaveNotify: motionNotifyEvent( e->xcrossing.window, e->xcrossing.state, e->xcrossing.x, e->xcrossing.y, e->xcrossing.x_root, e->xcrossing.y_root ); leaveNotifyEvent( &e->xcrossing ); break; case FocusIn: focusInEvent( &e->xfocus ); break; case FocusOut: focusOutEvent( &e->xfocus ); break; case ReparentNotify: break; case ClientMessage: clientMessageEvent( &e->xclient ); break; case ColormapChangeMask: if( e->xany.window == window()) { cmap = e->xcolormap.colormap; if ( isActive() ) workspace()->updateColormap(); } break; case VisibilityNotify: visibilityNotifyEvent( &e->xvisibility ); break; default: if( e->xany.window == window()) { if( e->type == Shape::shapeEvent() ) { is_shape = Shape::hasShape( window()); // workaround for #19644 updateShape(); } } break; } return true; // eat all events } /*! Handles map requests of the client window */ bool Client::mapRequestEvent( XMapRequestEvent* e ) { if( e->window != window()) { // Special support for the save-set feature, which is a bit broken. // If there's a window from one client embedded in another one, // e.g. using XEMBED, and the embedder suddenly looses its X connection, // save-set will reparent the embedded window to its closest ancestor // that will remains. Unfortunately, with reparenting window managers, // this is not the root window, but the frame (or in KWin's case, // it's the wrapper for the client window). In this case, // the wrapper will get ReparentNotify for a window it won't know, // which will be ignored, and then it gets MapRequest, as save-set // always maps. Returning true here means that Workspace::workspaceEvent() // will handle this MapRequest and manage this window (i.e. act as if // it was reparented to root window). if( e->parent == wrapperId()) return false; return true; // no messing with frame etc. } if( isTopMenu() && workspace()->managingTopMenus()) return true; // kwin controls these switch ( mappingState() ) { case WithdrawnState: assert( false ); // WMs are not supposed to manage clients in Withdrawn state, // manage(); // after initial mapping manage() is called from createClient() break; case IconicState: // also copied in clientMessage() if( isMinimized()) unminimize(); if( isShade()) setShade( ShadeNone ); if( !isOnCurrentDesktop()) { if( workspace()->allowClientActivation( this )) workspace()->activateClient( this ); else demandAttention(); } break; case NormalState: // TODO fake MapNotify? break; } return true; } /*! Handles unmap notify events of the client window */ void Client::unmapNotifyEvent( XUnmapEvent* e ) { if( e->window != window()) return; if( e->event != wrapperId()) { // most probably event from root window when initially reparenting bool ignore = true; if( e->event == workspace()->rootWin() && e->send_event ) ignore = false; // XWithdrawWindow() if( ignore ) return; } switch( mappingState()) { case IconicState: releaseWindow(); return; case NormalState: // maybe we will be destroyed soon. Check this first. XEvent ev; if( XCheckTypedWindowEvent (qt_xdisplay(), window(), DestroyNotify, &ev) ) // TODO I don't like this much { destroyClient(); // deletes this return; } releaseWindow(); break; default: assert( false ); } } void Client::destroyNotifyEvent( XDestroyWindowEvent* e ) { if( e->window != window()) return; destroyClient(); } bool blockAnimation = FALSE; /*! Handles client messages for the client window */ void Client::clientMessageEvent( XClientMessageEvent* e ) { if( e->window != window()) return; // ignore frame/wrapper // WM_STATE if ( e->message_type == atoms->kde_wm_change_state ) { if( isTopMenu() && workspace()->managingTopMenus()) return; // kwin controls these if( e->data.l[ 1 ] ) blockAnimation = true; if( e->data.l[ 0 ] == IconicState ) minimize(); else if( e->data.l[ 0 ] == NormalState ) { // copied from mapRequest() if( isMinimized()) unminimize(); if( isShade()) setShade( ShadeNone ); if( !isOnCurrentDesktop()) { if( workspace()->allowClientActivation( this )) workspace()->activateClient( this ); else demandAttention(); } } blockAnimation = false; } else if ( e->message_type == atoms->wm_change_state) { if( isTopMenu() && workspace()->managingTopMenus()) return; // kwin controls these if ( e->data.l[0] == IconicState ) minimize(); return; } } /*! Handles configure requests of the client window */ void Client::configureRequestEvent( XConfigureRequestEvent* e ) { if( e->window != window()) return; // ignore frame/wrapper if ( isResize() || isMove()) return; // we have better things to do right now if( fullscreen_mode == FullScreenNormal ) // refuse resizing of fullscreen windows { // but allow resizing fullscreen hacks in order to let them cancel fullscreen mode sendSyntheticConfigureNotify(); return; } if( isSplash() // no manipulations with splashscreens either || isTopMenu()) // topmenus neither { sendSyntheticConfigureNotify(); return; } if ( e->value_mask & CWBorderWidth ) { // first, get rid of a window border XWindowChanges wc; unsigned int value_mask = 0; wc.border_width = 0; value_mask = CWBorderWidth; XConfigureWindow( qt_xdisplay(), window(), value_mask, & wc ); } if( e->value_mask & ( CWX | CWY | CWHeight | CWWidth )) configureRequest( e->value_mask, e->x, e->y, e->width, e->height, 0, false ); if ( e->value_mask & CWStackMode ) restackWindow( e->above, e->detail, NET::FromApplication, userTime(), false ); // TODO sending a synthetic configure notify always is fine, even in cases where // the ICCCM doesn't require this - it can be though of as 'the WM decided to move // the window later'. The client should not cause that many configure request, // so this should not have any significant impact. With user moving/resizing // the it should be optimized though (see also Client::setGeometry()/plainResize()/move()). sendSyntheticConfigureNotify(); // SELI TODO accept configure requests for isDesktop windows (because kdesktop // may get XRANDR resize event before kwin), but check it's still at the bottom? } /*! Handles property changes of the client window */ void Client::propertyNotifyEvent( XPropertyEvent* e ) { if( e->window != window()) return; // ignore frame/wrapper switch ( e->atom ) { case XA_WM_NORMAL_HINTS: getWmNormalHints(); break; case XA_WM_NAME: fetchName(); break; case XA_WM_ICON_NAME: fetchIconicName(); break; case XA_WM_TRANSIENT_FOR: readTransient(); break; case XA_WM_HINTS: getWMHints(); getIcons(); // because KWin::icon() uses WMHints as fallback break; default: if ( e->atom == atoms->wm_protocols ) getWindowProtocols(); else if (e->atom == atoms->wm_client_leader ) getWmClientLeader(); else if( e->atom == qt_window_role ) window_role = staticWindowRole( window()); else if( e->atom == atoms->motif_wm_hints ) getMotifHints(); break; } } void Client::enterNotifyEvent( XCrossingEvent* e ) { if( e->window != frameId()) return; // care only about entering the whole frame if( e->mode == NotifyNormal || ( !options->focusPolicyIsReasonable() && e->mode == NotifyUngrab ) ) { if (options->shadeHover && isShade()) { delete shadeHoverTimer; shadeHoverTimer = new QTimer( this ); connect( shadeHoverTimer, SIGNAL( timeout() ), this, SLOT( shadeHover() )); shadeHoverTimer->start( options->shadeHoverInterval, TRUE ); } if ( options->focusPolicy == Options::ClickToFocus ) return; if ( options->autoRaise && !isDesktop() && !isDock() && !isTopMenu() && workspace()->focusChangeEnabled() && workspace()->topClientOnDesktop( workspace()->currentDesktop()) != this ) { delete autoRaiseTimer; autoRaiseTimer = new QTimer( this ); connect( autoRaiseTimer, SIGNAL( timeout() ), this, SLOT( autoRaise() ) ); autoRaiseTimer->start( options->autoRaiseInterval, TRUE ); } if ( options->focusPolicy != Options::FocusStrictlyUnderMouse && ( isDesktop() || isDock() || isTopMenu() ) ) return; if ( options->delayFocus ) workspace()->requestDelayFocus( this ); else workspace()->requestFocus( this ); return; } } void Client::leaveNotifyEvent( XCrossingEvent* e ) { if( e->window != frameId()) return; // care only about leaving the whole frame if ( e->mode == NotifyNormal ) { if ( !buttonDown ) { mode = PositionCenter; setCursor( arrowCursor ); } bool lostMouse = !rect().contains( QPoint( e->x, e->y ) ); // 'lostMouse' wouldn't work with e.g. B2 or Keramik, which have non-rectangular decorations // (i.e. the LeaveNotify event comes before leaving the rect and no LeaveNotify event // comes after leaving the rect) - so lets check if the pointer is really outside the window // TODO this still sucks if a window appears above this one - it should lose the mouse // if this window is another client, but not if it's a popup ... maybe after KDE3.1 :( // (repeat after me 'AARGHL!') if ( !lostMouse && e->detail != NotifyInferior ) { int d1, d2, d3, d4; unsigned int d5; Window w, child; if( XQueryPointer( qt_xdisplay(), frameId(), &w, &child, &d1, &d2, &d3, &d4, &d5 ) == False || child == None ) lostMouse = true; // really lost the mouse } if ( lostMouse ) { cancelAutoRaise(); workspace()->cancelDelayFocus(); cancelShadeHover(); if ( shade_mode == ShadeHover && !moveResizeMode && !buttonDown ) setShade( ShadeNormal ); } if ( options->focusPolicy == Options::FocusStrictlyUnderMouse ) if ( isActive() && lostMouse ) workspace()->requestFocus( 0 ) ; return; } } #define XCapL KKeyNative::modXLock() #define XNumL KKeyNative::modXNumLock() #define XScrL KKeyNative::modXScrollLock() void Client::grabButton( int modifier ) { unsigned int mods[ 8 ] = { 0, XCapL, XNumL, XNumL | XCapL, XScrL, XScrL | XCapL, XScrL | XNumL, XScrL | XNumL | XCapL }; for( int i = 0; i < 8; ++i ) XGrabButton( qt_xdisplay(), AnyButton, modifier | mods[ i ], wrapperId(), FALSE, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None ); } void Client::ungrabButton( int modifier ) { unsigned int mods[ 8 ] = { 0, XCapL, XNumL, XNumL | XCapL, XScrL, XScrL | XCapL, XScrL | XNumL, XScrL | XNumL | XCapL }; for( int i = 0; i < 8; ++i ) XUngrabButton( qt_xdisplay(), AnyButton, modifier | mods[ i ], wrapperId()); } #undef XCapL #undef XNumL #undef XScrL /* Releases the passive grab for some modifier combinations when a window becomes active. This helps broken X programs that missinterpret LeaveNotify events in grab mode to work properly (Motif, AWT, Tk, ...) */ void Client::updateMouseGrab() { // see Workspace::establishTabBoxGrab() if( isActive() && !workspace()->forcedGlobalMouseGrab()) { // remove the grab for no modifiers only if the window // is unobscured or if the user doesn't want click raise if( !options->clickRaise || not_obscured ) ungrabButton( None ); else grabButton( None ); ungrabButton( ShiftMask ); ungrabButton( ControlMask ); ungrabButton( ControlMask | ShiftMask ); } else { XUngrabButton( qt_xdisplay(), AnyButton, AnyModifier, wrapperId()); // simply grab all modifier combinations XGrabButton(qt_xdisplay(), AnyButton, AnyModifier, wrapperId(), FALSE, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None ); } } int qtToX11Button( Qt::ButtonState button ) { if( button == Qt::LeftButton ) return Button1; else if( button == Qt::MidButton ) return Button2; else if( button == Qt::RightButton ) return Button3; return AnyButton; } int qtToX11State( Qt::ButtonState state ) { int ret = 0; if( state & Qt::LeftButton ) ret |= Button1Mask; if( state & Qt::MidButton ) ret |= Button2Mask; if( state & Qt::RightButton ) ret |= Button3Mask; if( state & Qt::ShiftButton ) ret |= ShiftMask; if( state & Qt::ControlButton ) ret |= ControlMask; if( state & Qt::AltButton ) ret |= KKeyNative::modX(KKey::ALT); if( state & Qt::MetaButton ) ret |= KKeyNative::modX(KKey::WIN); return ret; } // Qt propagates mouse events up the widget hierachy, which means events // for the decoration window cannot be (easily) intercepted as X11 events bool Client::eventFilter( QObject* o, QEvent* e ) { if( decoration == NULL || o != decoration->widget()) return false; if( e->type() == QEvent::MouseButtonPress ) { QMouseEvent* ev = static_cast< QMouseEvent* >( e ); return buttonPressEvent( decorationId(), qtToX11Button( ev->button()), qtToX11State( ev->state()), ev->x(), ev->y(), ev->globalX(), ev->globalY() ); } if( e->type() == QEvent::MouseButtonRelease ) { QMouseEvent* ev = static_cast< QMouseEvent* >( e ); return buttonReleaseEvent( decorationId(), qtToX11Button( ev->button()), qtToX11State( ev->state()), ev->x(), ev->y(), ev->globalX(), ev->globalY() ); } if( e->type() == QEvent::MouseMove ) // FRAME i fake z enter/leave? { QMouseEvent* ev = static_cast< QMouseEvent* >( e ); return motionNotifyEvent( decorationId(), qtToX11State( ev->state()), ev->x(), ev->y(), ev->globalX(), ev->globalY() ); } if( e->type() == QEvent::Wheel ) { QWheelEvent* ev = static_cast< QWheelEvent* >( e ); bool r = buttonPressEvent( decorationId(), ev->delta() > 0 ? Button4 : Button5, qtToX11State( ev->state()), ev->x(), ev->y(), ev->globalX(), ev->globalY() ); r = r || buttonReleaseEvent( decorationId(), ev->delta() > 0 ? Button4 : Button5, qtToX11State( ev->state()), ev->x(), ev->y(), ev->globalX(), ev->globalY() ); return r; } if( e->type() == QEvent::Resize ) { QResizeEvent* ev = static_cast< QResizeEvent* >( e ); // Filter out resize events that inform about size different than frame size. // This will ensure that decoration->width() etc. and decoration->widget()->width() will be in sync. // These events only seem to be delayed events from initial resizing before show() was called // on the decoration widget. if( ev->size() != size()) return true; } return false; } // return value matters only when filtering events before decoration gets them bool Client::buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root ) { if (buttonDown) { if( w == wrapperId()) XAllowEvents(qt_xdisplay(), SyncPointer, CurrentTime ); //qt_x_time); return true; } if( w == wrapperId() || w == frameId() || w == decorationId()) { // FRAME neco s tohohle by se melo zpracovat, nez to dostane dekorace updateUserTime(); workspace()->setWasUserInteraction(); uint keyModX = (options->keyCmdAllModKey() == Qt::Key_Meta) ? KKeyNative::modX(KKey::WIN) : KKeyNative::modX(KKey::ALT); bool bModKeyHeld = keyModX != 0 && ( state & KKeyNative::accelModMaskX()) == keyModX; if( isSplash() && button == Button1 && !bModKeyHeld ) { // hide splashwindow if the user clicks on it hideClient( true ); if( w == wrapperId()) XAllowEvents(qt_xdisplay(), SyncPointer, CurrentTime ); //qt_x_time); return true; } Options::MouseCommand com = Options::MouseNothing; bool was_action = false; bool perform_handled = false; if ( bModKeyHeld ) { was_action = true; switch (button) { case Button1: com = options->commandAll1(); break; case Button2: com = options->commandAll2(); break; case Button3: com = options->commandAll3(); break; case Button4: case Button5: com = options->operationWindowMouseWheel( button == Button4 ? 120 : -120 ); break; } } else { // inactive inner window if( !isActive() && w == wrapperId()) { was_action = true; perform_handled = true; switch (button) { case Button1: com = options->commandWindow1(); break; case Button2: com = options->commandWindow2(); break; case Button3: com = options->commandWindow3(); break; default: com = Options::MouseActivateAndPassClick; } } // active inner window if( isActive() && w == wrapperId() && options->clickRaise && button < 4 ) // exclude wheel { com = Options::MouseActivateRaiseAndPassClick; was_action = true; perform_handled = true; } } if( was_action ) { bool replay = performMouseCommand( com, QPoint( x_root, y_root), perform_handled ); if ( isSpecialWindow()) replay = TRUE; if( w == wrapperId()) // these can come only from a grab XAllowEvents(qt_xdisplay(), replay? ReplayPointer : SyncPointer, CurrentTime ); //qt_x_time); return true; } } if( w == wrapperId()) // these can come only from a grab { XAllowEvents(qt_xdisplay(), ReplayPointer, CurrentTime ); //qt_x_time); return true; } if( w == decorationId()) return false; // don't eat decoration events if( w == frameId()) processDecorationButtonPress( button, state, x, y, x_root, y_root ); return true; } // this function processes button press events only after decoration decides not to handle them, // unlike buttonPressEvent(), which (when the window is decoration) filters events before decoration gets them void Client::processDecorationButtonPress( int button, int /*state*/, int x, int y, int x_root, int y_root ) { Options::MouseCommand com = Options::MouseNothing; bool active = isActive(); if ( !wantsInput() ) // we cannot be active, use it anyway active = TRUE; if ( button == Button1 ) com = active ? options->commandActiveTitlebar1() : options->commandInactiveTitlebar1(); else if ( button == Button2 ) com = active ? options->commandActiveTitlebar2() : options->commandInactiveTitlebar2(); else if ( button == Button3 ) com = active ? options->commandActiveTitlebar3() : options->commandInactiveTitlebar3(); if( button == Button1 && com != Options::MouseOperationsMenu // actions where it's not possible to get the matching && com != Options::MouseMinimize ) // mouse release event { mode = mousePosition( QPoint( x, y )); buttonDown = TRUE; moveOffset = QPoint( x, y ); invertedMoveOffset = rect().bottomRight() - moveOffset; unrestrictedMoveResize = false; setCursor( mode ); // update to sizeAllCursor if about to move } performMouseCommand( com, QPoint( x_root, y_root )); } // called from decoration void Client::processMousePressEvent( QMouseEvent* e ) { if( e->type() != QEvent::MouseButtonPress ) { kdWarning() << "processMousePressEvent()" << endl; return; } int button; switch( e->button()) { case LeftButton: button = Button1; break; case MidButton: button = Button2; break; case RightButton: button = Button3; break; default: return; } processDecorationButtonPress( button, e->state(), e->x(), e->y(), e->globalX(), e->globalY()); } // return value matters only when filtering events before decoration gets them bool Client::buttonReleaseEvent( Window w, int /*button*/, int state, int x, int y, int x_root, int y_root ) { if( w == decorationId() && !buttonDown) return false; if( w == wrapperId()) { XAllowEvents(qt_xdisplay(), SyncPointer, CurrentTime ); //qt_x_time); return true; } if( w != frameId() && w != decorationId() && w != moveResizeGrabWindow()) return true; x = this->x(); // translate from grab window to local coords y = this->y(); if ( (state & ( Button1Mask & Button2Mask & Button3Mask )) == 0 ) { buttonDown = FALSE; if ( moveResizeMode ) { finishMoveResize( false ); // mouse position is still relative to old Client position, adjust it QPoint mousepos( x_root - x, y_root - y ); mode = mousePosition( mousepos ); } setCursor( mode ); } return true; } static bool was_motion = false; static Time next_motion_time = CurrentTime; // Check whole incoming X queue for MotionNotify events // checking whole queue is done by always returning False in the predicate. // If there are more MotionNotify events in the queue, all until the last // one may be safely discarded (if a ButtonRelease event comes, a MotionNotify // will be faked from it, so there's no need to check other events). // This helps avoiding being overloaded by being flooded from many events // from the XServer. static Bool motion_predicate( Display*, XEvent* ev, XPointer ) { if( ev->type == MotionNotify ) { was_motion = true; next_motion_time = ev->xmotion.time; // for setting time } return False; } static bool waitingMotionEvent() { // The queue doesn't need to be checked until the X timestamp // of processes events reaches the timestamp of the last suitable // MotionNotify event in the queue. if( next_motion_time != CurrentTime && timestampCompare( qt_x_time, next_motion_time ) < 0 ) return true; was_motion = false; XSync( qt_xdisplay(), False ); // this helps to discard more MotionNotify events XEvent dummy; XCheckIfEvent( qt_xdisplay(), &dummy, motion_predicate, NULL ); return was_motion; } // return value matters only when filtering events before decoration gets them bool Client::motionNotifyEvent( Window w, int /*state*/, int x, int y, int x_root, int y_root ) { if( w != frameId() && w != decorationId() && w != moveResizeGrabWindow()) return true; // care only about the whole frame if ( !buttonDown ) { Position newmode = mousePosition( QPoint( x, y )); if( newmode != mode ) setCursor( newmode ); mode = newmode; // reset the timestamp for the optimization, otherwise with long passivity // the option in waitingMotionEvent() may be always true next_motion_time = CurrentTime; return false; } if( w == moveResizeGrabWindow()) { x = this->x(); // translate from grab window to local coords y = this->y(); } if( !waitingMotionEvent()) handleMoveResize( x, y, x_root, y_root ); return true; } void Client::focusInEvent( XFocusInEvent* e ) { if( e->window != window()) return; // only window gets focus if ( e->mode == NotifyUngrab ) return; // we don't care if ( e->detail == NotifyPointer ) return; // we don't care if( !isShown( false ) || !isOnCurrentDesktop()) // we unmapped it, but it got focus meanwhile -> return; // activateNextClient() already transferred focus elsewhere // check if this client is in should_get_focus list or if activation is allowed bool activate = workspace()->allowClientActivation( this, -1U, true ); workspace()->gotFocusIn( this ); // remove from should_get_focus list if( activate ) setActive( TRUE ); else { workspace()->restoreFocus(); demandAttention(); } } // When a client loses focus, FocusOut events are usually immediatelly // followed by FocusIn events for another client that gains the focus // (unless the focus goes to another screen, or to the nofocus widget). // Without this check, the former focused client would have to be // deactivated, and after that, the new one would be activated, with // a short time when there would be no active client. This can cause // flicker sometimes, e.g. when a fullscreen is shown, and focus is transferred // from it to its transient, the fullscreen would be kept in the Active layer // at the beginning and at the end, but not in the middle, when the active // client would be temporarily none (see Client::belongToLayer() ). // Therefore, the events queue is checked, whether it contains the matching // FocusIn event, and if yes, deactivation of the previous client will // be skipped, as activation of the new one will automatically deactivate // previously active client. static bool follows_focusin = false; static bool follows_focusin_failed = false; static Bool predicate_follows_focusin( Display*, XEvent* e, XPointer arg ) { if( follows_focusin || follows_focusin_failed ) return False; Client* c = ( Client* ) arg; if( e->type == FocusIn && c->workspace()->findClient( WindowMatchPredicate( e->xfocus.window ))) { // found FocusIn follows_focusin = true; return False; } // events that may be in the queue before the FocusIn event that's being // searched for if( e->type == FocusIn || e->type == FocusOut || e->type == KeymapNotify ) return False; follows_focusin_failed = true; // a different event - stop search return False; } static bool check_follows_focusin( Client* c ) { follows_focusin = follows_focusin_failed = false; XEvent dummy; // XCheckIfEvent() is used to make the search non-blocking, the predicate // always returns False, so nothing is removed from the events queue. // XPeekIfEvent() would block. XCheckIfEvent( qt_xdisplay(), &dummy, predicate_follows_focusin, (XPointer)c ); return follows_focusin; } void Client::focusOutEvent( XFocusOutEvent* e ) { if( e->window != window()) return; // only window gets focus if ( e->mode == NotifyGrab ) return; // we don't care if ( isShade() ) return; // here neither if ( e->detail != NotifyNonlinear && e->detail != NotifyNonlinearVirtual ) // SELI check all this return; // hack for motif apps like netscape if ( QApplication::activePopupWidget() ) return; if( !check_follows_focusin( this )) setActive( FALSE ); } void Client::visibilityNotifyEvent( XVisibilityEvent * e) { if( e->window != frameId()) return; // care only about the whole frame bool new_not_obscured = e->state == VisibilityUnobscured; if( not_obscured == new_not_obscured ) return; not_obscured = new_not_obscured; updateMouseGrab(); } // performs _NET_WM_MOVERESIZE void Client::NETMoveResize( int x_root, int y_root, NET::Direction direction ) { if( direction == NET::Move ) performMouseCommand( Options::MouseMove, QPoint( x_root, y_root )); else if( direction >= NET::TopLeft && direction <= NET::Left ) { static const Position convert[] = { PositionTopLeft, PositionTop, PositionTopRight, PositionRight, PositionBottomRight, PositionBottom, PositionBottomLeft, PositionLeft }; if(!isResizable() || isShade()) return; if( moveResizeMode ) finishMoveResize( false ); buttonDown = TRUE; moveOffset = QPoint( x_root - x(), y_root - y()); // map from global invertedMoveOffset = rect().bottomRight() - moveOffset; unrestrictedMoveResize = false; mode = convert[ direction ]; setCursor( mode ); if( !startMoveResize()) { buttonDown = false; setCursor( mode ); } } else if( direction == NET::KeyboardMove ) { // ignore mouse coordinates given in the message, mouse position is used by the moving algorithm QCursor::setPos( geometry().center() ); performMouseCommand( Options::MouseUnrestrictedMove, geometry().center()); } else if( direction == NET::KeyboardSize ) { // ignore mouse coordinates given in the message, mouse position is used by the resizing algorithm QCursor::setPos( geometry().bottomRight()); performMouseCommand( Options::MouseUnrestrictedResize, geometry().bottomRight()); } } void Client::keyPressEvent( uint key_code ) { updateUserTime(); if ( !isMove() && !isResize() ) return; bool is_control = key_code & Qt::CTRL; bool is_alt = key_code & Qt::ALT; key_code = key_code & 0xffff; int delta = is_control?1:is_alt?32:8; QPoint pos = QCursor::pos(); switch ( key_code ) { case Key_Left: pos.rx() -= delta; break; case Key_Right: pos.rx() += delta; break; case Key_Up: pos.ry() -= delta; break; case Key_Down: pos.ry() += delta; break; case Key_Space: case Key_Return: case Key_Enter: finishMoveResize( false ); buttonDown = FALSE; setCursor( mode ); break; case Key_Escape: finishMoveResize( true ); buttonDown = FALSE; setCursor( mode ); break; default: return; } QCursor::setPos( pos ); } // **************************************** // Group // **************************************** bool Group::groupEvent( XEvent* e ) { unsigned long dirty[ 2 ]; leader_info->event( e, dirty, 2 ); // pass through the NET stuff if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMIcon) != 0 ) getIcons(); if(( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2StartupId ) != 0 ) startupIdChanged(); return false; } } // namespace diff --git a/eventsrc b/eventsrc index f8506e8b5..923bd0a27 100644 --- a/eventsrc +++ b/eventsrc @@ -1,3532 +1,3542 @@ [!Global!] IconName=kwin Comment=The KDE Window Manager Comment[af]=Die Kde Venster Bestuurder Comment[ar]=مدير نوافذ كيدي Comment[az]=KDE Pəncərə İdarəcisi Comment[be]=Кіраваньне вокнамі KDE Comment[bg]=Мениджър на прозорци Comment[bn]=কে.ডি.ই উইণ্ডো ম্যানেজার Comment[br]=Merour prenester KDE Comment[bs]=KDE upravitelj prozorima Comment[ca]=El gestor de finestres KDE Comment[cs]=Správce oken KDE Comment[cy]=Y Trefnydd Ffenestri KDE Comment[da]=KDE Vindueshåndtering Comment[de]=KDE-Fenstermanager Comment[el]=Ο διαχειριστής παραθύρων του KDE Comment[eo]=KDE-fenestroadministrilo Comment[es]=El administrador de ventanas de KDE Comment[et]=KDE aknahaldur Comment[eu]=KDEren leiho kudeatzailea Comment[fa]=مدیر پنجره‌ی KDE Comment[fi]=KDE:n ikkunaohjelma Comment[fr]=Le gestionnaire de fenêtres de KDE Comment[fy]=De KDE-windowmanager Comment[ga]=Bainisteoir Fuinneoga KDE Comment[gl]=O Xestor de Fiestras de KDE Comment[he]=מנהל החלונות של KDE Comment[hi]=केडीई विंडो प्रबंधक Comment[hr]=KDE upravitelj prozorima Comment[hu]=KDE ablakkezelő Comment[id]=Manajer Jendela KDE Comment[is]=Gluggastjóri KDE Comment[it]=Il window manager di KDE Comment[ja]=KDEウィンドウマネージャ Comment[ko]=KDE 창 관리자 Comment[lo]=ລະບົບຈັດການຫນ້າຕ່າງຂອງ KDE Comment[lt]=KDE langų tvarkyklė Comment[lv]=KDE Logu Menedžeris Comment[mk]=KDE менаџер на прозорци Comment[mn]=КДЭ-Цонхны удирдагч Comment[mt]=Window manager tal-KDE Comment[nb]=KDE Vindusbehandler Comment[nds]=De KDE Finsterpleger Comment[nl]=De KDE-windowmanager Comment[nn]=KDE Vindaugshandterar Comment[nso]=Molaodi wa Window ya KDE Comment[oc]=Lo gestionari de finestres KDE Comment[pa]=KDE ਝਰੋਖਾ ਪ੍ਰਬੰਧਕ Comment[pl]=Menedżer okien KDE Comment[pt]=Gestor de janelas do KDE Comment[pt_BR]=Gerenciador de Janelas do KDE Comment[ro]=Managerul de ferestre KDE Comment[ru]=Оконный менеджер KDE Comment[se]=KDE lásegieđahalli Comment[sk]=Správca okien KDE Comment[sl]=Okenski upravitelj KDE Comment[sr]=KDE менаџер прозора Comment[sr@Latn]=KDE menadžer prozora Comment[sv]=KDE:s fönsterhanterare Comment[ta]=KDE சாளர மேலாளர் Comment[tg]=Мудири тирезаи KDE Comment[th]=ระบบจัดการหน้าต่างของ KDE Comment[tr]=KDE Pencere Yöneticisi Comment[uk]=Менеджер вікон KDE Comment[uz]=KDE ойна бошқарувчи Comment[ven]=Mulanguli wa windo ya KDE Comment[vi]=Trình quản lí cửa sổ của KDE Comment[wa]=Li manaedjeu di purneas di KDE Comment[xh]=Umphathi we Window ye KDE Comment[xx]=xxThe KDE Window Managerxx Comment[zh_CN]=KDE 窗口管理器 Comment[zh_TW]=KDE 視窗管理程式 Comment[zu]=Imenenja yama-Window ye-KDE [desktop1] Name=Change to Desktop 1 Name[af]=Verander na Werkskerm 1 Name[ar]=التغيير الى سطح المكتب 1 Name[az]=1. Masa Üstünə Get Name[bg]=Превключване на работен плот 1 Name[bn]=ডেস্কটপ ১-এ যাও Name[br]=Gwintañ da vurev 1 Name[bs]=Premjesti se na radnu površinu 1 Name[ca]=Canvi a l'escriptori 1 Name[cs]=Přepnutí na plochu 1 Name[cy]=Newid i Penbwrdd 1 Name[da]=Skift til desktop 1 Name[de]=Wechsel zu Arbeitsfläche 1 Name[el]=Αλλαγή στην επιφάνεια εργασίας 1 Name[eo]=Al tabulo 1 Name[es]=Cambiar al escritorio 1 Name[et]=Liikumine 1. töölauale Name[eu]=1 mahaigainera aldatu Name[fa]=تغییر به میزکار ۱ Name[fi]=Vaihda työpöytään 1 Name[fr]=Aller au bureau 1 Name[fy]=Gean nei buroblêd 1 Name[ga]=Téigh go Deasc 1 Name[gl]=Cambio ó Escritorio 1 Name[he]=מעבר לשולחן עבודה 1 Name[hi]=डेस्कटॉप 1 पर जाएँ Name[hr]=Premjesti se na radnu površinu 1 Name[hu]=Váltás az 1. asztalra Name[id]=Ganti ke Desktop 1 Name[is]=Birta skjáborð 1 Name[it]=Va al desktop 1 Name[ja]=デスクトップ1に移動 Name[ko]=첫번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີ່ທຳງານ 1 Name[lt]=Pereiti į darbastalį 1 Name[lv]=Nomainīt uz Darbvirsmu 1 Name[mk]=Кон површина 1 Name[mn]=Ажлын тавцан 1 рүү оч Name[mt]=Mur f' Desktop 1 Name[nb]=Bytt til skrivebord 1 Name[nds]=Na Schriefdisch 1 wesseln Name[nl]=Ga naar bureaublad 1 Name[nn]=Bytt til skrivebord 1 Name[nso]=Fetogela go Desktop 1 Name[oc]=Canvia au burèu 1 Name[pa]=ਵਿਹੜੇ ੧ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 1 Name[pt]=Mudar para o Ecrã 1 Name[pt_BR]=Mudar para a Área de Trabalho 1 Name[ro]=Trece în ecranul 1 Name[ru]=Перейти на рабочий стол 1 Name[se]=Mana vuosttáš čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 1 Name[sl]=Preklopi na namizje 1 Name[sr]=Прелаз на радну површину 1 Name[sr@Latn]=Prelaz na radnu površinu 1 Name[ss]=Tjintjela ku desktop 1 Name[sv]=Byt till skrivbord 1 Name[ta]=மேல்மேசை 1க்கு மாற்று Name[tg]=Гузариш ба мизи кории 1 Name[th]=สลับไปยังพื้นที่ทำงาน 1 Name[tr]=1. Masaüstüne Git Name[uk]=Стільниця 1 Name[uz]=Иш столи 1 га ўтиш Name[ven]=U shandukela kha desikithopo yau thoma Name[vi]=Đổi về Desktop 1 Name[wa]=Potchî sol prumî scribanne Name[xh]=Tshintshela kwi Desktop 1 Name[xx]=xxChange to Desktop 1xx Name[zh_CN]=更改到桌面 1 Name[zh_TW]=切換到桌面一 Name[zu]=Shintshela kwi-Desktop 1 Comment=Virtual desktop one is selected Comment[az]=1. Masa üstü seçildi Comment[be]=Выбраны першы віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 1 Comment[bn]=প্রথম ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Unan a zo diuzet Comment[bs]=Virtualna radna površina Jedan je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual u Comment[cs]=Je vybrána virtuální plocha 1 Comment[da]=Virtuel desktop én er valgt Comment[de]=Virtuelle Arbeitsfläche 1 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 1 Comment[eo]=Tabulo unua estas elektita Comment[es]=Seleccionado el escritorio virtual Uno Comment[et]=Esimene virtuaalne töölaud on valitud Comment[eu]=1 mahaigain birtuala hautatua dago. Comment[fi]=Virtuaalityöpöytä yksi on valittu Comment[fr]=Le bureau virtuel 1 est sélectionné Comment[fy]=Virtueel buroblêd ien is selektearre Comment[gl]=Selecciónase o escritorio virtual número Un Comment[he]=שולחן העבודה הווירטואלי אחד נבחר Comment[hi]=आभासी डेस्कटॉप एक चुना गया है Comment[hu]=Az 1. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð eitt er virkt Comment[it]=Il desktop virtuale uno viene selezionato. Comment[ja]=仮想デスクトップ1が選択されました Comment[lt]=Pasirinktas pirmas menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 1. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 1 Comment[mt]=Desktop Virtwali Wieħed huwa Magħżul Comment[nb]=Virtuelt skrivebord én er valgt Comment[nds]=De virtuelle Schriefdisch Een is utsöcht Comment[nl]=Virtueel bureaublad een is geselecteerd Comment[nn]=Virtuelt skrivebord éin vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੧ ਚੁਣਿਆ Comment[pl]=Wybrano pierwszy pulpit Comment[pt]=O ecrã virtual um é seleccionado Comment[pt_BR]=Área de trabalho virtual 1 está selecionada Comment[ro]=Ecranul virtual 1 este selectat Comment[ru]=Выбран первый виртуальный рабочий стол Comment[se]=Vuosttáš virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 1 Comment[sl]=Izbrano je prvo navidezno namizje Comment[sr]=Изабрана је прва виртуелна радна површина Comment[sr@Latn]=Izabrana je prva virtuelna radna površina Comment[sv]=Virtuellt skrivbord ett är valt Comment[ta]=மெய்நிகர் மேல்மேசை ஒன்று தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü bir seçili Comment[uk]=Вибрано віртуальну стільницю Один Comment[uz]=Биринчи виртуал иш столи танланган Comment[wa]=Li prumî forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop one is selectedxx Comment[zh_CN]=选择了虚拟桌面 1 default_sound=KDE_Desktop_1.ogg default_presentation=0 [desktop2] Name=Change to Desktop 2 Name[af]=Verander na Werkskerm 2 Name[ar]=التغيير الى سطح المكتب 2 Name[az]=2. Masa Üstünə Get Name[bg]=Превключване на работен плот 2 Name[bn]=ডেস্কটপ ২-এ যাও Name[br]=Gwintañ da vurev 2 Name[bs]=Premjesti se na radnu površinu 2 Name[ca]=Canvi a l'escriptori 2 Name[cs]=Přepnutí na plochu 2 Name[cy]=Newid i Penbwrdd 2 Name[da]=Skift til desktop 2 Name[de]=Wechsel zu Arbeitsfläche 2 Name[el]=Αλλαγή στην επιφάνεια εργασίας 2 Name[eo]=Al tabulo 2 Name[es]=Cambiar al escritorio 2 Name[et]=Liikumine 2. töölauale Name[eu]=2 mahaigainera aldatu Name[fa]=تغییر به میزکار ۲ Name[fi]=Vaihda työpöytään 2 Name[fr]=Aller au bureau 2 Name[fy]=Gean nei buroblêd 2 Name[ga]=Téigh go Deasc 2 Name[gl]=Cambio ó Escritorio 2 Name[he]=מעבר לשולחן עבודה 2 Name[hi]=डेस्कटॉप 2 पर जाएँ Name[hr]=Premjesti se na radnu površinu 2 Name[hu]=Váltás a 2. asztalra Name[id]=Ganti ke Desktop 2 Name[is]=Birta skjáborð 2 Name[it]=Va al desktop 2 Name[ja]=デスクトップ2に移動 Name[ko]=두번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີທຳງານ 2 Name[lt]=Pereiti į darbastalį 2 Name[lv]=Nomainīt uz Darbvirsmu 2 Name[mk]=Кон површина 2 Name[mn]=Ажлын тавцан 2 рүү оч Name[mt]=Mur f' Desktop 2 Name[nb]=Bytt til skrivebord 2 Name[nds]=Na Schriefdisch 2 wesseln Name[nl]=Ga naar bureaublad 2 Name[nn]=Bytt til skrivebord 2 Name[nso]=Fetogela go Desktop 2 Name[oc]=Canvia au burèu 2 Name[pa]=ਵਿਹੜੇ ੨ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 2 Name[pt]=Mudar para o Ecrã 2 Name[pt_BR]=Mudar para a Área de Trabalho 2 Name[ro]=Trece în ecranul 2 Name[ru]=Перейти на рабочий стол 2 Name[se]=Mana nuppi čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 2 Name[sl]=Preklopi na namizje 2 Name[sr]=Прелаз на радну површину 2 Name[sr@Latn]=Prelaz na radnu površinu 2 Name[ss]=Tjintjela ku desktop 2 Name[sv]=Byt till skrivbord 2 Name[ta]=மேல்மேசை 2க்கு மாற்று Name[tg]=Гузариш ба мизи кории 2 Name[th]=สลับไปยังพื้นที่ทำงาน 2 Name[tr]=2. Masaüstüne Git Name[uk]=Стільниця 2 Name[uz]=Иш столи 2 га ўтиш Name[ven]=U shandukela kha desikithopo ya vhuvhili Name[vi]=Đổi về Desktop 2 Name[wa]=Potchî sol deujhinme sicribanne Name[xh]=Tshintshela kwi Desktop 2 Name[xx]=xxChange to Desktop 2xx Name[zh_CN]=更改到桌面 2 Name[zh_TW]=切換到桌面二 Name[zu]=Shintshela kwi-Desktop 2 Comment=Virtual desktop two is selected Comment[az]=2. Masa üstü seçildi Comment[be]=Выбраны другі віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 2 Comment[bn]=দ্বিতীয় ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Daou a zo diuzet Comment[bs]=Virtualna radna površina Dva je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual dos Comment[cs]=Je vybrána virtuální plocha 2 Comment[da]=Virtuel desktop to er valgt Comment[de]=Virtuelle Arbeitsfläche 2 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 2 Comment[eo]=Tabulo dua estas elektita Comment[es]=Seleccionado el escritorio virtual Dos Comment[et]=Teine virtuaalne töölaud on valitud Comment[eu]=2 mahaigain birtuala hautatua dago Comment[fi]=Virtuaalityöpöytä kaksi on valittu Comment[fr]=Le bureau virtuel 2 est sélectionné Comment[fy]=Virtueel buroblêd twa is selektearre Comment[gl]=Selecciónase o escritorio virtual número Dous Comment[he]=שולחן העבודה הווירטואלי שתיים נבחר Comment[hi]=आभासी डेस्कटॉप दो चुना गया है Comment[hu]=A 2. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð tvö er virkt Comment[it]=Il desktop virtuale due viene selezionato. Comment[ja]=仮想デスクトップ2が選択されました Comment[lt]=Pasirinktas antras menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 2. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 2 Comment[mt]=Desktop Virtwali Tnejn huwa Magħżul Comment[nb]=Virtuelt skrivebord to er valgt Comment[nds]=De virtuelle Schriefdisch Twee is utsöcht Comment[nl]=Virtueel bureaublad twee is geselecteerd Comment[nn]=Virtuelt skrivebord to vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੨ ਚੁਣਿਆ Comment[pl]=Wybrano drugi pulpit Comment[pt]=O ecrã virtual dois é seleccionado Comment[pt_BR]=Área de trabalho virtual 2 está selecionada Comment[ro]=Ecranul virtual 2 este selectat Comment[ru]=Выбран второй виртуальный рабочий стол Comment[se]=Nubbi virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 2 Comment[sl]=Izbrano je drugo navidezno namizje Comment[sr]=Изабрана је друга виртуелна радна површина Comment[sr@Latn]=Izabrana je druga virtuelna radna površina Comment[sv]=Virtuellt skrivbord två är valt Comment[ta]=மெய்நிகர் மேல்மேசை இரண்டு தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü iki seçili Comment[uk]=Вибрано віртуальну стільницю Два Comment[uz]=Иккинчи виртуал иш столи танланган Comment[wa]=Li deujhinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop two is selectedxx Comment[zh_CN]=选择了虚拟桌面 2 default_sound=KDE_Desktop_2.ogg default_presentation=0 [desktop3] Name=Change to Desktop 3 Name[af]=Verander na Werkskerm 3 Name[ar]=التغيير الى سطح المكتب 3 Name[az]=3. Masa Üstünə Get Name[bg]=Превключване на работен плот 3 Name[bn]=ডেস্কটপ ৩-এ যাও Name[br]=Gwintañ da vurev 3 Name[bs]=Premjesti se na radnu površinu 3 Name[ca]=Canvi a l'escriptori 3 Name[cs]=Přepnutí na plochu 3 Name[cy]=Newid i Penbwrdd 3 Name[da]=Skift til desktop 3 Name[de]=Wechsel Arbeitsfläche 3 Name[el]=Αλλαγή στην επιφάνεια εργασίας 3 Name[eo]=Al tabulo 3 Name[es]=Cambiar al escritorio 3 Name[et]=Liikumine 3. töölauale Name[eu]=3 mahaigainera aldatu Name[fa]=تغییر به میزکار ۳ Name[fi]=Vaihda työpöytään 3 Name[fr]=Aller au bureau 3 Name[fy]=Gean nei buroblêd 3 Name[ga]=Téigh go Deasc 3 Name[gl]=Cambio ó Escritorio 3 Name[he]=מעבר לשולחן עבודה 3 Name[hi]=डेस्कटॉप 3 पर जाएँ Name[hr]=Premjesti se na radnu površinu 3 Name[hu]=Váltás a 3. asztalra Name[id]=Ganti ke Desktop 3 Name[is]=Birta skjáborð 3 Name[it]=Va al desktop 3 Name[ja]=デスクトップ3に移動 Name[ko]=세번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີ່ທຳງານ 3 Name[lt]=Pereiti į darbastalį 3 Name[lv]=Nomainīt uz Darbvirsmu 3 Name[mk]=Кон површина 3 Name[mn]=Ажлын тавцан 3 рүү оч Name[mt]=Mur f' Desktop 3 Name[nb]=Bytt til skrivebord 3 Name[nds]=Na Schriefdisch 3 wesseln Name[nl]=Ga naar bureaublad 3 Name[nn]=Bytt til skrivebord 3 Name[nso]=Fetogela go Desktop 3 Name[oc]=Canvia au burèu 3 Name[pa]=ਵਿਹੜੇ ੩ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 3 Name[pt]=Mudar para o Ecrã 3 Name[pt_BR]=Mudar para o Área de Trabalho 3 Name[ro]=Trece în ecranul 3 Name[ru]=Перейти на рабочий стол 3 Name[se]=Mana goalmmát čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 3 Name[sl]=Preklopi na namizje 3 Name[sr]=Прелаз на радну површину 3 Name[sr@Latn]=Prelaz na radnu površinu 3 Name[ss]=Tjintjela ku desktop 3 Name[sv]=Byt till skrivbord 3 Name[ta]=மேல்மேசை 3க்கு மாற்று Name[tg]=Гузариш ба мизи кории 3 Name[th]=สลับไปยังพื้นที่ทำงาน 3 Name[tr]=3. Masaüstüne Git Name[uk]=Стільниця 3 Name[uz]=Иш столи 3 га ўтиш Name[ven]=U shandukela kha desikithopo ya vhuraru Name[vi]=Đổi về Desktop 3 Name[wa]=Potchî sol troejhinme sicribanne Name[xh]=Tshintshela kwi Desktop 3 Name[xx]=xxChange to Desktop 3xx Name[zh_CN]=更改到桌面 3 Name[zh_TW]=切換到桌面三 Name[zu]=Shintshela kwi-Desktop 3 Comment=Virtual desktop three is selected Comment[az]=3. Masa üstü seçildi Comment[be]=Выбраны трэці віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 3 Comment[bn]=তৃতীয় ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Tri a zo diuzet Comment[bs]=Virtualna radna površina Tri je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual tres Comment[cs]=Je vybrána virtuální plocha 3 Comment[da]=Virtuel desktop tre er valgt Comment[de]=Virtuelle Arbeitsfläche 3 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 2 Comment[eo]=Tabulo tria estas elektita Comment[es]=Seleccionado el escritorio virtual Tres Comment[et]=Kolmas virtuaalne töölaud on valitud Comment[eu]=3 mahaigain birtuala hautatua dago. Comment[fi]=Virtuaalityöpöytä kolme on valittu Comment[fr]=Le bureau virtuel 3 est sélectionné Comment[fy]=Virtueel buroblêd trije is selektearre Comment[gl]=Selecciónase o escritorio virtual número Tres Comment[he]=שולחן העבודה הווירטואלי שלוש נבחר Comment[hi]=आभासी डेस्कटॉप तीन चुना गया है Comment[hu]=A 3. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð þrjú er virkt Comment[it]=Il desktop virtuale tre viene selezionato. Comment[ja]=仮想デスクトップ3が選択されました Comment[lt]=Pasirinktas trečias menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 3. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 3 Comment[mt]=Desktop Virtwali Tlieta huwa Magħżul Comment[nb]=Virtuelt skrivebord tre er valgt Comment[nds]=De virtuelle Schriefdisch Dree is utsöcht Comment[nl]=Virtueel bureaublad drie is geselecteerd Comment[nn]=Virtuelt skrivebord tre vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੩ ਚੁਣਿਆ Comment[pl]=Wybrano trzeci pulpit Comment[pt]=O ecrã virtual três é seleccionado Comment[pt_BR]=Área de trabalho virtual 3 está selecionada Comment[ro]=Ecranul virtual 3 este selectat Comment[ru]=Выбран третий виртуальный рабочий стол Comment[se]=Goalmmát virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 3 Comment[sl]=Izbrano je tretje navidezno namizje Comment[sr]=Изабрана је трећа виртуелна радна површина Comment[sr@Latn]=Izabrana je treća virtuelna radna površina Comment[sv]=Virtuellt skrivbord tre är valt Comment[ta]=மெய்நிகர் மேல்மேசை மூன்று தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü üç seçili Comment[uk]=Вибрано віртуальну стільницю Три Comment[uz]=Учинчи виртуал иш столи танланган Comment[wa]=Li troejhinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop three is selectedxx Comment[zh_CN]=选择了虚拟桌面 3 default_sound=KDE_Desktop_3.ogg default_presentation=0 [desktop4] Name=Change to Desktop 4 Name[af]=Verander na Werkskerm 4 Name[ar]=التغيير الى سطح المكتب 4 Name[az]=4. Masa Üstünə Get Name[bg]=Превключване на работен плот 4 Name[bn]=ডেস্কটপ ৪-এ যাও Name[br]=Gwintañ da vurev 4 Name[bs]=Premjesti se na radnu površinu 4 Name[ca]=Canvi a l'escriptori 4 Name[cs]=Přepnutí na plochu 4 Name[cy]=Newid i Penbwrdd 4 Name[da]=Skift til desktop 4 Name[de]=Wechsel zu Arbeitsfläche 4 Name[el]=Αλλαγή στην επιφάνεια εργασίας 4 Name[eo]=Al tabulo 4 Name[es]=Cambiar al escritorio 4 Name[et]=Liikumine 4. töölauale Name[eu]=4 mahaigainera aldatu Name[fa]=تغییر به میزکار ۴ Name[fi]=Vaihda työpöytään 4 Name[fr]=Aller au bureau 4 Name[fy]=Gean nei buroblêd 4 Name[ga]=Téigh go Deasc 4 Name[gl]=Cambio ó Escritorio 4 Name[he]=מעבר לשולחן עבודה 4 Name[hi]=डेस्कटॉप 4 पर जाएँ Name[hr]=Premjesti se na radnu površinu 4 Name[hu]=Váltás a 4. asztalra Name[id]=Ganti ke Desktop 4 Name[is]=Birta skjáborð 4 Name[it]=Va al desktop 4 Name[ja]=デスクトップ4に移動 Name[ko]=네번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີ່ທຳງານ 4 Name[lt]=Pereiti į darbastalį 4 Name[lv]=Nomainīt uz Darbvirsmu 4 Name[mk]=Кон површина 4 Name[mn]=Ажлын тавцан 41 рүү оч Name[mt]=Mur f' Desktop 4 Name[nb]=Bytt til skrivebord 4 Name[nds]=Na Schriefdisch 4 wesseln Name[nl]=Ga naar bureaublad 4 Name[nn]=Bytt til skrivebord 4 Name[nso]=Fetogela go Desktop 4 Name[oc]=Canvia au burèu 4 Name[pa]=ਵਿਹੜੇ ੪ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 4 Name[pt]=Mudar para o Ecrã 4 Name[pt_BR]=Mudar para o Área de Trabalho 4 Name[ro]=Trece în ecranul 4 Name[ru]=Перейти на рабочий стол 4 Name[se]=Mana njeallját čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 4 Name[sl]=Preklopi na namizje 4 Name[sr]=Прелаз на радну површину 4 Name[sr@Latn]=Prelaz na radnu površinu 4 Name[ss]=Tjintjela ku desktop 4 Name[sv]=Byt till skrivbord 4 Name[ta]=மேல்மேசை 4க்கு மாற்று Name[tg]=Гузариш ба мизи кории 4 Name[th]=สลับไปยังพื้นที่ทำงาน 4 Name[tr]=4. Masaüstüne Git Name[uk]=Стільниця 4 Name[uz]=Иш столи 4 га ўтиш Name[ven]=U shandukela kha desikithopo ya vhuna Name[vi]=Đổi về Desktop 4 Name[wa]=Potchî sol cwatrinme sicribanne Name[xh]=Tshintshela kwi Desktop 4 Name[xx]=xxChange to Desktop 4xx Name[zh_CN]=更改到桌面 4 Name[zh_TW]=切換到桌面四 Name[zu]=Shintshela kwi-Desktop 4 Comment=Virtual desktop four is selected Comment[az]=4. Masa üstü seçildi Comment[be]=Выбраны чацьверты віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 4 Comment[bn]=চতুর্থ ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Pevar a zo diuzet Comment[bs]=Virtualna radna površina Četiri je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual quatre Comment[cs]=Je vybrána virtuální plocha 4 Comment[da]=Virtuel desktop fire er valgt Comment[de]=Virtuelle Arbeitsfläche 4 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 4 Comment[eo]=Tabulo kvara estas elektita Comment[es]=Seleccionado el escritorio virtual Cuatro Comment[et]=Neljas virtuaalne töölaud on valitud Comment[eu]=4 mahaigain birtuala hautatua dago Comment[fi]=Virtuaalityöpöytä neljä on valittu Comment[fr]=Le bureau virtuel 4 est sélectionné Comment[fy]=Virtueel buroblêd fjouwer is selektearre Comment[gl]=Selecciónase o escritorio virtual número Catro Comment[he]=שולחן העבודה הווירטואלי ארבע נבחר Comment[hi]=आभासी डेस्कटॉप चार चुना गया है Comment[hu]=A 4. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð fjögur er virkt Comment[it]=Il desktop virtuale quattro viene selezionato. Comment[ja]=仮想デスクトップ4が選択されました Comment[lt]=Pasirinktas ketvirtas menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 4. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 4 Comment[mt]=Desktop Virtwali Erbgħa huwa Magħżul Comment[nb]=Virtuelt skrivebord fire er valgt Comment[nds]=De virtuelle Schriefdisch Veer is utsöcht Comment[nl]=Virtueel bureaublad vier is geselecteerd Comment[nn]=Virtuelt skrivebord fire vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੪ ਚੁਣਿਆ Comment[pl]=Wybrano czwarty pulpit Comment[pt]=O ecrã virtual quatro é seleccionado Comment[pt_BR]=Área de trabalho virtual 4 está selecionada Comment[ro]=Ecranul virtual 4 este selectat Comment[ru]=Выбран четвёртый виртуальный рабочий стол Comment[se]=Njeallját virtuella čállinbeavde lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 4 Comment[sl]=Izbrano je četrto navidezno namizje Comment[sr]=Изабрана је четврта виртуелна радна површина Comment[sr@Latn]=Izabrana je četvrta virtuelna radna površina Comment[sv]=Virtuellt skrivbord fyra är valt Comment[ta]=மெய்நிகர் மேல்மேசை நான்கு தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü dört seçili Comment[uk]=Вибрано віртуальну стільницю Чотири Comment[uz]=Тўртинчи виртуал иш столи танланган Comment[wa]=Li cwatrinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop four is selectedxx Comment[zh_CN]=选择了虚拟桌面 4 default_sound=KDE_Desktop_4.ogg default_presentation=0 [desktop5] Name=Change to Desktop 5 Name[af]=Verander na Werkskerm 5 Name[ar]=التغيير الى سطح المكتب 5 Name[az]=5. Masa Üstünə Get Name[bg]=Превключване на работен плот 5 Name[bn]=ডেস্কটপ ৫-এ যাও Name[br]=Gwintañ da vurev 5 Name[bs]=Premjesti se na radnu površinu 5 Name[ca]=Canvi a l'escriptori 5 Name[cs]=Přepnutí na plochu 5 Name[cy]=Newid i Penbwrdd 5 Name[da]=Skift til desktop 5 Name[de]=Wechsel zu Arbeitsfläche 5 Name[el]=Αλλαγή στην επιφάνεια εργασίας 5 Name[eo]=Al tabulo 5 Name[es]=Cambiar al escritorio 5 Name[et]=Liikumine 5. töölauale Name[eu]=5 mahaigainera aldatu Name[fa]=تغییر به میزکار ۵ Name[fi]=Vaihda työpöytään 5 Name[fr]=Aller au bureau 5 Name[fy]=Gean nei buroblêd 5 Name[ga]=Téigh go Deasc 5 Name[gl]=Cambio ó Escritorio 5 Name[he]=מעבר לשולחן עבודה 5 Name[hi]=डेस्कटॉप 5 पर जाएँ Name[hr]=Premjesti se na radnu površinu 5 Name[hu]=Váltás az 5. asztalra Name[id]=Ganti ke Desktop 5 Name[is]=Birta skjáborð 5 Name[it]=Va al desktop 5 Name[ja]=デスクトップ5に移動 Name[ko]=다섯번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນຈທີ່ທຳງານ 5 Name[lt]=Pereiti į darbastalį 5 Name[lv]=Nomainīt uz Darbvirsmu 5 Name[mk]=Кон површина 5 Name[mn]=Ажлын тавцан 5 рүү оч Name[mt]=Mur f' Desktop 5 Name[nb]=Bytt til skrivebord 5 Name[nds]=Na Schriefdisch 5 wesseln Name[nl]=Ga naar bureaublad 5 Name[nn]=Bytt til skrivebord 5 Name[nso]=Fetogela go Desktop 5 Name[oc]=Canvia au burèu 5 Name[pa]=ਵਿਹੜੇ ੫ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 5 Name[pt]=Mudar para o Ecrã 5 Name[pt_BR]=Mudar para o Área de Trabalho 5 Name[ro]=Trece în ecranul 5 Name[ru]=Перейти на рабочий стол 5 Name[se]=Mana viđát čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 5 Name[sl]=Preklopi na namizje 5 Name[sr]=Прелаз на радну површину 5 Name[sr@Latn]=Prelaz na radnu površinu 5 Name[ss]=Tjintjela ku desktop 5 Name[sv]=Byt till skrivbord 5 Name[ta]=மேல்மேசை 5க்கு மாற்று Name[tg]=Гузариш ба мизи кории 5 Name[th]=สลับไปยังพื้นที่ทำงาน 5 Name[tr]=5. Masaüstüne Git Name[uk]=Стільниця 5 Name[uz]=Иш столи 5 га ўтиш Name[ven]=U shandukela kha desikithopo ya vhutanu Name[vi]=Đổi về Desktop 5 Name[wa]=Potchî sol cénkinme sicribanne Name[xh]=Tshintshela kwi Desktop 5 Name[xx]=xxChange to Desktop 5xx Name[zh_CN]=更改到桌面 5 Name[zh_TW]=切換到桌面五 Name[zu]=Shintshela kwi-Desktop 5 Comment=Virtual desktop five is selected Comment[az]=5. Masa üstü seçildi Comment[be]=Выбраны пяты віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 5 Comment[bn]=পঞ্চম ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Pemp a zo diuzet Comment[bs]=Virtualna radna površina Pet je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual cinc Comment[cs]=Je vybrána virtuální plocha 5 Comment[da]=Virtuel desktop fem er valgt Comment[de]=Virtuelle Arbeitsfläche 5 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 5 Comment[eo]=Tabulo kvina estas elektita Comment[es]=Seleccionado el escritorio virtual Cinco Comment[et]=Viies virtuaalne töölaud on valitud Comment[eu]=5 mahaigain birtuala hautatua dago Comment[fi]=Virtuaalityöpöytä viisi on valittu Comment[fr]=Le bureau virtuel 5 est sélectionné Comment[fy]=Virtueel buroblêd viif is selektearre Comment[gl]=Selecciónase o escritorio virtual número Cinco Comment[he]=שולחן העבודה הווירטואלי חמש נבחר Comment[hi]=आभासी डेस्कटॉप पांच चुना गया है Comment[hu]=Az 5. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð fimm er virkt Comment[it]=Il desktop virtuale cinque viene selezionato. Comment[ja]=仮想デスクトップ5が選択されました Comment[lt]=Pasirinktas penktas menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 5. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 5 Comment[mt]=Desktop Virtwali Ħamsa huwa Magħżul Comment[nb]=Virtuelt skrivebord fem er valgt Comment[nds]=De virtuelle Schriefdisch Fief is utsöcht Comment[nl]=Virtueel bureaublad vijf is geselecteerd Comment[nn]=Virtuelt skrivebord fem vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੫ ਚੁਣਿਆ Comment[pl]=Wybrano piąty pulpit Comment[pt]=O ecrã virtual cinco é seleccionado Comment[pt_BR]=Área de trabalho virtual 5 está selecionada Comment[ro]=Ecranul virtual 5 este selectat Comment[ru]=Выбран пятый виртуальный рабочий стол Comment[se]=Viđát virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 5 Comment[sl]=Izbrano je peto navidezno namizje Comment[sr]=Изабрана је пета виртуелна радна површина Comment[sr@Latn]=Izabrana je peta virtuelna radna površina Comment[sv]=Virtuellt skrivbord fem är valt Comment[ta]=மெய்நிகர் மேல்மேசை ஐந்து தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü beş seçili Comment[uk]=Вибрано віртуальну стільницю П'ять Comment[uz]=Бешинчи виртуал иш столи танланган Comment[wa]=Li cénkinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop five is selectedxx Comment[zh_CN]=选择了虚拟桌面 5 default_sound=KDE_Desktop_5.ogg default_presentation=0 [desktop6] Name=Change to Desktop 6 Name[af]=Verander na Werkskerm 6 Name[ar]=التغيير الى سطح المكتب 6 Name[az]=6. Masa Üstünə Get Name[bg]=Превключване на работен плот 6 Name[bn]=ডেস্কটপ ৬-এ যাও Name[br]=Gwintañ da vurev 6 Name[bs]=Premjesti se na radnu površinu 6 Name[ca]=Canvi a l'escriptori 6 Name[cs]=Přepnutí na plochu 6 Name[cy]=Newid i Penbwrdd 6 Name[da]=Skift til desktop 6 Name[de]=Wechsel zu Arbeitsfläche 6 Name[el]=Αλλαγή στην επιφάνεια εργασίας 6 Name[eo]=Al tabulo 6 Name[es]=Cambiar al escritorio 6 Name[et]=Liikumine 6. töölauale Name[eu]=6 mahaigainera aldatu Name[fa]=تغییر به میزکار ۶ Name[fi]=Vaihda työpöytään 6 Name[fr]=Aller au bureau 6 Name[fy]=Gean nei buroblêd 6 Name[ga]=Téigh go Deasc 6 Name[gl]=Cambio ó Escritorio 6 Name[he]=מעבר לשולחן עבודה 6 Name[hi]=डेस्कटॉप 6 पर जाएँ Name[hr]=Premjesti se na radnu površinu 6 Name[hu]=Váltás a 6. asztalra Name[id]=Ganti ke Desktop 6 Name[is]=Birta skjáborð 6 Name[it]=Va al desktop 6 Name[ja]=デスクトップ6に移動 Name[ko]=여섯번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີ່ທຳງານ 6 Name[lt]=Pereiti į darbastalį 6 Name[lv]=Nomainīt uz Darbvirsmu 6 Name[mk]=Кон површина 6 Name[mn]=Ажлын тавцан 6 рүү оч Name[mt]=Mur f' Desktop 6 Name[nb]=Bytt til skrivebord 6 Name[nds]=Na Schriefdisch 6 wesseln Name[nl]=Ga naar bureaublad 6 Name[nn]=Bytt til skrivebord 6 Name[nso]=Fetogela go Desktop 6 Name[oc]=Canvia au burèu 6 Name[pa]=ਵਿਹੜੇ ੬ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 6 Name[pt]=Mudar para o Ecrã 6 Name[pt_BR]=Mudar para o Área de Trabalho 6 Name[ro]=Trece în ecranul 6 Name[ru]=Перейти на рабочий стол 6 Name[se]=Mana guđát čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 6 Name[sl]=Preklopi na namizje 6 Name[sr]=Прелаз на радну површину 6 Name[sr@Latn]=Prelaz na radnu površinu 6 Name[ss]=Tjintjela ku desktop 6 Name[sv]=Byt till skrivbord 6 Name[ta]=மேல்மேசை 6க்கு மாற்று Name[tg]=Гузариш ба мизи кории 6 Name[th]=สลับไปยังพื้นที่ทำงาน 6 Name[tr]=6. Masaüstüne Git Name[uk]=Стільниця 6 Name[uz]=Иш столи 6 га ўтиш Name[ven]=U shandukela kha desikithopo ya vhurathi Name[vi]=Đổi về Desktop 6 Name[wa]=Potchî sol shijhinme sicribanne Name[xh]=Tshintshela kwi Desktop 6 Name[xx]=xxChange to Desktop 6xx Name[zh_CN]=更改到桌面 6 Name[zh_TW]=切換到桌面六 Name[zu]=Shintshela kwi-Desktop 6 Comment=Virtual desktop six is selected Comment[az]=6. Masa üstü seçildi Comment[be]=Выбраны шосты віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 6 Comment[bn]=ষষ্ঠ ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel C'hwec'h a zo diuzet Comment[bs]=Virtualna radna površina Šest je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual sis Comment[cs]=Je vybrána virtuální plocha 6 Comment[da]=Virtuel desktop seks er valgt Comment[de]=Virtuelle Arbeitsfläche 6 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 6 Comment[eo]=Tabulo sesa estas elektita Comment[es]=Seleccionado el escritorio virtual Seis Comment[et]=Kuues virtuaalne töölaud on valitud Comment[eu]=6 mahaigain birtuala hautatua dago Comment[fi]=Virtuaalityöpöytä kuusi on valittu Comment[fr]=Le bureau virtuel 6 est sélectionné Comment[fy]=Virtueel buroblêd seis is selektearre Comment[gl]=Selecciónase o escritorio virtual número Seis Comment[he]=שולחן העבודה הווירטואלי שש נבחר Comment[hi]=आभासी डेस्कटॉप छः चुना गया है Comment[hu]=A 6. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð sex er virkt Comment[it]=Il desktop virtuale sei viene selezionato. Comment[ja]=仮想デスクトップ6が選択されました Comment[lt]=Pasirinktas šeštas menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 6. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 6 Comment[mt]=Desktop Virtwali Sitta huwa Magħżul Comment[nb]=Virtuelt skrivebord seks er valgt Comment[nds]=De virtuelle Schriefdisch Söss is utsöcht Comment[nl]=Virtueel bureaublad zes is geselecteerd Comment[nn]=Virtuelt skrivebord seks vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੬ ਚੁਣਿਆ Comment[pl]=Wybrano szósty pulpit Comment[pt]=O ecrã virtual seis é seleccionado Comment[pt_BR]=Área de trabalho virtual 6 está selecionada Comment[ro]=Ecranul virtual 6 este selectat Comment[ru]=Выбран шестой виртуальный рабочий стол Comment[se]=Guđát virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 6 Comment[sl]=Izbrano je šesto navidezno namizje Comment[sr]=Изабрана је шеста виртуелна радна површина Comment[sr@Latn]=Izabrana je šesta virtuelna radna površina Comment[sv]=Virtuellt skrivbord sex är valt Comment[ta]=மெய்நிகர் மேல்மேசை ஆறு தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü altı seçili Comment[uk]=Вибрано віртуальну стільницю Шість Comment[uz]=Олтинчи виртуал иш столи танланган Comment[wa]=Li shijhinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop six is selectedxx Comment[zh_CN]=选择了虚拟桌面 6 default_sound=KDE_Desktop_6.ogg default_presentation=0 [desktop7] Name=Change to Desktop 7 Name[af]=Verander na Werkskerm 7 Name[ar]=التغيير الى سطح المكتب 7 Name[az]=7. Masa Üstünə Get Name[bg]=Превключване на работен плот 5 Name[bn]=ডেস্কটপ ৭-এ যাও Name[br]=Gwintañ da vurev 7 Name[bs]=Premjesti se na radnu površinu 7 Name[ca]=Canvi a l'escriptori 7 Name[cs]=Přepnutí na plochu 7 Name[cy]=Newid i Penbwrdd 7 Name[da]=Skift til desktop 7 Name[de]=Wechsel zu Arbeitsfläche 7 Name[el]=Αλλαγή στην επιφάνεια εργασίας 7 Name[eo]=Al tabulo 7 Name[es]=Cambiar al escritorio 7 Name[et]=Liikumine 7. töölauale Name[eu]=7 mahaigainera aldatu Name[fa]=تغییر به میزکار ۷ Name[fi]=Vaihda työpöytään 7 Name[fr]=Aller au bureau 7 Name[fy]=Gean nei buroblêd 7 Name[ga]=Téigh go Deasc 7 Name[gl]=Cambio ó Escritorio 7 Name[he]=מעבר לשולחן עבודה 7 Name[hi]=डेस्कटॉप 7 पर जाएँ Name[hr]=Premjesti se na radnu površinu 7 Name[hu]=Váltás a 7. asztalra Name[id]=Ganti ke Desktop 7 Name[is]=Birta skjáborð 7 Name[it]=Va al desktop 7 Name[ja]=デスクトップ7に移動 Name[ko]=일곱번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີ່ທຳງານ 7 Name[lt]=Pereiti į darbastalį 7 Name[lv]=Nomainīt uz Darbvirsmu 7 Name[mk]=Кон површина 7 Name[mn]=Ажлын тавцан 7 рүү оч Name[mt]=Mur f' Desktop 7 Name[nb]=Bytt til skrivebord 7 Name[nds]=Na Schriefdisch 7 wesseln Name[nl]=Ga naar bureaublad 7 Name[nn]=Bytt til skrivebord 7 Name[nso]=Fetogela go Desktop 7 Name[oc]=Canvia au burèu 7 Name[pa]=ਵਿਹੜੇ ੭ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 7 Name[pt]=Mudar para o Ecrã 7 Name[pt_BR]=Mudar para o Área de Trabalho 7 Name[ro]=Trece în ecranul 7 Name[ru]=Перейти на рабочий стол 7 Name[se]=Mana čihččet čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 7 Name[sl]=Preklopi na namizje 7 Name[sr]=Прелаз на радну површину 7 Name[sr@Latn]=Prelaz na radnu površinu 7 Name[ss]=Tjintjela ku desktop 7 Name[sv]=Byt till skrivbord 7 Name[ta]=மேல்மேசை 7க்கு மாற்று Name[tg]=Гузариш ба мизи кории 7 Name[th]=สลับไปยังพื้นที่ทำงาน 7 Name[tr]=7. Masaüstüne Git Name[uk]=Стільниця 7 Name[uz]=Иш столи 7 га ўтиш Name[ven]=U shandukele kha desikithopo ya vhusumbe Name[vi]=Đổi về Desktop 7 Name[wa]=Potchî sol setinme sicribanne Name[xh]=Tshintshela kwi Desktop 7 Name[xx]=xxChange to Desktop 7xx Name[zh_CN]=更改到桌面 7 Name[zh_TW]=切換到桌面七 Name[zu]=Shintshela kwi-Desktop 7 Comment=Virtual desktop seven is selected Comment[az]=7. Masa üstü seçildi Comment[be]=Выбраны сёмы віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 7 Comment[bn]=সপ্তম ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Seizh a zo diuzet Comment[bs]=Virtualna radna površina Sedam je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual set Comment[cs]=Je vybrána virtuální plocha 7 Comment[da]=Virtuel desktop syv er valgt Comment[de]=Virtuelle Arbeitsfläche 7 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 7 Comment[eo]=Tabulo sepa estas elektita Comment[es]=Seleccionado el escritorio virtual Siete Comment[et]=Seitsmes virtuaalne töölaud on valitud Comment[eu]=7 mahaigain birtuala hautatua dago Comment[fi]=Virtuaalityöpöytä seitsemän on valittu Comment[fr]=Le bureau virtuel 7 est sélectionné Comment[fy]=Virtueel buroblêd sân is selektearre Comment[gl]=Selecciónase o escritorio virtual número Sete Comment[he]=שולחן העבודה הווירטואלי שבע נבחר Comment[hi]=आभासी डेस्कटॉप सात चुना गया है Comment[hu]=A 7. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð sjö er virkt Comment[it]=Il desktop virtuale sette viene selezionato. Comment[ja]=仮想デスクトップ7が選択されました Comment[lt]=Pasirinktas septintas menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 7. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 7 Comment[mt]=Desktop Virtwali Sebgħa huwa Magħżul Comment[nb]=Virtuelt skrivebord syv er valgt Comment[nds]=De virtuelle Schriefdisch Söben is utsöcht Comment[nl]=Virtueel bureaublad zeven is geselecteerd Comment[nn]=Virtuelt skrivebord sju vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੭ ਚੁਣਿਆ Comment[pl]=Wybrano siódmy pulpit Comment[pt]=O ecrã virtual sete é seleccionado Comment[pt_BR]=Área de trabalho virtual 7 está selecionada Comment[ro]=Ecranul virtual 7 este selectat Comment[ru]=Выбран седьмой виртуальный рабочий стол Comment[se]=Čihččet virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 7 Comment[sl]=Izbrano je sedmo navidezno namizje Comment[sr]=Изабрана је седма виртуелна радна површина Comment[sr@Latn]=Izabrana je sedma virtuelna radna površina Comment[sv]=Virtuellt skrivbord sju är valt Comment[ta]=மெய்நிகர் மேல்மேசை ஏழு தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü yedi seçili Comment[uk]=Вибрано віртуальну стільницю Сім Comment[uz]=Еттинчи виртуал иш столи танланган Comment[wa]=Li setinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop seven is selectedxx Comment[zh_CN]=选择了虚拟桌面 7 default_sound=KDE_Desktop_7.ogg default_presentation=0 [desktop8] Name=Change to Desktop 8 Name[af]=Verander na Werkskerm 8 Name[ar]=التغيير الى سطح المكتب 8 Name[az]=8. Masa Üstünə Get Name[bg]=Превключване на работен плот 7 Name[bn]=ডেস্কটপ ৮-এ যাও Name[br]=Gwintañ da vurev 8 Name[bs]=Premjesti se na radnu površinu 8 Name[ca]=Canvi a l'escriptori 8 Name[cs]=Přepnutí na plochu 8 Name[cy]=Newid i Penbwrdd 8 Name[da]=Skift til desktop 8 Name[de]=Wechsel zu Arbeitsfläche 8 Name[el]=Αλλαγή στην επιφάνεια εργασίας 8 Name[eo]=Al tabulo 8 Name[es]=Cambiar al escritorio 8 Name[et]=Liikumine 8. töölauale Name[eu]=8 mahaigainera aldatu Name[fa]=تغییر به میزکار ۸ Name[fi]=Vaihda työpöytään 8 Name[fr]=Aller au bureau 8 Name[fy]=Gean nei buroblêd 8 Name[ga]=Téigh go Deasc 8 Name[gl]=Cambio ó Escritorio 8 Name[he]=מעבר לשולחן עבודה 8 Name[hi]=डेस्कटॉप 8 पर जाएँ Name[hr]=Premjesti se na radnu površinu 8 Name[hu]=Váltás a 8. asztalra Name[id]=Ganti ke Desktop 8 Name[is]=Birta skjáborð 8 Name[it]=Va al desktop 8 Name[ja]=デスクトップ8に移動 Name[ko]=여덟번째 일터로 옮김 Name[lo]=ສະລັບໄປຍັງພື້ນທີ່ທຳງານ 8 Name[lt]=Pereiti į darbastalį 8 Name[lv]=Nomainīt uz Darbvirsmu 8 Name[mk]=Кон површина 8 Name[mn]=Ажлын тавцан 8 рүү оч Name[mt]=Mur f' Desktop 8 Name[nb]=Bytt til skrivebord 8 Name[nds]=Na Schriefdisch 8 wesseln Name[nl]=Ga naar bureaublad 8 Name[nn]=Bytt til skrivebord 8 Name[nso]=Fetogela go Desktop 8 Name[oc]=Canvia au burèu 8 Name[pa]=ਵਿਹੜੇ ੮ ਲਈ ਤਬਦੀਲ Name[pl]=Zmień na pulpit 8 Name[pt]=Mudar para o Ecrã 8 Name[pt_BR]=Mudar para o Área de Trabalho 8 Name[ro]=Trece în ecranul 8 Name[ru]=Перейти на рабочий стол 8 Name[se]=Mana gávccát čállinbeavdái Name[sk]=Zmeniť na pracovnú plochu 8 Name[sl]=Preklopi na namizje 8 Name[sr]=Прелаз на радну површину 8 Name[sr@Latn]=Prelaz na radnu površinu 8 Name[ss]=Tjintjela ku desktop 8 Name[sv]=Byt till skrivbord 8 Name[ta]=மேல்மேசை 8க்கு மாற்று Name[tg]=Гузариш ба мизи кории 8 Name[th]=สลับไปยังพื้นที่ทำงาน 8 Name[tr]=8. Masaüstüne Git Name[uk]=Стільниця 8 Name[uz]=Иш столи 8 га ўтиш Name[ven]=U shandukela kha desikithopo ya vhumalo Name[vi]=Đổi về Desktop 8 Name[wa]=Potchî sol ûtinme sicribanne Name[xh]=Tshintshela kwi Desktop 8 Name[xx]=xxChange to Desktop 8xx Name[zh_CN]=更改到桌面 8 Name[zh_TW]=切換到桌面八 Name[zu]=Shintshela kwi-Desktop 8 Comment=Virtual desktop eight is selected Comment[az]=8. Masa üstü seçildi Comment[be]=Выбраны восьмы віртуальны працоўны cтол Comment[bg]=Превключване на работен плот 8 Comment[bn]=অষ্টম ভার্চুয়াল ডেস্কটপ নির্বাচিত হয়েছে Comment[br]=Burev galloudel Eizh a zo diuzet Comment[bs]=Virtualna radna površina Osam je izabrana Comment[ca]=S'ha seleccionat l'escriptori virtual vuit Comment[cs]=Je vybrána virtuální plocha 8 Comment[da]=Virtuel desktop otte er valgt Comment[de]=Virtuelle Arbeitsfläche 8 ausgewählt Comment[el]=Έχει επιλεγεί η εικονική επιφάνεια εργασίας 8 Comment[eo]=Tabulo oka estas elektita Comment[es]=Seleccionado el escritorio virtual Ocho Comment[et]=Kaheksas virtuaalne töölaud on valitud Comment[eu]=8 mahaigain birtuala hautatua dago Comment[fi]=Virtuaalityöpöytä kahdeksan on valittu Comment[fr]=Le bureau virtuel 8 est sélectionné Comment[fy]=Virtueel buroblêd acht is selektearre Comment[gl]=Selecciónase o escritorio virtual número Oito Comment[he]=שולחן העבודה הווירטואלי שמונה נבחר Comment[hi]=आभासी डेस्कटॉप आठ चुना गया है Comment[hu]=A 8. virtuális asztal kiválasztva Comment[is]=Sýndarskjáborð átta er virkt Comment[it]=Il desktop virtuale otto viene selezionato. Comment[ja]=仮想デスクトップ8が選択されました Comment[lt]=Pasirinktas aštuntas menamas darbastalis Comment[lv]=Virtuālā Darbvirsma nr. 8. ir izvēlēta Comment[mk]=Избрана е виртуелната површина бр. 8 Comment[mt]=Desktop Virtwali Tmienja huwa Magħżul Comment[nb]=Virtuelt skrivebord åtte er valgt Comment[nds]=De virtuelle Schriefdisch Acht is utsöcht Comment[nl]=Virtueel bureaublad acht is geselecteerd Comment[nn]=Virtuelt skrivebord åtte vert valt Comment[pa]=ਫ਼ਰਜ਼ੀ ਵਿਹੜਾ ੮ ਚੁਣਿਆ Comment[pl]=Wybrano ósmy pulpit Comment[pt]=O ecrã virtual oito é seleccionado Comment[pt_BR]=Área de trabalho virtual 8 está selecionada Comment[ro]=Ecranul virtual 8 este selectat Comment[ru]=Выбран восьмой виртуальный рабочий стол Comment[se]=Gávccát virtuella čállinbeavdi lea válljejuvvon Comment[sk]=Je zvolená virtuálna plocha 8 Comment[sl]=Izbrano je osmo navidezno namizje Comment[sr]=Изабрана је осма виртуелна радна површина Comment[sr@Latn]=Izabrana je osma virtuelna radna površina Comment[sv]=Virtuellt skrivbord åtta är valt Comment[ta]=மெய்நிகர் மேல்மேசை எட்டு தேர்ந்தெடுக்கப்பட்டது Comment[tr]=Sanal masaüstü sekiz seçili Comment[uk]=Вибрано віртуальну стільницю Вісім Comment[uz]=Саккизинчи виртуал иш столи танланган Comment[wa]=Li ûtinme forveyou scribanne a stî tchoezi Comment[xx]=xxVirtual desktop eight is selectedxx Comment[zh_CN]=选择了虚拟桌面 8 default_sound=KDE_Desktop_8.ogg default_presentation=0 [desktop9] Name=Change to Desktop 9 Name[bg]=Превключване на работен плот 9 Name[da]=Skift til desktop 9 Name[ga]=Téigh go Deasc 9 Name[pt_BR]=Mudar para a Área de Trabalho 9 Name[sv]=Byt till skrivbord 9 Name[ta]=மேல்மேசை 9க்கு மாற்று Name[tr]=9. Masaüstüne Git Comment=Virtual desktop nine is selected Comment[bg]=Превключване на работен плот 9 Comment[da]=Virtuel desktop ni er valgt Comment[pt_BR]=Área de trabalho virtual 9 está selecionada Comment[sv]=Virtuellt skrivbord nio är valt default_presentation=0 [desktop10] Name=Change to Desktop 10 Name[bg]=Превключване на работен плот 10 Name[da]=Skift til desktop 10 Name[ga]=Téigh go Deasc 10 Name[pt_BR]=Mudar para a Área de Trabalho 10 Name[sv]=Byt till skrivbord 10 Name[ta]=மேல்மேசை 10க்கு மாற்று Name[tr]=10. Masaüstüne Git Comment=Virtual desktop ten is selected Comment[bg]=Превключване на работен плот 10 Comment[da]=Virtuel desktop ti er valgt Comment[pt_BR]=Área de trabalho virtual 10 está selecionada Comment[sv]=Virtuellt skrivbord tio är valt Comment[ta]=மெய்நிகர் மேல்மேசை பத்து தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop11] Name=Change to Desktop 11 Name[bg]=Превключване на работен плот 11 Name[da]=Skift til desktop 11 Name[ga]=Téigh go Deasc 11 Name[pt_BR]=Mudar para a Área de Trabalho 11 Name[sv]=Byt till skrivbord 11 Name[ta]=மேல்மேசை 11க்கு மாற்று Name[tr]=11. Masaüstüne Git Comment=Virtual desktop eleven is selected Comment[bg]=Превключване на работен плот 11 Comment[da]=Virtuel desktop elleve er valgt Comment[pt_BR]=Área de trabalho virtual 11 está selecionada Comment[sv]=Virtuellt skrivbord elva är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதினொன்று தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop12] Name=Change to Desktop 12 Name[bg]=Превключване на работен плот 12 Name[da]=Skift til desktop 12 Name[ga]=Téigh go Deasc 12 Name[pt_BR]=Mudar para a Área de Trabalho 12 Name[sv]=Byt till skrivbord 12 Name[ta]=மேல்மேசை 12க்கு மாற்று Name[tr]=12. Masaüstüne Git Comment=Virtual desktop twelve is selected Comment[bg]=Превключване на работен плот 12 Comment[da]=Virtuel desktop tolv er valgt Comment[pt_BR]=Área de trabalho virtual 12 está selecionada Comment[sv]=Virtuellt skrivbord tolv är valt Comment[ta]=மெய்நிகர் மேல்மேசை பன்னிரெண்டு தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop13] Name=Change to Desktop 13 Name[bg]=Превключване на работен плот 13 Name[da]=Skift til desktop 13 Name[ga]=Téigh go Deasc 13 Name[pt_BR]=Mudar para o Área de Trabalho 13 Name[sv]=Byt till skrivbord 13 Name[ta]=மேல்மேசை 13க்கு மாற்று Name[tr]=13. Masaüstüne Git Comment=Virtual desktop thirteen is selected Comment[bg]=Превключване на работен плот 13 Comment[da]=Virtuel desktop tretten er valgt Comment[pt_BR]=Área de trabalho virtual 13 está selecionada Comment[sv]=Virtuellt skrivbord tretton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதின்மூன்று தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop14] Name=Change to Desktop 14 Name[bg]=Превключване на работен плот 14 Name[da]=Skift til desktop 14 Name[ga]=Téigh go Deasc 14 Name[pt_BR]=Mudar para o Área de Trabalho 14 Name[sv]=Byt till skrivbord 14 Name[ta]=மேல்மேசை 14க்கு மாற்று Name[tr]=14. Masaüstüne Git Comment=Virtual desktop fourteen is selected Comment[bg]=Превключване на работен плот 14 Comment[da]=Virtuel desktop fjorten er valgt Comment[pt_BR]=Área de trabalho virtual 14 está selecionada Comment[sv]=Virtuellt skrivbord fjorton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதினான்கு தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop15] Name=Change to Desktop 15 Name[bg]=Превключване на работен плот 15 Name[da]=Skift til desktop 15 Name[ga]=Téigh go Deasc 15 Name[pt_BR]=Mudar para o Área de Trabalho 15 Name[sv]=Byt till skrivbord 15 Name[ta]=மேல்மேசை 15க்கு மாற்று Name[tr]=15. Masaüstüne Git Comment=Virtual desktop fifteen is selected Comment[bg]=Превключване на работен плот 15 Comment[da]=Virtuel desktop femten er valgt Comment[pt_BR]=Área de trabalho virtual 15 está selecionada Comment[sv]=Virtuellt skrivbord femton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதினைந்து தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop16] Name=Change to Desktop 16 Name[bg]=Превключване на работен плот 16 Name[da]=Skift til desktop 16 Name[ga]=Téigh go Deasc 16 Name[pt_BR]=Mudar para o Área de Trabalho 16 Name[sv]=Byt till skrivbord 16 Name[ta]=மேல்மேசை 116க்கு மாற்று Name[tr]=16. Masaüstüne Git Comment=Virtual desktop sixteen is selected Comment[bg]=Превключване на работен плот 16 Comment[da]=Virtuel desktop seksten er valgt Comment[pt_BR]=Área de trabalho virtual 16 está selecionada Comment[sv]=Virtuellt skrivbord sexton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதினாறு தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop17] Name=Change to Desktop 17 Name[bg]=Превключване на работен плот 17 Name[da]=Skift til desktop 17 Name[ga]=Téigh go Deasc 17 Name[pt_BR]=Mudar para o Área de Trabalho 17 Name[sv]=Byt till skrivbord 17 Name[ta]=மேல்மேசை 17க்கு மாற்று Name[tr]=17. Masaüstüne Git Comment=Virtual desktop seventeen is selected Comment[bg]=Превключване на работен плот 17 Comment[da]=Virtuel desktop sytten er valgt Comment[pt_BR]=Área de trabalho virtual 17 está selecionada Comment[sv]=Virtuellt skrivbord sjutton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதினேழு தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop18] Name=Change to Desktop 18 Name[bg]=Превключване на работен плот 18 Name[da]=Skift til desktop 18 Name[ga]=Téigh go Deasc 18 Name[pt_BR]=Mudar para o Área de Trabalho 18 Name[sv]=Byt till skrivbord 18 Name[ta]=மேல்மேசை 18க்கு மாற்று Name[tr]=18. Masaüstüne Git Comment=Virtual desktop eighteen is selected Comment[bg]=Превключване на работен плот 18 Comment[da]=Virtuel desktop atten er valgt Comment[pt_BR]=Área de trabalho virtual 18 está selecionada Comment[sv]=Virtuellt skrivbord arton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பதினெட்டு தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop19] Name=Change to Desktop 19 Name[bg]=Превключване на работен плот 19 Name[da]=Skift til desktop 19 Name[ga]=Téigh go Deasc 19 Name[pt_BR]=Mudar para a Área de Trabalho 19 Name[sv]=Byt till skrivbord 19 Name[ta]=மேல்மேசை 19க்கு மாற்று Name[tr]=19. Masaüstüne Git Comment=Virtual desktop nineteen is selected Comment[bg]=Превключване на работен плот 19 Comment[da]=Virtuel desktop nitten er valgt Comment[pt_BR]=Área de trabalho virtual 19 está selecionada Comment[sv]=Virtuellt skrivbord nitton är valt Comment[ta]=மெய்நிகர் மேல்மேசை பத்தொன்பது தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [desktop20] Name=Change to Desktop 20 Name[bg]=Превключване на работен плот 20 Name[da]=Skift til desktop 20 Name[ga]=Téigh go Deasc 20 Name[pt_BR]=Mudar para a Área de Trabalho 20 Name[sv]=Byt till skrivbord 20 Name[ta]=மேல்மேசை 20க்கு மாற்று Name[tr]=20. Masaüstüne Git Comment=Virtual desktop twenty is selected Comment[bg]=Превключване на работен плот 20 Comment[da]=Virtuel desktop tyve er valgt Comment[pt_BR]=Área de trabalho virtual 20 está selecionada Comment[sv]=Virtuellt skrivbord tjugo är valt Comment[ta]=மெய்நிகர் மேல்மேசை இருபது தேர்ந்தெடுக்கப்பட்டது default_presentation=0 [activate] Name=Activate Window Name[af]=Aktiveer Venster Name[ar]=تنشيط النافذة Name[az]=Pəncərəni Fəallaşdır Name[be]=Актывізацыя акна Name[bg]=Активиране на прозорец Name[bn]=উইণ্ডো সক্রিয় করো Name[br]=Dihuniñ ar prenestr Name[bs]=Aktiviraj prozor Name[ca]=Activa finestra Name[cs]=Aktivace okna Name[cy]=Gweithredu Ffenestr Name[da]=Aktivér vindue Name[de]=Fenster aktivieren Name[el]=Ενεργοποίηση παραθύρου Name[eo]=Aktiviĝo de fenestro Name[es]=Activar ventana Name[et]=Akna aktiveerimine Name[eu]=Leihoa aktibatu Name[fa]=فعال نمودن پنجره Name[fi]=Aktivoi ikkuna Name[fr]=Activer une fenêtre Name[fy]=Finster aktivearje Name[ga]=Gníomhachtaigh Fuinneog Name[gl]=Actívase unha Fiestra Name[he]=הפעלת חלון Name[hi]= विंडो सक्रिय करें Name[hr]=Aktiviraj prozor Name[hu]=Ablak aktiválása Name[id]=Mengaktifkan Jendela Name[is]=Virkja glugga Name[it]=Attiva finestra Name[ja]=ウィンドウを活性化 Name[ko]=활성화된 창 Name[lo]=ຮງກຫນ້າຕ່າງທຳງານ Name[lt]=Suaktyvinti langą Name[lv]=Aktivizēt Logu Name[mk]=Активирај прозорец Name[mn]=Цонх идэвхижүүлэх Name[mt]=Attiva Window Name[nb]=Aktiver vindu Name[nds]=Finster aktiv setten Name[nl]=Venster activeren Name[nn]=Aktiver vindauge Name[nso]=Berekisa Window Name[oc]=Activa finestra Name[pa]=ਝਰੋਖਾ ਸਰਗਰਮ Name[pl]=Aktywacja okna Name[pt]=Activar Janela Name[pt_BR]=Ativar Janela Name[ro]=Activează fereastra Name[ru]=Сделать окно активным Name[se]=Aktivere láse Name[sk]=Aktívne okno Name[sl]=Aktiviraj okno Name[sr]=Прозор се активира Name[sr@Latn]=Prozor se aktivira Name[ss]=Vuselela liwindi Name[sv]=Aktivera fönster Name[ta]=சாளரத்தை செயற்படுத்து Name[tg]=Фаъол намудани тиреза Name[th]=เรียกหน้าต่างทำงาน Name[tr]=Pencereyi Etkinleştir Name[uk]=Активізувати вікно Name[uz]=Ойнани активлаштириш Name[ven]=Lugisani dzi windo Name[vi]=Cửa sổ hoạt động (activate) Name[wa]=Dispierter li purnea Name[xh]=Yenza i window isebenze Name[xx]=xxActivate Windowxx Name[zh_CN]=激活窗口 Name[zh_TW]=作用中視窗 Name[zu]=Nyakazisa I-window Comment=Another window is activated Comment[az]=Başqa pəncərə fəallaşdırdı Comment[be]=Актывізаванае іншае акно Comment[bg]=Активиран е друг прозорец Comment[bn]=অন্য একটি উইণ্ডো সক্রিয় করা হয়েছে Comment[bs]=Drugi prozor je aktiviran Comment[ca]=S'ha activat una altra finestra Comment[cs]=Je aktivováno jiné okno Comment[da]=Et andet vindue er aktiveret Comment[de]=Ein anderes Fenster ist aktiv. Comment[el]=Ενεργοποιήθηκε ένα άλλο παράθυρο Comment[eo]=Alia fenestro aktiviĝis Comment[es]=Otra ventana está activada Comment[et]=Teine aken on aktiveeritud Comment[eu]=Beste leiho bat aktibatua dago Comment[fi]=Toinen ikkuna aktivoitu Comment[fr]=Une autre fenêtre est activée Comment[fy]=In oar finster is aktivearre Comment[gl]=Outra fiestra está activa Comment[he]=חלון אחר מופעל Comment[hi]=अन्य विंडो सक्रिय है Comment[hu]=Egy másik ablak lett aktiválva Comment[is]=Annar gluggi verður virkur Comment[it]=Attivazione di un'altra finestra Comment[ja]=他のウィンドウが活性化されました Comment[lt]=Suaktyvintas kitas langas Comment[lv]=Cits Logs jau ir aktivizēts Comment[mk]=Активиран е друг прозорец Comment[mt]=Window Oħra Ġiet Attivata Comment[nb]=Et annet vindu er aktivert Comment[nds]=En anner Finster warrt aktiv maakt Comment[nl]=Een ander venster is geactiveerd Comment[nn]=Eit anna vindauge vert aktivert Comment[pa]=ਹੋਰ ਝਰੋਖਾ ਸਰਗਰਮ ਹੈ Comment[pl]=Uaktywnienie innego okna Comment[pt]=Outra janela é activada Comment[pt_BR]=Outra janela está ativa Comment[ro]=A fost activată altă fereastră Comment[ru]=Активировано другое окно Comment[se]=Eará láse aktiverejuvvo Comment[sk]=Iné okno je už aktívne Comment[sl]=Aktivno je drugo okno Comment[sr]=Активиран је други прозор Comment[sr@Latn]=Aktiviran je drugi prozor Comment[sv]=Ett annat fönster är aktiverat Comment[ta]=மற்றொரு சாளரம் செயலாக்கப்படது Comment[tr]=Başka bir pencere etkinleştirildi Comment[uk]=Активоване інше вікно Comment[uz]=Бошқа ойна актив бўлди Comment[xx]=xxAnother window is activatedxx Comment[zh_CN]=激活了另外一个窗口 default_presentation=0 [new] Name=New Window Name[af]=Nuwe Venster Name[ar]=نافذة جديدة Name[az]=Yeni Pəncərə Name[be]=Новае акно Name[bg]=Нов прозорец Name[bn]=নতুন উইণ্ডো Name[br]=Prenestr nevez Name[bs]=Novi prozor Name[ca]=Nova finestra Name[cs]=Nové okno Name[cy]=Ffenestr Newydd Name[da]=Nyt vindue Name[de]=Neues Fenster Name[el]=Νέο παράθυρο Name[eo]=Nova fenestro Name[es]=Nueva ventana Name[et]=Uus aken Name[eu]=Leiho berria Name[fa]=پنجره‌ی جدید Name[fi]=Uusi ikkuna Name[fr]=Nouvelle fenêtre Name[fy]=Nij finster Name[ga]=Fuinneog Nua Name[gl]=Nova Fiestra Name[he]=חלון חדש Name[hi]=नया विंडो Name[hr]=Novi prozor Name[hu]=Új ablak Name[id]=Jendela Baru Name[is]=Opna nýjan glugga Name[it]=Nuova finestra Name[ja]=新規ウィンドウ Name[ko]=새 창 Name[lo]=ສ້າງຫນ້າຕ່າງໃຫມ່ Name[lt]=Naujas langas Name[lv]=Jauns Logs Name[mk]=Нов прозорец Name[mn]=Шинэ цонх Name[mt]=Window Ġdida Name[nb]=Nytt vindu Name[nds]=Nieg Finster Name[nl]=Nieuw venster Name[nn]=Nytt vindauge Name[nso]=Window ye Ntshwa Name[oc]=Navera finestra Name[pa]=ਨਵਾਂ ਝਰੋਖਾ Name[pl]=Nowe okno Name[pt]=Nova Janela Name[pt_BR]=Nova Janela Name[ro]=Fereastră nouă Name[ru]=Новое окно Name[se]=Ođđa láse Name[sk]=Nové okno Name[sl]=Novo okno Name[sr]=Нови прозор Name[sr@Latn]=Novi prozor Name[ss]=Liwindi lelisha Name[sv]=Nytt fönster Name[ta]=புதிய சாளரம் Name[tg]=Тирезаи Нав Name[th]=สร้างหน้าต่างใหม่ Name[tr]=Yeni Pencere Name[uk]=Нове вікно Name[uz]=Янги ойна Name[ven]=Windo ntswa Name[vi]=Cửa sổ mới Name[wa]=Novea purnea Name[xh]=Window Entsha Name[xx]=xxNew Windowxx Name[zh_CN]=新建窗口 Name[zh_TW]=新視窗 Name[zu]=I-window Entsha Comment=New window Comment[az]=Yeni pəncərə Comment[be]=Новае акно Comment[bg]=Нов прозорец Comment[bn]=নতুন উইণ্ডো Comment[br]=Prenestr nevez Comment[bs]=Novi prozor Comment[ca]=Finestra nova Comment[cs]=Nové okno Comment[da]=Nyt vindue Comment[de]=Neues Fenster Comment[el]=Νέο παράθυρο Comment[eo]=Nova fenestro Comment[es]=Nueva ventana Comment[et]=Uus aken Comment[eu]=Leiho berria Comment[fi]=Uusi ikkuna Comment[fr]=Nouvelle fenêtre Comment[fy]=Nij finster Comment[ga]=Fuinneog nua Comment[gl]=Nova Fiestra Comment[he]=חלון חדש Comment[hi]=नया विंडो Comment[hu]=Új ablak Comment[is]=Nýr gluggi Comment[it]=Nuova finestra Comment[ja]=新規ウィンドウ Comment[lt]=Naujas langas Comment[lv]=Jauns Logs Comment[mk]=Нов прозорец Comment[mt]=Window Ġdida Comment[nb]=Nytt vindu Comment[nds]=Nieg Finster Comment[nl]=Nieuw venster Comment[nn]=Nytt vindauge Comment[pa]=ਨਵਾਂ ਝਰੋਖਾ Comment[pl]=Nowe okno Comment[pt]=Nova janela Comment[pt_BR]=Nova janela Comment[ro]=Fereastră nouă Comment[ru]=Новое окно Comment[se]=Ođđa láse Comment[sk]=Nové okno Comment[sl]=Novo okno Comment[sr]=Нови прозор Comment[sr@Latn]=Novi prozor Comment[sv]=Nytt fönster Comment[ta]=புது சாளரம் Comment[tr]=Yeni pencere Comment[uk]=Відкрите нове вікно Comment[uz]=Янги ойна Comment[wa]=Novea purnea Comment[xx]=xxNew windowxx Comment[zh_CN]=新建窗口 default_sound=KDE_Window_Open.ogg default_presentation=0 [delete] Name=Delete Window Name[af]=Uitvee Venster Name[ar]=الغاء النافذة Name[az]=Pəncərəni Sil Name[be]=Выдаленьне акна Name[bg]=Изтриване на прозорец Name[bn]=উইণ্ডো মুছে ফেলো Name[br]=Lemel ur Prenestr Name[bs]=Brisanje prozora Name[ca]=Elimina finestra Name[cs]=Zrušit okno Name[cy]=Dileu Ffenestr Name[da]=Slet vindue Name[de]=Fenster löschen Name[el]=Διαγραφή παραθύρου Name[eo]=Forigu fenestron Name[es]=Eliminar ventana Name[et]=Akna kustutamine Name[eu]=Ezabatu leihoa Name[fa]=حذف پنجره Name[fi]=Tuhoa ikkuna Name[fr]=Supprimer la fenêtre Name[fy]=Finster wisse Name[ga]=Scrios Fuinneog Name[gl]=Borrar Fiestra Name[he]=מחיקת חלון Name[hi]=विंडो मिटाएँ Name[hr]=Brisanje prozora Name[hu]=Ablak törlése Name[id]=Hapus Jendela Name[is]=Eyða glugga Name[it]=Elimina finestra Name[ja]=ウィンドウを削除 Name[ko]=창 없애기 Name[lo]=ລົບຫນ້າຕ່າງ Name[lt]=Pašalinti langą Name[lv]=Dzēst Logu Name[mk]=Избриши прозорец Name[mn]=Цонх устгах Name[mt]=Neħħi Window Name[nb]=Slett vindu Name[nds]=Finster löschen Name[nl]=Venster verwijderen Name[nn]=Fjern vindauge Name[nso]=Tlosa Window Name[oc]=Suprima finestra Name[pa]=ਝਰੋਖਾ ਹਟਾਓ Name[pl]=Usunięcie okna Name[pt]=Apagar Janela Name[pt_BR]=Remover Janela Name[ro]=Distruge fereastra Name[ru]=Удалить окно Name[se]=Sihko láse Name[sk]=Zmazať okno Name[sl]=Zbriši okno Name[sr]=Прозор се брише Name[sr@Latn]=Prozor se briše Name[ss]=Bulala liwindi Name[sv]=Ta bort fönster Name[ta]=சாளரத்தை நீக்கு Name[tg]=Нобуд сохтани тиреза Name[th]=ลบหน้าต่าง Name[tr]=Pencereyi Sil Name[uk]=Видалити вікно Name[uz]=Ойнани ўчириш Name[ven]=Thuthani Windo Name[vi]=Xoá cửa sổ Name[wa]=Disfacer purnea Name[xh]=Cima i Window Name[xx]=xxDelete Windowxx Name[zh_CN]=删除窗口 Name[zh_TW]=刪除視窗 Name[zu]=Cisha I-window Comment=Delete window Comment[az]=Pəncərəni sil Comment[be]=Акно выдаляецца Comment[bg]=Изтриване на прозорец Comment[bn]=উইণ্ডো বন্ধ করো Comment[br]=Lemel ur prenestr Comment[bs]=Brisanje prozora Comment[ca]=Esborra finestra Comment[cs]=Okna bylo odstraněno Comment[da]=Slet vindue Comment[de]=Fenster entfernen Comment[el]=Διαγραφή παραθύρου Comment[eo]=Forigu fenestron Comment[es]=Eliminar ventana Comment[et]=Akna kustutamine Comment[eu]=Ezabatu leihoa Comment[fi]=Tuhoa ikkuna Comment[fr]=Supprimer une fenêtre Comment[fy]=Finster wisse Comment[ga]=Scrios Fuinneog Comment[gl]=Borrar fiestra Comment[he]=חלון נמחק Comment[hi]=विंडो मिटाएँ Comment[hu]=Ablak törlése Comment[is]=Eyða glugga Comment[it]=Eliminazione finestra Comment[ja]=ウィンドウを削除 Comment[lt]=Pašalinti langą Comment[lv]=Dzēst Logu Comment[mk]=Избриши прозорец Comment[mt]=Ħassar Window Comment[nb]=Slett vindu Comment[nds]=Finster löschen Comment[nl]=Venster verwijderen Comment[nn]=Lukk vindauge Comment[pa]=ਝਰੋਖਾ ਹਟਾਓ Comment[pl]=Usuń okno Comment[pt]=Apagar a janela Comment[pt_BR]=Remover Janela Comment[ro]=Închide fereastra Comment[ru]=Удалить окно Comment[se]=Sihko láse Comment[sk]=Odstrániť okno Comment[sl]=Zbriši okno Comment[sr]=Прозор се брише Comment[sr@Latn]=Prozor se briše Comment[sv]=Ta bort fönster Comment[ta]=சாளரத்தை நீக்கு Comment[tr]=Pencereyi sil Comment[uk]=Вікно вилучено Comment[uz]=Ойнани ўчириш Comment[wa]=Disfacer purnea Comment[xx]=xxDelete windowxx Comment[zh_CN]=删除窗口 default_presentation=0 [close] Name=Window Close Name[af]=Venster Maak toe Name[ar]=اغلاق نافذة Name[az]=Pəncərəni Bağla Name[be]=Зачыненьне акна Name[bg]=Затваряне на прозорец Name[bn]=উইণ্ডো বন্ধ Name[br]=Serriñ ar Prenestr Name[bs]=Zatvaranje prozora Name[ca]=Tanca finestra Name[cs]=Zavření okna Name[cy]=Cau Ffenestr Name[da]=Luk vindue Name[de]=Fenster schließen Name[el]=Κλείσιμο παραθύρου Name[eo]=Fenestro fermiĝĉs Name[es]=Cerrar ventana Name[et]=Akna sulgemine Name[eu]=Itxi leihoa Name[fa]=بستن پنجره Name[fi]=Sulje ikkuna Name[fr]=Fermer une fenêtre Name[fy]=Finster slute Name[ga]=Dún Fuinneog Name[gl]=Péchase unha Fiestra Name[he]=סגירת חלון Name[hi]=विंडो बन्द करें Name[hr]=Zatvaranje prozora Name[hu]=Ablak bezárása Name[id]=Tutup Jendela Name[is]=Glugga lokað Name[it]=Chiudi finestra Name[ja]=ウィンドウを閉じる Name[ko]=창 닫기 Name[lo]=ປິດຫນ້າຕ່າງ Name[lt]=Uždaryti langą Name[lv]=Aizvērt logu Name[mk]=Затвори прозорец Name[mn]=Цонх хаах Name[mt]=Agħlaq Window Name[nb]=Lukk vindu Name[nds]=Finster tomaken Name[nl]=Venster sluiten Name[nn]=Lukk vindauge Name[nso]=Tswalelo ya Window Name[oc]=Tanca finestra Name[pa]=ਝਰੋਖਾ ਬੰਦ Name[pl]=Zamknięcie okna Name[pt]=Fechar Janela Name[pt_BR]=Fechar Janela Name[ro]=Închide fereastra Name[ru]=Закрыть окно Name[se]=Láse giddana Name[sk]=Zatvoriť okno Name[sl]=Zapri okno Name[sr]=Прозор се затвара Name[sr@Latn]=Prozor se zatvara Name[ss]=Vala liwindi Name[sv]=Fönster stängs Name[ta]=சாளரத்தை மூடு Name[tg]=Пӯшидани тиреза Name[th]=ปิดหน้าต่าง Name[tr]=Pencereyi Kapat Name[uk]=Закрити вікно Name[uz]=Ойнани ёпиш Name[ven]=Valani Windo Name[vi]=Đóng cửa sổ Name[wa]=Cloyaedje di purnea Name[xh]=Window Iyavala Name[xx]=xxWindow Closexx Name[zh_CN]=窗口关闭 Name[zh_TW]=關閉視窗 Name[zu]=Ukuvaleka Kwe-window Comment=A window closes Comment[az]=Pəncərə bağlanır Comment[be]=Акно зачыняецца Comment[bg]=Затваряне на прозорец Comment[bn]=একটি উইণ্ডো বন্ধ করা হয়েছে Comment[br]=Sarret eo ur prenestr Comment[bs]=Prozor se zatvara Comment[ca]=Es tanca una finestra Comment[cs]=Okno bylo zavřeno Comment[da]=Et vindue lukker Comment[de]=Fenster wird geschlossen Comment[el]=Ένα παράθυρο κλείνει Comment[eo]=Fenestro fermiĝas Comment[es]=Se cierra una ventana Comment[et]=Aken sulgub Comment[eu]=Leihoa itxi egiten da Comment[fi]=Ikkuna sulkeutuu Comment[fr]=Une fenêtre se ferme Comment[fy]=In finster slút Comment[ga]=Dúntar fuinneog Comment[gl]=Pechouse unha fiestra Comment[he]=חלון נסגר Comment[hi]=एक विंडो बन्द हुआ Comment[hu]=Ablak bezáródása Comment[is]=Gluggi lokast Comment[it]=Una finestra si chiude Comment[ja]=ウィンドウが閉じます Comment[lt]=Langas uždaromas Comment[lv]=Logs Aizveras Comment[mk]=Прозорецот се затвора Comment[mt]=Window Tingħalaq Comment[nb]=Et vindu lukkes Comment[nds]=En Finster warrt tomaakt Comment[nl]=Een venster sluit Comment[nn]=Eit vindauge vert lukka Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਬੰਦ Comment[pl]=Okno się zamyka Comment[pt]=Uma janela é fechada Comment[pt_BR]=Uma janela fecha Comment[ro]=A fost închisă o fereastră Comment[ru]=Окно закрывается Comment[se]=Láse giddejuvvo Comment[sk]=Okno sa uzavrie Comment[sl]=Zapre se okno Comment[sr]=Прозор се затвара Comment[sr@Latn]=Prozor se zatvara Comment[sv]=Ett fönster stängs Comment[ta]=சாளரம் மூடுகிறது Comment[tr]=Bir pencere kapatıldı Comment[uk]=Вікно закривається Comment[uz]=Ойна ёпилмоқда Comment[wa]=On purnea est cloyou Comment[xx]=xxA window closesxx Comment[zh_CN]=窗口关闭 default_sound=KDE_Window_Close.ogg default_presentation=0 [shadeup] Name=Window Shade Up Name[af]=Venster Skadu Begin Name[ar]=تظليل نافذة الى أعلى Name[az]=Pəncərənin Yuxarı Burulması Name[bg]=Свиване на прозорец нагоре Name[bn]=উইণ্ডো উপরে গুটিয়ে নাও Name[br]=Rollañ ar prenestr Name[bs]=Podizanje prozora Name[ca]=Plega la finestra Name[cs]=Zarolování okna Name[cy]=Rholio'r Ffenestr i Fyny Name[da]=Skyg vindue op Name[de]=Fensterheber nach oben Name[el]=Τύλιγμα πάνω παραθύρου Name[eo]=Fenestro supren volviĝas Name[es]=Enrrollar ventana Name[et]=Akna varjamine Name[eu]=Leihoaren pertsiana igo Name[fa]=پنجره به بالا سایه شد Name[fi]=Rullaa ikkuna ylös Name[fr]=Enrouler une fenêtre Name[fy]=Finster oprôlje Name[gl]=Enrólase unha Fiestra Name[he]=גלילת חלון למעלה Name[hi]=विंडो शेड अप Name[hr]=Zamotaj prozor Name[hu]=Ablak felgördítése Name[id]=Jendela berangsur ke atas Name[is]=Glugga rúllað upp Name[it]=Arrotola finestra Name[ja]=ウィンドウを手前に Name[ko]=창 감추기 Name[lo]=ພັບເກັບຫນ້າຕ່າງ Name[lt]=Rodyti pilnai Name[lv]=Aizēnots logs Name[mk]=Засенчи нагоре Name[mn]=Цонхны сүүдэр дээш нь Name[mt]=Cekken Window f'Linja Name[nb]=Rull opp vinduet Name[nds]=Finster tosamenrullen Name[nl]=Venster oprollen Name[nn]=Rull opp vindauge Name[nso]=Ntshofatso ya Window Name[oc]=Plega la finestra Name[pa]=ਝਰੋਖਾ ਪਰਛਾਵਾਂ ਕਰੋ Name[pl]=Odsłonięcie okna Name[pt]=Enrolar Janela Name[pt_BR]=Enrolar Janela Name[ro]=Strînge fereastra Name[ru]=Свернуть в заголовок Name[se]=Rulle láse bajás Name[sk]=Zobraziť okno Name[sl]=Zvij okno Name[sr]=Прозор се намотава Name[sr@Latn]=Prozor se namotava Name[sv]=Fönster rullas upp Name[ta]=சாளர நிழல் ஏற்று Name[tg]=Тиреза ба боло соя шуд Name[th]=พับเก็บหน้าต่าง Name[tr]=Pencere Yukarı Name[uk]=Згорнути вікно Name[ven]=Murunzi wa windo wa ntha Name[vi]=Cuộn cửa sổ xuống Name[wa]=Erôlmint do purnea Name[xh]=Window Yenza umthunzi Phezulu Name[xx]=xxWindow Shade Upxx Name[zh_CN]=窗口卷起 Name[zh_TW]=收起視窗 Name[zu]=Umthunzi we-Window Uphezulu Comment=A window is shaded up Comment[az]=Pəncərə yuxarı burulub Comment[bg]=Свиване на прозорец нагоре Comment[bn]=একটি উইণ্ডো গুটানো হয়েছে Comment[br]=Rollet eo ur prenestr Comment[bs]=Prozor je podignut (zarolan) Comment[ca]=Una finestra es plega amunt Comment[cs]=Okno je zarolováno Comment[da]=Et vindue skygges op Comment[de]=Fenster ist eingefahren Comment[el]=Ένα παράθυρο τυλίχθηκε πάνω Comment[eo]=Fenestro volviĝis supren Comment[es]=Se recoge una ventana Comment[et]=Aken rullitakse kokku Comment[eu]=Leihoa pertsiana gisa biltzen da Comment[fi]=Ikkuna rullataan ylös Comment[fr]=Une fenêtre est enroulée Comment[fy]=In finster is oprôle Comment[gl]=Unha fiestra prégase Comment[he]=חלון נגלל למעלה Comment[hi]=एक विंडो में छाया भरी गई Comment[hu]=Ablak felgördítése Comment[is]=Glugga er rúllað upp Comment[it]=Una finestra viene arrotolata Comment[ja]=ウィンドウが手前に来ます Comment[lt]=Langas rodomas pilnai Comment[lv]=Logs ir Aizēnots Comment[mk]=Прозорецот се засенчува нагоре Comment[mt]=Window tingħalaq 'il fuq Comment[nb]=Et vindu rulles opp Comment[nds]=En Finster warrt tosamenrullt Comment[nl]=Een venster is opgerold Comment[nn]=Eit vindauge vert rulla opp Comment[pa]=ਇੱਕ ਝਰੋਖੇ ਦਾ ਪਰਛਾਵਾਂ ਤਬਦੀਲ Comment[pl]=Okno zostaje rozwinięte Comment[pt]=Uma janela é enrolada Comment[pt_BR]=Uma janela é enrolada (para cima) Comment[ro]=O fereastră s-a strîns Comment[ru]=Окно свёрнуто в заголовок Comment[se]=Láse rullejuvvo bajás Comment[sk]=Okno je zabalené Comment[sl]=Okno je zvito Comment[sr]=Прозор је намотан Comment[sr@Latn]=Prozor je namotan Comment[sv]=Ett fönster rullas upp Comment[ta]=சாளரம் நிழலிடப்பட்டுள்ளது. Comment[tr]=Pencere yukarı gizlendi Comment[uk]=Вікно згорнуто Comment[wa]=On purnea a stî erôlé Comment[xx]=xxA window is shaded upxx Comment[zh_CN]=窗口被卷起 default_sound=KDE_Window_Shade_Up.ogg default_presentation=0 [shadedown] Name=Window Shade Down Name[af]=Venster Skadu Ondertoe Name[ar]=تظليل نافذة الى الأسفل Name[az]=Pəncərəni Aşağı Salınması Name[bg]=Свиване на прозорец надолу Name[bn]=উইণ্ডো নামাও Name[br]=Dirollañ ar Prenestr Name[bs]=Spuštanje prozora Name[ca]=Desplega la finestra Name[cs]=Vyrolování okna Name[cy]=Rholio'r Ffenestr i Lawr Name[da]=Skyg vindue ned Name[de]=Fensterheber nach unten Name[el]=Τύλιγμα κάτω παραθύρου Name[eo]=Fenestro malsupren volviĝas Name[es]=Desenrrollar ventana Name[et]=Akna taasnäitamine Name[eu]=Leihoaren petsiana jitsi Name[fa]=پنجره به پایین سایه شد Name[fi]=Rullaa ikkuna alas Name[fr]=Dérouler une fenêtre Name[fy]=Finster ôfrôlje Name[gl]=Desprégase unha Fiestra Name[he]=גלילת חלון למטה Name[hi]=विंडो शेड डाउन Name[hr]=Odmotaj prozor Name[hu]=Ablak legördítése Name[id]=Jendela berangsur ke basah Name[is]=Glugga rúllað niður Name[it]=Srotola finestra Name[ja]=ウィンドウを後ろに Name[ko]=창 보이기 Name[lo]=ເລີກພັບເກັບຫນ້າຕ່າງ Name[lt]=Tik antraštės juosta Name[lv]=Atēnots Logs Name[mk]=Засенчи прозорец надолу Name[mn]=Цонхны сүүдэр доош нь Name[mt]=Kabbar Window Minn Linja Name[nb]=Rull ned vinduet Name[nds]=Finster utrullen Name[nl]=Venster afrollen Name[nn]=Rull ned vindauge Name[nso]=Tagafatso ya Window Name[oc]=Desplega la finestra Name[pa]=ਝਰੋਖਾ ਪਰਛਾਵਾਂ ਹਟਾਓ Name[pl]=Zasłonięcie okna Name[pt]=Desenrolar Janela Name[pt_BR]=Desenrolar Janela Name[ro]=Derulează fereastra Name[ru]=Развернуть из заголовка Name[se]=Rulle láse vulos Name[sk]=Schovať okno Name[sl]=Razvij okno Name[sr]=Прозор се одмотава Name[sr@Latn]=Prozor se odmotava Name[sv]=Fönster rullas ner Name[ta]=சாளர நிழல் இறக்கு Name[tg]=Тиреза ба поён соя шуд Name[th]=ยกเลิกพับเก็บหน้าต่าง Name[tr]=Pencere Aşağı Name[uk]=Розгорнути вікно Name[ven]=Murunzi wa windo wa fhasi Name[vi]=Cuộn Cửa sổ xuống Name[wa]=Disrôlmint des purneas Name[xh]=Window Yenza umthunzi Ezantsi Name[xx]=xxWindow Shade Downxx Name[zh_CN]=窗口展开 Name[zh_TW]=展開視窗 Name[zu]=Umthunzi we-Window Uphansi Comment=A window is shaded down Comment[az]=Pəncərə aşağı salınıb Comment[bg]=Свиване на прозорец нагоре Comment[bn]=একটি উইণ্ডো নামানো হয়েছে Comment[br]=Dirollet eo ur prenestr Comment[bs]=Prozor je spušten (odrolan) Comment[ca]=Una finestra es plega avall Comment[cs]=Okno je vyrolováno Comment[da]=Et vindue skygges ned Comment[de]=Fenster ist ausgefahren Comment[el]=Ένα παράθυρο τυλίχθηκε κάτω Comment[eo]=Fenestro volviĝis malsupren Comment[es]=Se extiende una ventana Comment[et]=Aken rullitakse lahti Comment[eu]=Leihoa pertsiana gisa zabaltzen da Comment[fi]=Ikkuna rullataan alas Comment[fr]=Une fenêtre est déroulée Comment[fy]=In finster is ôfrôle Comment[gl]=Unha fiestra desprégase Comment[he]=חלון נגלל למטה Comment[hi]=एक विंडो से छाया हटाई गई Comment[hu]=Ablak legördítése Comment[is]=Glugga er rúllað niður Comment[it]=Una finestra viene srotolata Comment[ja]=ウィンドウが後ろに回り込みます Comment[lt]=Rodoma tik lango antraštės juosta Comment[lv]=Logs ir Atēnots Comment[mk]=Прозорецот е засенчен надолу Comment[mt]=Window tingħalaq 'l isfel Comment[nb]=Et vindu rulles ned Comment[nds]=En Finster warrt wedder utrullt Comment[nl]=Een venster is afgerold Comment[nn]=Eit vindauge vert rulla ned Comment[pa]=ਇੱਕ ਝਰੋਖੇ ਦਾ ਪਰਛਾਵਾਂ ਹਟਾਓ Comment[pl]=Okno zostaje zwinięte Comment[pt]=Uma janela é desenrolada Comment[pt_BR]=Uma janela é desenrolada Comment[ro]=O fereastră s-a derulat Comment[ru]=Окно развёрнуто из заголовка Comment[se]=Láse rullejuvvo vulos Comment[sk]=Okno je rozbalené Comment[sl]=Okno je razvito Comment[sr]=Прозор је одмотан Comment[sr@Latn]=Prozor je odmotan Comment[sv]=Ett fönster rullas ner Comment[ta]=சாளரமொன்று நிழலிடப்பட்டது Comment[tr]=Pencere aşağı gizlendi Comment[uk]=Вікно розгорнуто Comment[wa]=On purnea a stî disrôlé Comment[xx]=xxA window is shaded downxx Comment[zh_CN]=窗口被展开 default_sound=KDE_Window_Shade_Down.ogg default_presentation=0 [minimize] Name=Window Minimize Name[ar]=تصغير الشاشة Name[az]=Pəncərə Kiçildilməsi Name[be]=Мінімалізацыя акна Name[bg]=Минимизиране на прозорец Name[bn]=উইণ্ডো মিনিমাইজ Name[br]=Kilbleg ar prenestr Name[bs]=Minimiziranje prozora Name[ca]=Minimitza finestra Name[cs]=Minimalizace okna Name[cy]=Lleihau Ffenestr Name[da]=Minimér vindue Name[de]=Fenster minimieren Name[el]=Ελαχιστοποίηση παραθύρου Name[en_GB]=Window Minimise Name[eo]=Fenestro minimumiĝas Name[es]=Minimizar ventana Name[et]=Akna minimeerimine Name[eu]=Leihoa minimizatu Name[fi]=Pienennä ikkuna Name[fr]=Réduire une fenêtre Name[fy]=Minimalisearje finster Name[ga]=Íoslaghdaigh Fuinneog Name[gl]=Fiestra Minimizada Name[he]=מזעור חלון Name[hi]=विंडो न्यूनतम Name[hr]=Minimizacija prozora Name[hu]=Ablak minimalizálása Name[is]=Glugga lágmarkað Name[it]=Minimizza finestra Name[ja]=ウィンドウ最小化 Name[lt]=Sumažinti langą Name[lv]=Minimizet logu Name[mk]=Спушти прозорец Name[mn]=Цонх жижигсгэх Name[mt]=Imminimizza Window Name[nb]=Minimer vindu Name[nds]=Finster minimeert Name[nl]=Venster minimaliseren Name[nn]=Minimer vindauge Name[pa]=ਝਰੋਖਾ ਨਿਊਨਤਮ Name[pl]=Minimalizacja okna Name[pt]=Minimizar Janela Name[pt_BR]=Minimizar Janela Name[ro]=Minimizează fereastra Name[ru]=Минимизация окна Name[se]=Minimere láse Name[sk]=Minimalizovať okno Name[sl]=Pomanjšaj okno Name[sr]=Минимизација прозора Name[sr@Latn]=Minimizacija prozora Name[sv]=Fönster minimeras Name[ta]=சாளரத்தைப் சிறிதாக்கு Name[tg]=Тирезаи бешина Name[th]=ย่อหน้าต่างเล็กสุด Name[tr]=Pencereyi Simge Haline Getir Name[uk]=Мінімізувати вікно Name[uz]=Ойнани йиғиш Name[vi]=Làm to cửa sổ Name[wa]=Purnea metou å pus ptit Name[xx]=xxWindow Minimizexx Name[zh_CN]=窗口最小化 Name[zh_TW]=最小化視窗 Comment=A window is minimized Comment[az]=Pəncərə kiçildilib Comment[be]=Акно мінімалізаванае Comment[bg]=Минимизиране на прозорец Comment[bn]=একটি উইণ্ডো মিনিমাইজ করা হয়েছে Comment[br]=Kilbleget eo ur prenestr Comment[bs]=Prozor je minimiziran Comment[ca]=Es minimitza una finestra Comment[cs]=Okno je minimalizováno Comment[da]=Et vindue minimeres Comment[de]=Fenster ist minimiert Comment[el]=Ένα παράθυρο ελαχιστοποιήθηκε Comment[en_GB]=A window is minimised Comment[eo]=Fenestro minimumiĝas Comment[es]=Se minimiza una ventana Comment[et]=Aken on minimeeritud Comment[eu]=Leihoa minimizatu egiten da Comment[fi]=Ikkuna on pienennetty Comment[fr]=Une fenêtre est réduite Comment[fy]=In finster is minimalisearre Comment[gl]=Minimizouse unha fiestra Comment[he]=חלון ממוזער Comment[hi]=एक विंडो न्यूनतम हुआ Comment[hu]=Ablak minimalizálása Comment[is]=Gluggi er lágmarkaður Comment[it]=Una finestra viene minimizzata Comment[ja]=ウィンドウが最小化されます Comment[lt]=Langas sumažintas Comment[lv]=Logs ir Minimizēts Comment[mk]=Прозорецот се спушта Comment[mt]=Window ġiet minimizzata Comment[nb]=Et vindu minimeres Comment[nds]=En Finster warrt minimeert Comment[nl]=Een venster is geminimaliseerd Comment[nn]=Eit vindauge vert minimert Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਨਿਊਨਤਮ Comment[pl]=Okno jest minimalizowane Comment[pt]=Uma janela é minimizada Comment[pt_BR]=Uma janela é minimizada Comment[ro]=O fereastră a fost minimizată Comment[ru]=Окно минимизировано Comment[se]=Láse minimerejuvvo Comment[sk]=Okno je minimalizované Comment[sl]=Okno je pomanjšano Comment[sr]=Прозор је минимизован Comment[sr@Latn]=Prozor je minimizovan Comment[sv]=Ett fönster minimeras Comment[ta]=சாளரம் சிறிதாக்கப்பட்டுள்ளது Comment[tr]=Bir pencere simge haline getirildi Comment[uk]=Вікно мінімізовано Comment[uz]=Ойна йиғилган Comment[wa]=On purnea a stî metou å pus ptit Comment[xx]=xxA window is minimizedxx Comment[zh_CN]=窗口被最小化 default_sound=KDE_Window_Iconify.ogg default_presentation=0 [unminimize] Name=Window Unminimize Name[ar]=عدم تصغير الشاشة Name[az]=Pəncərə Geri Böyüdülməsi Name[bg]=Възстановяване на минимизиран прозорец Name[bn]=উইণ্ডো আনমিনিমাইজ Name[bs]=Deminimiziranje prozora Name[ca]=Desminimitza finestra Name[cs]=Obnovení okna po minimalizaci Name[cy]=Dad-leihau Ffenestr Name[da]=Afminimér vindue Name[de]=Minimieren rückgängig machen Name[el]=Αποελαχιστοποίηση παραθύρου Name[en_GB]=Window Unminimise Name[eo]=Fenestro neminimumiĝas Name[es]=Deminimizar ventana Name[et]=Akna suuruse taastamine Name[eu]=Leihoa desminimizatu Name[fi]=Suurenna ikkuna takaisin Name[fr]=Restaurer une fenêtre Name[fy]=Minimalisearjen fan finster ûngedien meitsje Name[gl]=Fiestra Non Minimizada Name[he]=ביטול מזעור חלון Name[hi]=विंडो न्यूनतम नहीं Name[hr]=Prozor se obnavlja poslije minimizacije Name[hu]=Minimalizált ablak visszaállítása Name[is]=Gluggi ekki lágmarkað Name[it]=Deminimizza finestra Name[ja]=ウィンドウ最小化解除 Name[lt]=Panaikinti lango sumažinimą Name[lv]=Loga Atminimizēšana Name[mk]=Врати прозорец Name[mn]=Цонхны томсголт авах Name[mt]=Irrestawra window minimizzata Name[nb]=Gjenopprett vindu Name[nds]=Finster wedder wiesen Name[nl]=Minimalisatie van venster ongedaan maken Name[nn]=Gjenopprett vindauge Name[pa]=ਝਰੋਖਾ ਨਾ-ਨਿਊਨਤਮ Name[pl]=Powrót ze stanu minimalizacji okna Name[pt]=Desminimizar Janela Name[pt_BR]=Desminimizar Janela Name[ro]=Reface fereastra Name[ru]=Восстановление размеров окна Name[se]=Máhcat láse Name[sk]=Zrušiť minimalizáciu okna Name[sl]=Od-pomanjšaj okno Name[sr]=Прозор се обнавља после минимизације Name[sr@Latn]=Prozor se obnavlja posle minimizacije Name[sv]=Fönsterminimering tas bort Name[ta]=சாளர சிறிதாக்காதே Name[tg]=Тирезаи то бешина Name[th]=ยกเลิกย่อหน้าต่างเล็กสุด Name[tr]=Pencereyi Simge Halinden Çıkar Name[uk]=Демінімізувати вікно Name[vi]=Không làm to cửa sổ Name[wa]=Purnea rimetou a s' grandeu di dvant Name[xx]=xxWindow Unminimizexx Name[zh_CN]=窗口取消最小化 Name[zh_TW]=取消最小化視窗 Comment=A Window is restored Comment[az]=Pəncərə köhnə böyüklüyünə gətirilib Comment[bg]=Възстановяване на минимизиран прозорец Comment[bn]=একটি উইণ্ডো রিস্টোর করা হয়েছে Comment[br]=Assavet eo ur prenestr Comment[bs]=Prozor je prikazan Comment[ca]=Es restaura una finestra Comment[cs]=Okno je obnoveno Comment[da]=Et vindue genetableres Comment[de]=Fenster ist wiederhergestellt Comment[el]=Ένα παράθυρο αποκαταστάθηκε Comment[eo]=Fenestro reaperas Comment[es]=Se restaura una ventana Comment[et]=Aken on taastatud Comment[eu]=Leihoa lehengoratu egiten da Comment[fi]=Ikkuna on palautettu Comment[fr]=Une fenêtre en icône est restaurée Comment[fy]=In finster is hersteld Comment[gl]=Restaurouse unha fiestra Comment[he]=חלון משוחזר Comment[hi]=एक विंडो पुनर्स्थापित हुआ Comment[hu]=Ablak visszaállítása Comment[is]=Gluggi er færður úr táknmynd Comment[it]=Una finestra viene ripristinata Comment[ja]=ウィンドウが修復されます Comment[lt]=Langas atstatytas Comment[lv]=Logs ir Atjaunots Comment[mk]=Прозорецот се враќа Comment[mt]=Window tiġi Restawrata Comment[nb]=Et vindu gjenopprettes Comment[nds]=En Finster warrt torüchbrocht Comment[nl]=Een venster is hersteld Comment[nn]=Eit vindauge vert gjenoppretta Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਮੁੜ-ਪ੍ਰਾਪਤ Comment[pl]=Okno jest przywrócone Comment[pt]=Uma janela é restaurada Comment[pt_BR]=Uma Janela é restaurada Comment[ro]=O fereastră a fost restaurată Comment[ru]=Размер окна восстановлен Comment[se]=Láse huksejuvvo fas Comment[sk]=Okno je obnovené Comment[sl]=Okno je povrnjeno Comment[sr]=Прозор је обновљен Comment[sr@Latn]=Prozor je obnovljen Comment[sv]=Ett fönster återställs Comment[ta]=சாளரமொன்று மீளமைக்கப்பட்டது Comment[tr]=Bir pencere eski boyutuna getirildi Comment[uk]=Вікно відновлено Comment[uz]=Ойна тикланган Comment[xx]=xxA Window is restoredxx Comment[zh_CN]=窗口被恢复 default_sound=KDE_Window_DeIconify.ogg default_presentation=0 [maximize] Name=Window Maximize Name[af]=Venster Maksimeer Name[ar]=تكبير النافذة Name[az]=Pəncərənin Böyüdülməsi Name[bg]=Максимизиране на прозорец Name[bn]=উইণ্ডো ম্যাক্সিমাইজ Name[br]=Astenn ar Prenestr Name[bs]=Maksimiziranje prozora Name[ca]=Maximitza finestra Name[cs]=Maximalizace okna Name[cy]=Ehangu Ffenestr Name[da]=Maksimér vindue Name[de]=Fenster maximieren Name[el]=Μεγιστοποίηση παραθύρου Name[en_GB]=Window Maximise Name[eo]=Fenestro maksimumiĝas Name[es]=Maximizar ventana Name[et]=Akna maksimeerimine Name[eu]=Leihoa maximizatu Name[fa]=پنجره‌ی بیشینه Name[fi]=Suurenna ikkuna Name[fr]=Maximiser une fenêtre Name[fy]=finster maksimalisearje Name[ga]=Uasmhéadaigh Fuinneog Name[gl]=Maximízase unha Fiestra Name[he]=הגדלת חלון Name[hi]=विंडो अधिकतम Name[hr]=Maksimiziranje prozora Name[hu]=Ablak maximalizálása Name[id]=Maximize Jendela Name[is]=Gluggi hámarkaður Name[it]=Massimizza finestra Name[ja]=ウィンドウ最大化 Name[ko]=창 크기를 가장 크게 Name[lo]=ຂະຫຍາຍຫນ້າຕ່າງໃຫຍ່ສຸດ Name[lt]=Išdidinti langą Name[lv]=Maksimizēt logu Name[mk]=Рашири прозорец Name[mn]=Цонх томсгох Name[mt]=Immassimizza Window Name[nb]=Maksimer vindu Name[nds]=Finster maximeren Name[nl]=Venster maximaliseren Name[nn]=Maksimer vindauge Name[nso]=Koketso ya Window Name[oc]=Maximitza finestra Name[pa]=ਝਰੋਖਾ ਅਧਿਕਤਮ Name[pl]=Maksymalizacja okna Name[pt]=Maximizar Janela Name[pt_BR]=Maximizar Janela Name[ro]=Maximizează fereastra Name[ru]=Распахнуть окно Name[se]=Maksimere láse Name[sk]=Maximalizovať okno Name[sl]=Razpni okno Name[sr]=Прозор се максимизује Name[sr@Latn]=Prozor se maksimizuje Name[ss]=Khulisa liwindi Name[sv]=Fönster maximeras Name[ta]=சாளரத்தைப் பெரிதாக்கு Name[tg]=Тирезаи бешина Name[th]=ขยายหน้าต่างใหญ่สุด Name[tr]=Pencereyi Kapla Name[uk]=Максимізувати вікно Name[uz]=Ойнани ёйиш Name[ven]=U hudza Windo Name[vi]=Làm to cửa sổ Name[wa]=Purnea metou å pus grand Name[xh]=Window Yenza nkulu Name[xx]=xxWindow Maximizexx Name[zh_CN]=窗口最大化 Name[zh_TW]=最大化視窗 Name[zu]=Khulisa I-window Comment=A window is maximized Comment[az]=Pəncərə böyüdülüb Comment[be]=Акно максымалізаванае Comment[bg]=Максимизиране на прозорец Comment[bn]=একটি উইণ্ডো ম্যাক্সিমাইজ করা হয়েছে Comment[br]=Astennet eo ur prenestr Comment[bs]=Prozor je maksimiziran Comment[ca]=Es maximitza una finestra Comment[cs]=Okno je maximalizováno Comment[da]=Et vindue maksimeres Comment[de]=Fenster ist maximiert Comment[el]=Ένα παράθυρο μεγιστοποιήθηκε Comment[en_GB]=A window is maximised Comment[eo]=Fenestro maksimumiĝas Comment[es]=Se maximiza una ventana Comment[et]=Aken on maksimeeritud Comment[eu]=Leihoa maximizatu egiten da Comment[fi]=Ikkuna on suurennettu Comment[fr]=Une fenêtre est maximisée Comment[fy]=In finster is maksimalisearre Comment[gl]=Maximizouse unha fiestra Comment[he]=חלון מוגדל Comment[hi]=एक विंडो अधिकतम हुआ Comment[hu]=Ablak maximalizálása Comment[is]=Gluggi er hámarkaður Comment[it]=Una finestra viene massimizzata Comment[ja]=ウィンドウが最大化されます Comment[lt]=Langas išdidintas Comment[lv]=Logs ir Maksimizēts Comment[mk]=Прозорецот се раширува Comment[mt]=Window tiġi Mkabbra Comment[nb]=Et vindu maksimeres Comment[nds]=En Finster warrt maximeert Comment[nl]=Een venster is gemaximaliseerd Comment[nn]=Eit vindauge vert maksimert Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਅਧਿਕਤਮ Comment[pl]=Okno jest maksymalizowane Comment[pt]=Uma janela é maximizada Comment[pt_BR]=Uma janela é maximizada Comment[ro]=O fereastră a fost maximizată Comment[ru]=Окно распахнуто на весь экран Comment[se]=Láse maksimerejuvvo Comment[sk]=Okno je maximalizované Comment[sl]=Okno je razpeto Comment[sr]=Прозор је максимизован Comment[sr@Latn]=Prozor je maksimizovan Comment[sv]=Ett fönster maximeras Comment[ta]=சாளரம் பெரிதாக்கப்பட்டுள்ளது Comment[tr]=Bir pencere büyütüldü Comment[uk]=Вікно максимізовано Comment[uz]=Ойна ёйилган Comment[wa]=On purnea a stî metou å pus grand Comment[xx]=xxA window is maximizedxx Comment[zh_CN]=窗口被最大化 default_sound=KDE_Window_UnHide.ogg default_presentation=0 [unmaximize] Name=Window Unmaximize Name[af]=Venster On-maksimeer Name[ar]=اعادة النافذة Name[az]=Pəncərənin Geri Kiçildilməsi Name[bg]=Възстановяване на максимизиран прозорец Name[bn]=উইণ্ডো আনম্যাক্সিমাইজ Name[br]=Krennañ ar Prenestr Name[bs]=Demaksimiziranje prozora Name[ca]=Desmaximitza finestra Name[cs]=Obnovení okna po maximalizaci Name[cy]=Dad_ehangu Ffenestr Name[da]=Afmaksimér vindue Name[de]=Fenster auf vorige Größe Name[el]=Απομεγιστοποίηση παραθύρου Name[en_GB]=Window Unmaximise Name[eo]=Fenestro nemaksimumiĝas Name[es]=Demaximizar ventana Name[et]=Akna suuruse taastamine Name[eu]=Leihoa desmaximizatu Name[fa]=پنجره‌ی نابیشینه Name[fi]=Poista ikkunan suurennus Name[fr]=Restaurer une fenêtre maximisée Name[fy]=Maksimalisaasje fan finster ûngedien meitsje Name[gl]=Desmaximízase unha Fiestra Name[he]=שיחזור הגדלת חלון Name[hi]=विंडो अधिकतम नहीं Name[hr]=Demaksimiziranje prozora Name[hu]=Maximalizált ablak visszaállítása Name[id]=UnMaximize Jendela Name[is]=Gluggi úr hámarki Name[it]=Demassimizza finestra Name[ja]=ウィンドウ最大化解除 Name[ko]=창 크기 원레대로 Name[lo]=ຍົກເລີກຂະຫຍາຍຫນ້າຕ່າງໃຫຍ່ສຸດ Name[lt]=Sumažinti langą Name[lv]=Loga Atmaksimizēšana Name[mk]=Одрашири прозорец Name[mn]=Цонхны томсголт авах Name[mt]=Ċekken Window mill-Massimu Name[nb]=Gjenopprett vindu Name[nds]=Finster op vörige Grött Name[nl]=Maximalisatie van venster ongedaan maken Name[nn]=Gjenopprett vindauge Name[nso]=Phokotso ya Window Name[oc]=Demaximitza finestra Name[pa]=ਝਰੋਖਾ ਨਾ-ਅਧਿਕਤਮ Name[pl]=Powrót ze stanu maksymalizacji okna Name[pt]=Reduzir Janela Name[pt_BR]=Desmaximizar Janela Name[ro]=Reface fereastra Name[ru]=Восстановить размер окна Name[se]=Máhcat láse Name[sk]=Zmenšiť okno Name[sl]=Od-razpni okno Name[sr]=Прозор се обнавља после максимизовања Name[sr@Latn]=Prozor se obnavlja posle maksimizovanja Name[sv]=Fönstermaximering tas bort Name[ta]=சாளரத்தை பெரிதாக்காதே Name[tg]=Тирезаи то бешина Name[th]=ยกเลิกขยายหน้าต่างใหญ่สุด Name[tr]=Pencereyi Küçült Name[uk]=Демаксимізувати вікно Name[ven]=U fhungudza Windo Name[vi]=Không làm to cửa sổ Name[wa]=Purnea rimetou a s' grandeu di dvant Name[xh]=Window Sukwenza ubukhulu Name[xx]=xxWindow Unmaximizexx Name[zh_CN]=窗口取消最大化 Name[zh_TW]=取消最大化視窗 Name[zu]=Nciphisa i-Window Comment=A window loses maximization Comment[az]=Pəncərə geri kiçildilir Comment[bg]=Възстановяване на максимизиран прозорец Comment[bn]=একটি উইণ্ডো ম্যাক্সিমাইজেশন হারিয়েছে Comment[br]=Koll a ra ur prenestr e astenn Comment[bs]=Prozor gubi maksimizaciju Comment[ca]=Una finestra perd la maximització Comment[cs]=Okno ztratilo maximalizaci Comment[da]=Et vindue afmaksimeres Comment[de]=Fenster unter Maximalgröße gebracht Comment[en_GB]=A window loses maximisation Comment[eo]=Fenestro nemaksimumiĝis Comment[es]=Una ventana pierde su maximización Comment[et]=Aken kaotab maksimaalse suuruse Comment[eu]=Leihoak gadu egiten du maximizazioa Comment[fi]=Ikkuna menettää suurennuksen Comment[fr]=Une fenêtre maximisée est restaurée Comment[fy]=In finster ferliest maksimalisaasje Comment[gl]=Unha fiestra perdeu a maximización Comment[he]=מבוטלת הגדלת חלון Comment[hi]=एक विंडो ने अधिकतम खोया Comment[hu]=Maximalizált ablak visszaállítása Comment[is]=Gluggi hættir að vera hámarkaður Comment[it]=Una finestra massimizzata viene ripristinata Comment[ja]=ウィンドウの最大化を解除します Comment[lt]=Langas prarado išdidinimą Comment[lv]=Logs Zaudējis Maksimizāciju Comment[mk]=Прозорецот го губи раширувањето Comment[mt]=Window ma Tibqax Imkabbra Comment[nb]=Et vindu mister maksimering Comment[nds]=En Finster is nich mehr maximeert Comment[nl]=Een venster verliest maximalisatie Comment[nn]=Eit vindauge mister maksimering Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਢਿੱਲਾ ਅਧਿਕਤਮ Comment[pl]=Okno przestaje być zmaksymalizowane Comment[pt]=Uma janela deixa de estar maximizada Comment[pt_BR]=Uma janela perde a maximização Comment[ro]=O fereastră a pierdut maximizarea Comment[ru]=Окно более не распахнуто Comment[se]=Láse ii šat maksimerejuvvon Comment[sk]=Okno nie je maximalizované Comment[sl]=Okno ni več razpeto Comment[sr]=Прозор више није максимизован Comment[sr@Latn]=Prozor više nije maksimizovan Comment[sv]=Ett fönster förlorar maximering Comment[ta]=சாளரம் பெரிதாவதை இழந்தது Comment[tr]=Bir pencere büyümesini kaybetti Comment[uk]=Вікно втрачає максимізацію Comment[xx]=xxA window loses maximizationxx Comment[zh_CN]=窗口不再最大化 default_sound=KDE_Window_Hide.ogg default_presentation=0 [on_all_desktops] Name=Window On All Desktops Name[ar]=النافذة على كل أسطح المكاتب Name[be]=Акно на ўсіх працоўных cталох Name[bg]=Прозорец на всички работни плотове Name[bn]=উইণ্ডো সব ডেস্কটপে Name[br]=Ar prenestr war an holl vurevoù Name[bs]=Prozor na svim desktopima Name[ca]=Finestra a tots els escriptoris Name[cs]=Okno na všech plochách Name[cy]=Ffenestr ar Bob Un Penbwrdd Name[da]=Vindue på alle desktoppe Name[de]=Fenster auf allen Arbeitsflächen Name[el]=Παράθυρο σε όλες τις επιφάνειες εργασίας Name[eo]=Fenestro sur ĉiuj labortabloj Name[es]=Ventana en todos los escritorios Name[et]=Aken kõigil töölaudadel Name[eu]=Leihoa mahaigain guztietan Name[fi]=Ikkuna kaikilla työpöydillä Name[fr]=Fenêtre visible sur tous les bureaux Name[fy]=Finster op alle buroblêden Name[gl]=Fiestra en Tódolos Escritorios Name[he]=הצגת חלון על כל שולחנות העבודה Name[hi]=सभी डेस्कटॉप पर विंडो Name[hr]=Prozor na svim radnim površinama Name[hu]=Ablak az összes munkaasztalra Name[is]=Glugga á öll skjáborð Name[it]=Finestra su tutti i desktop Name[ja]=全デスクトップのウィンドウ Name[lt]=Langas matomas visuose darbastaliuose Name[lv]=Logs uz visām darbvirsmām Name[mk]=Прозорецот кон сите површини Name[mn]=Цонхыг бүх ажлын тавцан дээр Name[mt]=Window fuq desktops kollha Name[nb]=Vindu på alle skrivebord Name[nds]=Finster op all Schriefdischen Name[nl]=Venster op alle bureaubladen Name[nn]=Vindauge på alle skrivebord Name[pa]=ਝਰੋਖਾ ਸਾਰੇ ਵਿਹੜਿਆਂ ਤੇ Name[pl]=Pokazywanie okna na wszystkich pulpitach Name[pt]=Janela em Todos os Ecrãs Name[pt_BR]=Janela em Todas as Áreas de Trabalho Name[ro]=Fereastră pe toate ecranele Name[ru]=Окно на всех рабочих столах Name[se]=Láse buot čállinbevddiin Name[sk]=Okno na všetky plochy Name[sl]=Okno na vsa namizja Name[sr]=Прозор на свим радним површинама Name[sr@Latn]=Prozor na svim radnim površinama Name[sv]=Fönster på alla skrivbord Name[ta]=எல்லா மேல்மேசைகளிலும் சாளரம் Name[tg]=Тиреза ба тамоми мизи корӣ Name[th]=หน้าต่างบนทุกพื้นที่ทำงาน Name[tr]=Pencere Tüm Masaüstlerinde Name[uk]=Вікно на всі стільниці Name[uz]=Ойна ҳамма иш столларига Name[vi]=Hiện cửa sổ trên tất cả các Desktop Name[wa]=Purnea håyné so tos les scribannes Name[xx]=xxWindow On All Desktopsxx Name[zh_CN]=窗口在全部桌面上 Name[zh_TW]=視窗在所有桌面 Comment=A window is made visible on all desktops Comment[bg]=Прозорец на всички работни плотове Comment[bn]=একটি উইণ্ডো এখন থেকে সব ডেস্কটপে দেখা যাবে Comment[bs]=Prozor je vidljiv na svim radnim površinama Comment[ca]=Una finestra es fa visible a tots els escriptoris Comment[cs]=Okno je viditelné na všech plochách Comment[da]=Et vindue gøres synligt på alle desktoppe Comment[de]=Fenster wird auf allen Arbeitsflächen angezeigt Comment[el]=Ένα παράθυρο γίνεται ορατό σε όλες τις επιφάνειες εργασίας Comment[eo]=Fenestro videbliĝis sur ĉiuj labortabloj Comment[es]=Una ventana se hace visible en todos los escritorios Comment[et]=Aken on muudetud nähtavaks kõigil töölaudadel Comment[eu]=Leihoa mahaigain guztietan ikusgai bihurtzen da Comment[fi]=Ikkuna näytetään kaikilla työpöydillä Comment[fr]=Une fenêtre est maintenant visible sur tous les bureaux Comment[fy]=In finster is sichtber makke op alle buroblêden Comment[gl]=Unha fiestra faise visíbel en tódolos escritorios Comment[he]=חלון נעשה מוצג בכל שולחנות העבודה Comment[hi]=एक विंडो सभी डेस्कटॉप पर दृष्टिगोचर हुआ Comment[hu]=Egy ablak megjelent az összes munkaasztalon Comment[is]=Gluggi er látinn sjást á öllum skjáborðum Comment[it]=Una finestra viene resa visibile su tutti i desktop Comment[ja]=全デスクトップで全ウィンドウが可視状態にされます Comment[lt]=Langas matomas visuose darbastaliuose Comment[lv]=Logs ir redzams uz visām darbvirsmām Comment[mk]=Прозорецот се прави видлив на сите површини Comment[mt]=Window twaħħlet fuq id-desktops kollha Comment[nb]=Et vindu gjøres synlig på alle skrivebord Comment[nds]=En Finster warrt op all Schriefdischen wiest Comment[nl]=Een venster is zichtbaar gemaakt op alle bureaubladen Comment[nn]=Eit vindauge vert gjort synleg på alle skriveborda Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਸਭ ਵਿਹੜਿਆਂ ਵਿੱਚ ਦਿੱਸੇ Comment[pl]=Okno bedzie widoczne na wszystkich pulpitach Comment[pt]=Uma janela passa a aparecer em todos os ecrãs Comment[pt_BR]=Uma janela ficou visível em todas as áreas de trabalho Comment[ro]=O fereastră a fost făcută vizibilă pe toate ecranele Comment[ru]=Окно сделано видимым на всех рабочих столах Comment[se]=Láse darvvihuvvo buot čállinbevddiide Comment[sk]=Okno bude viditeľné na všetkých plochách Comment[sl]=Okno je vidno na vseh namizjih Comment[sr]=Прозор је учињен видљивим на свим радним површинама Comment[sr@Latn]=Prozor je učinjen vidljivim na svim radnim površinama Comment[sv]=Ett fönster görs synligt på alla skrivbord Comment[ta]=சாளரத்தை அனைத்து மேல்மேசையிலும் பார்க்க முடியும் Comment[tr]=Bir pencere tüm masaüstlerinde görünür hale getirildi Comment[uk]=Вікно зроблено видимим на всіх стільницях Comment[uz]=Ойна ҳамма иш столларида кўринадиган қилинди Comment[wa]=On purnea a stî håyné so tos les scribannes Comment[xx]=xxA window is made visible on all desktopsxx Comment[zh_CN]=窗口出现在全部桌面上 default_sound=KDE_Window_Sticky.ogg default_presentation=0 [not_on_all_desktops] Name=Window Not On All Desktops Name[ar]=النافذة ليست على كل أسطح المكاتب Name[bg]=Прозорец само на един работен плот Name[bn]=উইণ্ডো সব ডেস্কটপে নয় Name[br]=N'eo ket war an holl vurevoù ar prenestr Name[bs]=Prozor nije na svim desktopima Name[ca]=Finestra no a tots els escriptoris Name[cs]=Okno není na všech plochách Name[cy]=Ffenestr Dim ar Bob Un Penbwrdd Name[da]=Vindue ikke på alle desktoppe Name[de]=Fenster nicht auf allen Arbeitsflächen Name[el]=Παράθυρο όχι σε όλες τις επιφάνειες εργασίας Name[eo]=Fenestro ne sur ĉiuj labortabloj Name[es]=Ventana no en todos los escritorios Name[et]=Aken ei ole kõigil töölaudadel Name[eu]=Leihoa mahaigain guztietan ez Name[fi]=Ikkuna vain yhdellä työpöydällä Name[fr]=Fenêtre visible sur un seul bureau Name[fy]=Finster net op alle buroblêden Name[gl]=Fiestra Non en Tódolos Escritorios Name[he]=הצגת חלון לא על כל שולחנות העבודה Name[hi]=सभी डेस्कटॉप पर विंडो नहीं Name[hr]=Prozor nije na svim radnim površinama Name[hu]=Ablak nem az összes munkaasztalra Name[is]=Gluggi ekki á öllum skjáborðum Name[it]=Finestra non su tutti i desktop Name[ja]=全てのデスクトップ上にないウィンドウ Name[lt]=Langas matomas ne visuose darbastaliuose Name[lv]=Logs ne uz visām darbvirsmām Name[mk]=Прозорецот не кон сите површини Name[mn]=Цонхыг бүх ажлын тавцан дээр биш Name[mt]=Window mhux fuq desktops kollha Name[nb]=Vindu ikke på alle skrivebord Name[nds]=Finster nich op all Schriefdischen Name[nl]=Venster niet op alle bureaubladen Name[nn]=Vindauge ikkje på alle skrivebord Name[pa]=ਝਰੋਖਾ ਸਾਰੇ ਵਿਹੜਿਆਂ ਤੇ ਨਹੀਂ Name[pl]=Usunięcie pokazywania okna na wszystkich pulpitach Name[pt]=Janela Não Em Todos os Ecrãs Name[pt_BR]=Janela Não Em Todas Áreas de Trabalho Name[ro]=Fereastra nu este pe toate ecranele Name[ru]=Окно не на всех рабочих столах Name[se]=Láse ii buot čállinbevddiin Name[sk]=Okno na jednu plochu Name[sl]=Okno ne na vsa namizja Name[sr]=Прозор није на свим радним површинама Name[sr@Latn]=Prozor nije na svim radnim površinama Name[sv]=Fönster inte på alla skrivbord Name[ta]=எல்லா மேல்மேசைகளிலும் சாளரம் இல்லை Name[tg]=Тиреза на ба тамоми мизи корӣ Name[th]=หน้าต่างไม่อยู่บนทุกพื้นที่ทำงาน Name[tr]=Pencere Tüm Masaüstlerinde Değil Name[uk]=Вікно не на всі стільниці Name[uz]=Ойна ҳамма иш столларида эмас Name[vi]=Không hiện cửa sổ trên tất cả các Desktop Name[wa]=Purnea nén håyné so tos les scribannes Name[xx]=xxWindow Not On All Desktopsxx Name[zh_CN]=窗口不在全部桌面上 Name[zh_TW]=視窗不在所有桌面 Comment=A Window is no longer visible on all desktops Comment[bg]=Прозорец само на един работен плот Comment[bn]=একটি উইণ্ডো আর সব ডেস্কটপে দেখা যাচ্ছে না Comment[bs]=Prozor više nije vidljiv na svim radnim površinama Comment[ca]=Una finestra deixa de ser visible a tots els escriptoris Comment[cs]=Okno již není viditelné na všech plochách Comment[da]=Et vindue er ikke længere synligt på alle desktoppe Comment[de]=Fenster wird nicht mehr auf allen Arbeitsflächen angezeigt Comment[el]=Ένα παράθυρο δεν είναι πλέον ορατό σε όλες τις επιφάνειες εργασίας Comment[eo]=Fenestro nevidebliĝis sur ĉiuj labortabloj Comment[es]=Una ventana ya no es visible en todos los escritorios Comment[et]=Aken ei ole enam nähtav kõigil töölaudadel Comment[eu]=Leihoa ez da gehiago ikusiko leiho guztietan Comment[fi]=Ikkuna ei ole enää näkyvillä kaikilla työpöydillä Comment[fr]=Une fenêtre n'est maintenant plus visible sur tous les bureaux Comment[fy]=In finster is net langer sichtber op alle buroblêden Comment[gl]=Unha fiestra xa non é visíbel en tódolos escritorios Comment[he]=חלון כבר לא מוצג בכל שולחנות העבודה Comment[hi]=एक विंडो सभी डेस्कटॉप पर अब दृष्टिगोचर नहीं है Comment[hu]=Egy ablak nem jelenik meg többé az összes munkaasztalon Comment[is]=Gluggi er ekki lengur sýnilegur á öllum skjáborðum Comment[it]=Una finestra non è più visibile su tutti i desktop Comment[ja]=ウィンドウがどのデスクトップでも可視状態ではありません Comment[lt]=Langas nebematomas visuose darbastaliuose Comment[lv]=Logs vairs nav redzams uz visām darba virsmām Comment[mk]=Прозорецот не е повеќе видлив на сите површини Comment[mt]=Window m'għadhiex imwaħħla fuq id-desktops kollha Comment[nb]=Et vindu er ikke lenger synlig på alle skrivebord Comment[nds]=En Finster warrt nich mehr op all Schriefdischen wiest Comment[nl]=Een venster is niet langer zichtbaar op alle bureaubladen Comment[nn]=Eit vindauge er ikkje lenger synleg på alle skriveborda Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਸਭ ਵਿਹੜਿਆਂ ਵਿੱਚ ਨਾ ਦਿੱਸੇੱਸੇ Comment[pl]=Okno nie jest już widoczne na wszystkich pulpitach Comment[pt]=Uma janela deixa de aparecer em todos os ecrãs Comment[pt_BR]=Uma Janela não está mais visível em todas as áreas de trabalho Comment[ro]=O fereastră nu mai este vizibilă pe toate ecranele Comment[ru]=Окно более не является видимым на всех рабочих столах Comment[se]=Láse ii šat oidno buot čállinbevddiin Comment[sk]=Okno už nebude viditeľné na všetkých plochách Comment[sl]=Okno ni več vidno na vseh namizjih Comment[sr]=Прозор више није видљив на свим радним површинама Comment[sr@Latn]=Prozor više nije vidljiv na svim radnim površinama Comment[sv]=Ett fönster blir inte längre synligt på alla skrivbord Comment[ta]=அனைத்து மேல்மேசையிலும் சாளரம் தெரியாது Comment[tr]=Bir pencere tüm masaüstlerinde gizli hale getirildi Comment[uk]=Вікно більше не є видимим на всіх стільницях Comment[uz]=Ойна ҳамма иш столларида кўринмайдиган қилинди Comment[wa]=On purnea n' est pus håyné so tos les scribannes Comment[xx]=xxA Window is no longer visible on all desktopsxx Comment[zh_CN]=窗口不再出现在全部桌面上 default_presentation=1 default_sound=KDE_Window_UnSticky.ogg [transnew] Name=New Dialog Name[af]=Nuwe Dialoog Name[ar]=مربع حوار جديد Name[az]=Yeni Pəncərə Name[bg]=Нов диалогов прозорец Name[bn]=নতুন ডায়ালগ Name[br]=Kendiviz nevez Name[bs]=Novi dijalog Name[ca]=Nou diàleg Name[cs]=Nové dialogové okno Name[cy]=Ymgom Newydd Name[da]=Ny dialog Name[de]=Neuer Dialog Name[el]=Νέος διάλογος Name[en_GB]=New Dialogue Name[eo]=Nova dialogo Name[es]=Nuevo diálogo Name[et]=Uus dialoog Name[eu]=Elkarrizketa berria Name[fa]=گفتگوی جدید Name[fi]=Uusi ikkuna Name[fr]=Nouvelle boîte de dialogue Name[fy]=Nij dialooch Name[ga]=Dialóg Nua Name[gl]=Novo Diálogo Name[he]=דו־שיח חדש Name[hi]=नया संवाद Name[hr]=Novi dijalog Name[hu]=Új párbeszédablak Name[id]=Dialog Baru Name[is]=Opna nýjan glugga Name[it]=Nuova finestra di dialogo Name[ja]=新規ダイアログ Name[ko]=새 대화창 Name[lo]=ສ້າງກ່ອງໂຕ້ຕອບໃຫມ່ Name[lt]=Naujas dialogas Name[lv]=Jauns Dialogs Name[mk]=Нов дијалог Name[mn]=Шинэ диалог Name[mt]=Djalogu Ġdid Name[nb]=Ny dialogvindu Name[nds]=Niegen Dialoog Name[nl]=Nieuw dialoog Name[nn]=Ny dialogboks Name[nso]=Poledisano ye Ntshwa Name[pa]=ਨਵੀਂ ਤਖਤੀ Name[pl]=Nowe okno dialogowe Name[pt]=Nova Janela Name[pt_BR]=Novo Diálogo Name[ro]=Dialog nou Name[ru]=Новый диалог Name[se]=Ođđa láseš Name[sk]=Nový dialóg Name[sl]=Novo pogovorno okno Name[sr]=Нови дијалог Name[sr@Latn]=Novi dijalog Name[ss]=Inkhulumo-mphendvulwano lensha Name[sv]=Ny dialog Name[ta]=புதிய உரையாடல் Name[tg]=Гуфтугӯи нав Name[th]=สร้างกล่องโต้ตอบใหม่ Name[tr]=Yeni Pencere Name[uk]=Нове вікно діалогу Name[uz]=Янги диалог Name[ven]=Nyambedzano ntswa Name[vi]=Hộp thoại mới Name[wa]=Novea purnea di kesse Name[xh]=Incoko yababini Entsha Name[xx]=xxNew Dialogxx Name[zh_CN]=新建对话框 Name[zh_TW]=新對話盒 Name[zu]=Ingxoxo Entsha Comment=Transient window (a dialog) appears Comment[bg]=Нов диалогов прозорец Comment[bn]=একটি সাময়িক উইণ্ডো (ডায়ালগ) আবির্ভূত হয়েছে Comment[bs]=Prolazni prozor (dijalog) se pojavljuje Comment[ca]=Apareix una finestra transitòria (un diàleg) Comment[cs]=Objevilo se dialogové okno Comment[da]=Midlertidigt vindue (en dialog) kommer til syne Comment[de]=Transientes Fenster (Dialog) wird angezeigt Comment[el]=Εμφάνιση μεταβατικού παραθύρου (διαλόγου) Comment[en_GB]=Transient window (a dialogue) appears Comment[eo]=Provizora fenestro (dialogo) aperas Comment[es]=Aparece una ventana transitoria (un diálogo) Comment[et]=Ajutine aken (dialoog) ilmub Comment[eu]=Leiho elkarrizketa agertzen da Comment[fi]=Transientti-ikkuna (dialogi) ilmestyy Comment[fr]=Une boîte de dialogue apparaît Comment[fy]=In dialooch ferskynd Comment[gl]=Aparece unha fiestra temporal (un diálogo) Comment[he]=מופיע חלון ארעי (דו־שיח) Comment[hi]=ट्रांजिएंट विंडो (एक संवाद) प्रकट हुआ Comment[hu]=Párbeszédablak megjelenése Comment[is]=Fyrirspurnargluggi birtist Comment[it]=Appare una finestra di dialogo Comment[ja]=トランジェントウィンドウ(ダイアログ)が現れます Comment[lt]=Atsiranda laikinas langas (dialogas) Comment[lv]=Parādās Īslaicīgs Logs (dialogs) Comment[mk]=Се појавува преоден прозорец (дијалог) Comment[mt]=Tidher window tranżjenti (djalogu) Comment[nb]=Midlertidig dialogvindu vises Comment[nds]=En kortwielig Finster (Dialoog) dukt op Comment[nl]=Een dialoog verschijnt Comment[nn]=Mellombels vindauge (ein dialog) vert opna Comment[pa]=ਗੱਲਬਾਤ ਝਰੋਖਾ(ਤਖਤੀ) ਉਪਲੱਬਧ Comment[pl]=Pojawia się tymczaowe okno dialogowe Comment[pt]=Uma janela transitória (uma janela de diálogo) aparece Comment[pt_BR]=Aparece uma janela transiente (um diálogo) Comment[ro]=A apărut o fereastră de dialog Comment[ru]=Выводится временное окно (диалог) Comment[se]=Gaskaboddosaš láse (láseš) rahpojuvvo Comment[sk]=Objavilo sa dočasné dialógové okno Comment[sl]=Odprlo se je prehodno (pogovorno) okno Comment[sr]=Пролазни прозор (дијалог) се појављује Comment[sr@Latn]=Prolazni prozor (dijalog) se pojavljuje Comment[sv]=Ett tillfälligt fönster (en dialogruta) dyker upp Comment[ta]=தற்காலிக சாளரம் (ஒரு உரையாடல்) தோன்றுகிறது Comment[tr]=Bir iletişim kutusu belirdi Comment[uk]=З'являється тимчасове вікно (діалог) Comment[uz]=Мулоқат ойнаси пайдо бўлди Comment[xx]=xxTransient window (a dialog) appearsxx default_sound=KDE_Dialog_Appear.ogg default_presentation=0 [transdelete] Name=Delete Dialog Name[af]=Uitvee Dialoog Name[ar]=الغاء مربع الحوار Name[az]=Dialoqu Sil Name[bg]=Затваряне на диалогов прозорец Name[bn]=ডায়ালগ মুছে ফেল Name[br]=Lemel ar gendiviz Name[bs]=Briši dijalog Name[ca]=Esborra el diàleg Name[cs]=Zrušení dialogového okna Name[cy]=Dileu Ymgom Name[da]=Slet dialog Name[de]=Dialog löschen Name[el]=Διαγραφή διαλόγου Name[en_GB]=Delete Dialogue Name[eo]=Forigo de dialogo Name[es]=Eliminar diálogo Name[et]=Dialoogi kustutamine Name[eu]=Ezabatu elkarrizketa Name[fa]=حذف گفتگو Name[fi]=Tuhoa ikkuna Name[fr]=Fermeture de la boîte de dialogue Name[fy]=Dialooch wisse Name[ga]=Scrios Dialóg Name[gl]=Pechar Diálogo Name[he]=מחיקת דו־שיח Name[hi]=संवाद मिटाएँ Name[hr]=Brisanje dijaloga Name[hu]=Törlési párbeszédablak Name[id]=Hapus Dialog Name[is]=Eyða glugga Name[it]=Elimina finestra di dialogo Name[ja]=ダイアログを削除 Name[ko]=대화창 지우기 Name[lo]=ລົບກ່ອງໂຕ້ຕອບ Name[lt]=Pašalinti dialogą Name[lv]=Dzēst Dialogu Name[mk]=Избриши дијалог Name[mn]=Диалог устгах Name[mt]=Neħħi Dialog Name[nb]=Fjern dialogvindu Name[nds]=Dialoog löschen Name[nl]=Dialoog verwijderen Name[nn]=Fjern dialogboks Name[nso]=Tlosa Poledisano Name[pa]=ਤਖਤੀ ਹਟਾਓ Name[pl]=Usunięcie okna dialogowego Name[pt]=Apagar Janela Name[pt_BR]=Remover Diálogo Name[ro]=Închide dialog Name[ru]=Удалить диалог Name[se]=Sihko láseš Name[sk]=Zmazať dialóg Name[sl]=Zbriši pogovorno okno Name[sr]=Дијалог се брише Name[sr@Latn]=Dijalog se briše Name[ss]=Bulala inkhulumo-mphendvulwano Name[sv]=Ta bort dialog Name[ta]=உரையாடலை நீக்கு Name[tg]=Нобуд сохтани гуфтугӯ Name[th]=ลบกล่องโต้ตอบ Name[tr]=Pencereyi Sil Name[uk]=Видалити вікно діалогу Name[uz]=Диалогни ўчириш Name[ven]=Thuthani nyambedzano Name[vi]=Xoá hộp thoại Name[wa]=Disfacer l' purnea di kesse Name[xh]=Cima Incoko yababini Name[xx]=xxDelete Dialogxx Name[zh_CN]=删除对话框 Name[zh_TW]=刪除對話盒 Name[zu]=Cisha Ingxoxo Comment=Transient window (a dialog) is removed Comment[bg]=Затваряне на диалогов прозорец Comment[bn]=একটি সাময়িক উইণ্ডো (ডায়ালগ) সরিয়ে ফেলা হয়েছে Comment[bs]=Prolazni prozor (dijalog) nestaje Comment[ca]=S'elimina una finestra transitòria (un diàleg) Comment[cs]=Dialogové okno bylo zavřeno Comment[da]=Midlertidigt vindue (en dialog) fjernes Comment[de]=Transientes Fenster (Dialog) wird entfernt Comment[el]=Μεταβατικό παράθυρο (ένας διάλογος) αφαιρείται Comment[en_GB]=Transient window (a dialogue) is removed Comment[eo]=Provizora fenestro (dialogo) malaperas Comment[es]=Desaparece una ventana transitoria (un diálogo) Comment[et]=Ajutine aken (dialoog) on eemaldatud Comment[eu]=Leiho elkarrizketa kentzen da Comment[fi]=Transientti-ikkuna (dialogi) poistetaan Comment[fr]=Une boîte de dialogue disparaît Comment[fy]=In dialooch is slúten Comment[gl]=Elimínase unha fiestra temporal (un diálogo) Comment[he]=מוסר חלון ארעי (דו־שיח) Comment[hi]=ट्रांजिएंट विंडो (एक संवाद) हटाया गया Comment[hu]=Párbeszédablak eltávolítása Comment[is]=Fyrirspurnarglugga er eytt Comment[it]=Viene rimossa una finestra di dialogo Comment[ja]=トランジェントウィンドウ(ダイアログ)を削除します Comment[lt]=Laikinas langas (dialogas) yra pašalintas Comment[lv]=Īslaicīgais Logs (dialogs) ir aizvākts Comment[mk]=Отстранет е преодниот прозорец (дијалог) Comment[mt]=Titneħħa window tranżjenti (djalogu) Comment[nb]=Midlertidig dialogvindu fjernes Comment[nds]=En kortwielig Finster (Dialoog) verswinnt Comment[nl]=Een dialoog is gesloten Comment[nn]=Mellombels vindauge (ein dialog) vert lukka Comment[pa]=ਗੱਲਬਾਤ ਝਰੋਖਾ(ਤਖਤੀ) ਹਟੀਂ Comment[pl]=Znika tymczasowe okno dialogowe Comment[pt]=Uma janela transitória (uma janela de diálogo) desaparece Comment[pt_BR]=Uma janela transiente (um diálogo) é removida Comment[ro]=A dispărut o fereastră de dialog Comment[ru]=Временное окно (диалог) удалено Comment[se]=Gaskaboddosaš láse (láseš) giddejuvvo Comment[sk]=Dočasné dialógové okno je odstránené Comment[sl]=Zaprlo se je prehodno (pogovorno) okno Comment[sr]=Пролазни прозор (дијалог) је уклоњен Comment[sr@Latn]=Prolazni prozor (dijalog) je uklonjen Comment[sv]=Ett tillfälligt fönster (en dialogruta) försvinner Comment[ta]=தற்காலிக சாளரம்(உரையாடல் பெட்டி) நீக்கப்பட்டது Comment[tr]=Bir iletişim kutusu kaldırıldı Comment[uk]=Зникає тимчасове вікно (діалог) Comment[uz]=Мулоқат ойнаси ёпилди Comment[xx]=xxTransient window (a dialog) is removedxx default_sound=KDE_Dialog_Disappear.ogg default_presentation=0 [movestart] Name=Window Move Start Name[af]=Venster Beweeg Begin Name[ar]=بداية تحريك النافذة Name[az]=Pəncərə Daşıma Başlanğıcı Name[bg]=Начало на преместване на прозорец Name[bn]=উইণ্ডো সরানো শুরু Name[br]=Kregiñ da zilec'hiañ ar prenestr Name[bs]=Početak pomjeranja prozora Name[ca]=Inici de moviment de la finestra Name[cs]=Začátek přesunu okna Name[cy]=Cychwyn Symud y Ffenestr Name[da]=Vindue flyt begynd Name[de]=Fenster verschieben: Start Name[el]=Αρχή μετακίνησης παραθύρου Name[eo]=Komenco de fenestromovo Name[es]=Comenzar a mover la ventana Name[et]=Akna liigutamise algus Name[eu]=Leihoaren mugimenduaren hasiera Name[fa]=پنجره‌ای شروع به حرکت کرد Name[fi]=Ikkunan siirto alkaa Name[fr]=Début de déplacement de fenêtre Name[fy]=Begjinne mei finsterbeweging Name[gl]=Inicio dun Movemento de Fiestra Name[he]=התחלת הזזת חלון Name[hi]=विंडो खिसकाना चालू Name[hr]=Početak micanja prozora Name[hu]=Ablakmozgatás kezdete Name[id]=Pindah Start Jendela Name[is]=Færsla glugga hefst Name[it]=Inizio spostamento finestra Name[ja]=ウィンドウ移動開始 Name[ko]=창 옮기기 시작 Name[lo]=ເລີ່ມຍ້າຍຫນ້າຕ່າງ Name[lt]=Lango perkėlimo pradžia Name[lv]=Loga Pārvietošana Sākta Name[mk]=Полчеток на преместување на прозорец Name[mn]=Цонх шилжүүлэх: Эхлэл Name[mt]=Ibda' Mexxi Window Name[nb]=Start vindusflytting Name[nds]=Finsterschuven hett anfangt Name[nl]=Starten met vensterbeweging Name[nn]=Start vindaugsflytting Name[nso]=Thomiso ya Tshutiso ya Window Name[oc]=Inici de moviment de finestra Name[pa]=ਝਰੋਖਾ ਏਧਰ-ਓਧਰ ਸ਼ੁਰੂ Name[pl]=Start przesuwania okna Name[pt]=Janela começa a mover-se Name[pt_BR]=Começar a mover janela Name[ro]=Început mutare fereastră Name[ru]=Начало передвижения окна Name[se]=Lásesirdima álgu Name[sk]=Začať presun okna Name[sl]=Premakni začetek okna Name[sr]=Почетак премештања прозора Name[sr@Latn]=Početak premeštanja prozora Name[sv]=Fönsterflytt börjar Name[ta]=சாளர நகர்த்தல் ஆரம்பம் Name[tg]=Тирезаҳо шурӯъ ба ҳаракат кард Name[th]=เริ่มย้ายหน้าต่าง Name[tr]=Windows Taşı Başlangıç Name[uk]=Почати рухати вікно Name[uz]=Ойнани кўчиришни бошлаш Name[ven]=U thoma u tshimbila ha windo Name[vi]=Chuyển cửa sổ về đầu Name[wa]=Li purnea cmince a bodjî Name[xh]=Isiqalo Sentshukumo ye Window Name[xx]=xxWindow Move Startxx Name[zh_CN]=窗口移动开始 Name[zh_TW]=開始移動視窗 Name[zu]=Ukuqala komnyakazo we-Window Comment=A window has begun moving Comment[bg]=Начало на преместване на прозорец Comment[bn]=একটি উইণ্ডো সরানো শুরু হয়েছে Comment[bs]=Prozor se počeo pomjerati Comment[ca]=Una finestra ha començat a moure's Comment[cs]=Okno započalo přesun Comment[da]=Et vindue er begyndt at flyttes Comment[de]=Fenster wird verschoben Comment[el]=Ένα παράθυρο άρχισε να μετακινείται Comment[eo]=Fenestro komencis movadon Comment[es]=Comienza a moverse una ventana Comment[et]=Aken on hakanud liikuma Comment[eu]=Leihoa mugitzen hasi da Comment[fi]=Ikkuna aloittaa siirtymisen Comment[fr]=Début de déplacement de fenêtre Comment[fy]=In finster begon mei bewegen Comment[gl]=Unha Fiestra Comezou a se Mover Comment[he]=חלון החל לזוז Comment[hi]=एक विंडो खिसकना चालू हुआ Comment[hu]=Ablakmozgatás kezdete Comment[is]=Gluggi hefur byrjað að færast Comment[it]=Inizia lo spostamento di una finestra Comment[ja]=ウィンドウ移動が開始しています Comment[lt]=Langas pradėjo judėti Comment[lv]=Logs ir Sācis Pārvietoties Comment[mk]=Прозорецот почнува да се преместува Comment[mt]=Window bdiet titmexxa Comment[nb]=Vindusflytting starter Comment[nds]=Dat Verschuven vun'n Finster hett anfungen Comment[nl]=Een venster begon met bewegen Comment[nn]=Vindaugsflytting startar Comment[pa]=ਇੱਕ ਝਰੋਖਾ ਹਿੱਲਣਾ ਸ਼ੁਰੂ Comment[pl]=Okno zaczyna być przesuwane Comment[pt]=Uma janela começou a movimentar-se Comment[pt_BR]=Uma janela começou a ser movida Comment[ro]=O fereastră a început să se mişte Comment[ru]=Окно начало перемещаться Comment[se]=Láse lea lihkadišgoahtán Comment[sk]=Začal sa presun okna Comment[sl]=Okno se je pričelo premikati Comment[sr]=Прозор је почео са премештањем Comment[sr@Latn]=Prozor je počeo sa premeštanjem Comment[sv]=Ett fönster har börjat flyttas Comment[ta]=சாளரம் நகர ஆரம்பித்தது Comment[tr]=Bir pencere hareket etmeye başladı Comment[uk]=Початок пересування вікна Comment[uz]=Ойна кўчиб бошлади Comment[wa]=On purnea a cmincî a bodjî Comment[xx]=xxA window has begun movingxx Comment[zh_CN]=窗口开始移动 default_presentation=0 [moveend] Name=Window Move End Name[af]=Venster Beweeg Einde Name[ar]=نهاية تحريك النافذة Name[az]=Pəncərə Daşıma Bitişi Name[bg]=Край на преместване на прозорец Name[bn]=উইণ্ডো সরানো শেষ Name[br]=Echuiñ da zilec'hiañ ar prenestr Name[bs]=Kraj pomjeranja prozora Name[ca]=Fi de moviment de la finestra Name[cs]=Konec přesunu okna Name[cy]=Gorffen Symud y Ffenestr Name[da]=Vindue flyt slut Name[de]=Fenster verschieben: Ende Name[el]=Τέλος μετακίνησης παραθύρου Name[eo]=Fino de fenestromovo Name[es]=Terminar de mover la ventana Name[et]=Akna liigutamise lõpp Name[eu]=Leihoaren mugimenduaren bukaera Name[fa]=حرکت پنجره تمام شد Name[fi]=Ikkunan siirto loppuu Name[fr]=Fin de déplacement de fenêtre Name[fy]=Stopje mei finsterbeweging Name[gl]=Remate dun Movemento de Fiestra Name[he]=סיום הזזת חלון Name[hi]=विंडो खिसकाना ख़त्म Name[hr]=Kraj micanja prozora Name[hu]=Ablakmozgatás vége Name[id]=Pindah End Jendela Name[is]=Færslu glugga lýkur Name[it]=Fine spostamento finestra Name[ja]=ウィンドウ移動終了 Name[ko]=창 옮기기 끝 Name[lo]=ສີ້ນສຸດການຍ້າຍຫນ້າຕ່າງ Name[lt]=Lango perkėlimo pabaiga Name[lv]=Loga Pārvietošana Beigta Name[mk]=Крај на преместување на прозорец Name[mn]=Цонх шилжүүлэх: Төгсгөл Name[mt]=Lest Mexxi Window Name[nb]=Slutt vindusflytting Name[nds]=Finsterschuven is an't Enn Name[nl]=Stoppen met vensterbeweging Name[nn]=Slutt vindaugsflytting Name[nso]=Mafelelo a Tshutiso ya Window Name[oc]=Fin de moviment de finestra Name[pa]=ਝਰੋਖਾ ਏਧਰ-ਓਧਰ ਸਮਾਪਤ Name[pl]=Koniec przesuwania okna Name[pt]=Janela para de mover-se Name[pt_BR]=Acabar de mover janela Name[ro]=Sfîrşit mutare fereastră Name[ru]=Конец передвижения окна Name[se]=Lásesirdima loahppa Name[sk]=Dokončiť presun okna Name[sl]=Premakni konec okna Name[sr]=Крај премештања прозора Name[sr@Latn]=Kraj premeštanja prozora Name[sv]=Fönsterflytt slutar Name[ta]=சாளர நகர்த்தல் முடிவு Name[tg]=Ҳаракати тиреза тамом шуд Name[th]=สิ้นสุดการย้ายหน้าต่าง Name[tr]=Pencere Taşı Bitiş Name[uk]=Закінчити рухати вікно Name[uz]=Ойнани кўчиришни тугатиш Name[ven]=U fhela hau tshimbila ha windo Name[vi]=Chuyển cửa sổ về cuối Name[wa]=Li purnea s' djoke di bodjî Name[xh]=Isiphelo Sentshukumo ye Window Name[xx]=xxWindow Move Endxx Name[zh_CN]=窗口移动结束 Name[zh_TW]=完成移動視窗 Name[zu]=Ukuphela komnyakazo we-Window Comment=A window has completed its moving Comment[bg]=Край на преместване на прозорец Comment[bn]=একটি উইণ্ডো সরানো শেষ হয়েছে Comment[bs]=Prozor je završio micanje Comment[ca]=Una finestra ha acabat de moure's Comment[cs]=Okno dokončilo přesun Comment[da]=Et vindue er færdigt med at flytte Comment[de]=Fensterverschiebung abgeschlossen Comment[el]=Ένα παράθυρο ολοκλήρωσε τη μετακίνησή του Comment[eo]=Fenestro finis la movadon Comment[es]=Termina de moverse una ventana Comment[et]=Aken on lõpetanud liikumise Comment[eu]=Leihoaren mugimendua bukatu da Comment[fi]=Ikkunan siirto valmis Comment[fr]=Fin de déplacement de fenêtre Comment[fy]=In finster is klear mei bewegen Comment[gl]=Unha Fiestra rematou o seu movemento Comment[he]=חלון השלים את הזזתו Comment[hi]=एक विंडो ने खिसकना पूर्ण किया Comment[hu]=Ablakmozgatás vége Comment[is]=Gluggi er kominn á áfangastað Comment[it]=Finisce lo spostamento di una finestra Comment[ja]=ウィンドウ移動が終了しました Comment[lt]=Lango perkėlimas baigtas Comment[lv]=Logs ir Pabeidzis Pārvietošanos Comment[mk]=Прозорецот го заврши своето преместување Comment[mt]=Window waqfet titmexxa Comment[nb]=Vindusflytting slutter Comment[nds]=Dat Verschuven vun'n Finster is fardig Comment[nl]=Een venster is klaar met bewegen Comment[nn]=Vindaugsflytting ferdig Comment[pa]=ਇੱਕ ਝਰੋਖੇ ਦਾ ਗਤੀਵਿਧੀ ਸਮਾਪਤ Comment[pl]=Okno zakończyło przesuwanie Comment[pt]=Uma janela acabou de movimentar-se Comment[pt_BR]=Uma janela acabou de ser movida Comment[ro]=O fereastră şi-a terminat mişcarea Comment[ru]=Перемещение окна завершилось Comment[se]=Láse lea geargan lihkadeames Comment[sk]=Presun okna je ukončený Comment[sl]=Okno se je prenehalo premikati Comment[sr]=Прозор је завршио премештање Comment[sr@Latn]=Prozor je završio premeštanje Comment[sv]=Ett fönster har flyttats klart Comment[ta]=நகர்த்துவதன் மூலம் சாளரம் முழுமையடைந்தது. Comment[tr]=Bir pencere hareketini tamamladı Comment[uk]=Завершення пересування вікна Comment[uz]=Ойна кўчишни тугатди Comment[wa]=On purnea a fini d' bodjî Comment[xx]=xxA window has completed its movingxx Comment[zh_CN]=窗口完成移动 default_presentation=0 [resizestart] Name=Window Resize Start Name[af]=Venster Hervergroot Begin Name[ar]=بداية تحجيم النافذة Name[az]=Pəncərə Böyüklüyü Dəyişdirmə Başlanğıcı Name[bg]=Начало на промяна на размера на прозорец Name[bn]=উইণ্ডো মাপ বদল শুরু Name[br]=Kregiñ da adventañ ar prenestr Name[bs]=Početak promjene veličine prozora Name[ca]=Inici del canvi de mida de la finestra Name[cs]=Začátek změny velikosti okna Name[cy]=Cychwyn Newid Maint y Ffenestr Name[da]=Vindue ændr størrelse begynd Name[de]=Fenstergröße verstellen: Start Name[el]=Αρχή αλλαγής μεγέθους παραθύρου Name[eo]=Komenco de fenestro-grandecŝanĝo Name[es]=Comenzar a redimensionar la ventana Name[et]=Akna suuruse muutmise algus Name[eu]=Leihoaren tamaina aldaketaren hasiera Name[fa]=تغییر اندازه پنجره شروع شد Name[fi]=Ikkunan koonmuutos alkaa Name[fr]=Début de redimensionnement de fenêtre Name[fy]=Begjin mei it finster fan grutte te wizigjen Name[gl]=Inicio dun Redimensionamento de Fiestra Name[he]=התחלת שינוי גודל חלון Name[hi]=विंडो नया-आकार चालू Name[hr]=Početak promjene veličine prozora Name[hu]=Ablakátméretezés kezdete Name[id]=Resize Start Jendela Name[is]=Stærðarbreyting glugga hefst Name[it]=Inizio ridimensionamento finestra Name[ja]=ウィンドウリサイズ開始 Name[ko]=창 크기 조절 시작 Name[lo]=ເລີ່ມປັບຂະຫນາດຫນ້າຕ່າງ Name[lt]=Lango dydžio keitimo pradžia Name[lv]=Sākas Loga Izmēra Maiņa Name[mk]=Почеток на промена на големината на прозорец Name[mn]=Цонхны хэмжээ өөрчилөх: Эхлэл Name[mt]=Ibda daqqas it-tieqa Name[nb]=Start endring av vindusstørrelse Name[nds]=Grött-Ännern hett anfangt Name[nl]=Starten met venster van grootte wijzigen Name[nn]=Start endring av vindaugsstorleik Name[nso]=Thomiso ya Popoleswa ya Window Name[oc]=Inici de canvia de talha de finestra Name[pa]=ਝਰੋਖਾ ਮੁੜ-ਆਕਾਰ ਸ਼ੁਰੂ Name[pl]=Początek zmiany rozmiaru okna Name[pt]=Janela começa a mudar de tamanho Name[pt_BR]=Iniciar redimensionamento da janela Name[ro]=Început redimensionare fereastră Name[ru]=Меняется размер окна Name[se]=Lásesturrodaga rievdadeami álgu Name[sk]=Zmeniť veľkosť okna Name[sl]=Začetek raztezanja okna Name[sr]=Почетак мењања величине прозора Name[sr@Latn]=Početak menjanja veličine prozora Name[sv]=Storleksändring av fönster börjar Name[ta]=சாளர அளவு மாற்ற ஆரம்பம் Name[tg]=Таъғири андозаи тиреза шурӯъ шуд Name[th]=เริ่มปรับขนาดหน้าต่าง Name[tr]=Pencere Boyutlandır Başlat Name[uk]=Почати змінювати розмір вікна Name[uz]=Ойнанинг ўлчамини ўзгартириш бошланди Name[ven]=U thoma ha uita saizi hafhu ha windo Name[vi]=Thay đổi cỡ cửa sổ bắt đầu Name[wa]=Li purnea cmince a candjî di grandeu Name[xh]=Isiqalo Soniko kwakhona sobungakanani se Window Name[xx]=xxWindow Resize Startxx Name[zh_CN]=窗口缩放开始 Name[zh_TW]=開始改變視窗大小 Name[zu]=Ukuqala Kokushintsha usayizi we-Window Comment=A window has begun resizing Comment[bg]=Начало на промяна на размера на прозорец Comment[bn]=একটি উইণ্ডোর মাপ বদলানো শুরু হয়েছে Comment[bs]=Prozor je počeo mijenjati veličinu Comment[ca]=Una finestra ha començat a canviar de mida Comment[cs]=Okno započalo změnu velikosti Comment[da]=Et vindue er begyndt at ændre størrelse Comment[de]=Größenveränderung des Fensters wird gestartet Comment[el]=Ένα παράθυρο άρχισε να αλλάζει μέγεθος Comment[eo]=Vindozo komencis grandecŝanĝon Comment[es]=Comienza a redimensionarse una ventana Comment[et]=Akna suurus on hakanud muutuma Comment[eu]=Leihoaren tamaina aldatzen hasi da Comment[fi]=Ikkunan koonmuutos alkaa Comment[fr]=Début de redimensionnement de fenêtre Comment[fy]=In finster is begon mei it wizigjen fan grutte Comment[gl]=Unha Fiestra Comezou a se Redimensionar Comment[he]=חלון החל לשנות את גודלו Comment[hi]=एक विंडो में नया-आकार बनाना चालू हुआ Comment[hu]=Ablakátméretezés kezdete Comment[is]=Stærð glugga er byrjuð að breytast Comment[it]=Inizia il ridimensionamento di una finestra Comment[ja]=ウィンドウのリサイズが開始しています Comment[lt]=Lango dydis pradėtas keisti Comment[lv]=Loga Izmēra Maiņa Sākusies Comment[mk]=Прозорецот започна да ја менува големината Comment[mt]=Window bdiet tiddaqqas Comment[nb]=Endring av vindusstørrelsen starter Comment[nds]=Dat Ännern vun de Grött hett anfungen Comment[nl]=Een venster begon met het wijzigen van grootte Comment[nn]=Endring av vindaugsstorleiken startar Comment[pa]=ਇੱਕ ਝਰੋਖੇ ਦੀ ਆਕਾਰ ਤਬਦੀਲੀ ਸ਼ੁਰੂ Comment[pl]=Okno zaczęło zmianiać rozmiar Comment[pt]=Uma janela começou a mudar de tamanho Comment[pt_BR]=Uma janela começou a ser redimensionada Comment[ro]=O fereastră şi-a început redimensionarea Comment[ru]=Окно начало изменять размер Comment[se]=Láse lea rievdadišgoahtán sturrodaga Comment[sk]=Začala zmena veľkosti okna Comment[sl]=Spreminjanje velikosti okna se je začelo Comment[sr]=Прозор је почео мењање величине Comment[sr@Latn]=Prozor je počeo menjanje veličine Comment[sv]=Storleksändring av ett fönster har påbörjats Comment[ta]=சாளரத்தின் அளவு மாறத்துவங்குகிறது Comment[tr]=Bir pencere yeniden boyutlandırılmaya başladı Comment[uk]=Початок зміни розміру вікна Comment[uz]=Ойнанинг ўлчами ўзгариб бошлади Comment[wa]=On purnea a cmincî a candjî s' grandeu Comment[xx]=xxA window has begun resizingxx default_presentation=0 [resizeend] Name=Window Resize End Name[af]=Venster Hervergroot Einde Name[ar]=نهاية تحجيم النافذة Name[az]=Pəncərə Böyüklüyü Dəyişdirmə Bitişi Name[bg]=Край на промяна на размера на прозорец Name[bn]=উইণ্ডো মাপ বদল শেষ Name[br]=Echuiñ da adventañ ar prenestr Name[bs]=Kraj promjene veličine prozora Name[ca]=Fi del canvi de mida de la finestra Name[cs]=Konec změny velikosti okna Name[cy]=Gorffen Newid Maint y Ffenestr Name[da]=Vindue ændr størrelse slut Name[de]=Fenstergröße verstellen: Ende Name[el]=Τέλος αλλαγής μεγέθους παραθύρου Name[eo]=Fino de fenestro-grandecŝanĝo Name[es]=Terminar de redimensionar la ventana Name[et]=Akna suuruse muutmise lõpp Name[eu]=Leihoaren tamaina aldaketaren bukaera Name[fa]=تغییر اندازه‌ی پنجره تمام شد Name[fi]=Ikkunan koonmuutos loppuu Name[fr]=Fin de redimensionnement de fenêtre Name[fy]=Stopje mei finster fan grutte wizigjen Name[gl]=Remate dun Redimensionamento de Fiestra Name[he]=סיום שינוי גודל חלון Name[hi]=विंडो नया-आकार बन्द Name[hr]=Kraj promjene veličine prozora Name[hu]=Ablakátméretezés vége Name[id]=Resize End Jendela Name[is]=Stærðarbreyting glugga lýkur Name[it]=Fine ridimensionamento finestra Name[ja]=ウィンドウリサイズ終了 Name[ko]=창 크기 조절 끝 Name[lo]=ສີ້ນສຸດການປັບຂະຫນາດຫນ້າຕ່າງ Name[lt]=Lango dydžio keitimo pabaiga Name[lv]=Loga Izmēra Maiņa Beidzas Name[mk]=Крај на промена на големината на прозорец Name[mn]=Цонхны хэмжээ өөрчилөх: Төгсгөл Name[mt]=Lesti mid-daqqis tat-tieqa Name[nb]=Slutt endring av vindusstørrelse Name[nds]=Grött-Ännern is an't Enn Name[nl]=Stoppen met venster van grootte wijzigen Name[nn]=Slutt endring av vindaugsstorleik Name[nso]=Mafelelo a Popoleswa ya Window Name[oc]=Fin de canvi de talha de finestra Name[pa]=ਝਰੋਖਾ ਮੁੜ ਆਕਾਰ ਸਮਾਪਤ Name[pl]=Koniec zmiany rozmiaru okna Name[pt]=Janela acaba de mudar de tamanho Name[pt_BR]=Parar redimensionamento da janela Name[ro]=Sfîrşit redimensionare fereastră Name[ru]=Размер окна изменился Name[se]=Lásesturrodaga rievdadeami loahppa Name[sk]=Dokončiť zmenu veľkosti okna Name[sl]=Konec raztezanja okna Name[sr]=Крај мењања величине прозора Name[sr@Latn]=Kraj menjanja veličine prozora Name[sv]=Storleksändring av fönster slutar Name[ta]=சாளர அளவு மாற்ற முடிவு Name[tg]=Таъғири андозаи тиреза тамом шуд Name[th]=สิ้นสุดการปรับขนาดหน้าต่าง Name[tr]=Pencer Boyutlandır Bitir Name[uk]=Закінчити змінювати розмір вікна Name[uz]=Ойнанинг ўлчамини ўзгартириш тугади Name[ven]=U fhela ha uita saizi hafhu ha windo Name[vi]=Thay đổi cỡ cửa sổ kết thúc Name[wa]=Li purnea s' djoke di candjî di grandeu Name[xh]=Isiphelo Sobungakanani kwakhona se Window Name[xx]=xxWindow Resize Endxx Name[zh_CN]=窗口缩放结束 Name[zh_TW]=完成改變視窗大小 Name[zu]=Ukuphela ngokushintsha usayizi we-Window Comment=A window has finished resizing Comment[bg]=Край на промяна на размера на прозорец Comment[bn]=একটি উইণ্ডোর মাপ বদলানো শেষ হয়েছে Comment[bs]=Prozor je gotov s mijenjanjem veličine Comment[ca]=Una finestra ha acabat de canviar de mida Comment[cs]=Okno dokončilo změnu velikosti Comment[da]=Et vindue er færdigt med at ændre størrelse Comment[de]=Größenveränderung des Fensters abgeschlossen Comment[el]=Ένα παράθυρο ολοκλήρωσε την αλλαγή μεγέθους Comment[eo]=Vindozo finis grandecŝanĝon Comment[es]=Termina de redimensionarse una ventana Comment[et]=Aken on suuruse muutmise lõpetanud Comment[eu]=Leihoaren tamaina aldaketa bukatu da Comment[fi]=Ikkunan koonmuutos loppuu Comment[fr]=Fin de redimensionnement de fenêtre Comment[fy]=In finster is klaar mei it wizigjen fan grutte Comment[gl]=Unha Fiestra Rematou o Redimensionamento Comment[he]=חלון השלים את שינוי גודלו Comment[hi]=एक विंडो ने नया-आकार पूर्ण किया Comment[hu]=Ablakátméretezés vége Comment[is]=Stærð glugga hefur breyst Comment[it]=Finisce il ridimensionamento di una finestra Comment[ja]=ウィンドウのリサイズが終了しました Comment[lt]=Lango dydžio keitimas baigtas Comment[lv]=Loga Izmēra Maiņa Beigusies Comment[mk]=Прозорецот заврши со менувањето на големината Comment[mt]=Window spiċċat tiddaqqas Comment[nb]=Endring av vindusstørrelsen slutter Comment[nds]=Dat Ännern vun de Grött is fardig Comment[nl]=Een venster is klaar met het wijzigen van grootte Comment[nn]=Endring av vindaugsstorleiken ferdig Comment[pa]=ਇੱਕ ਝਰੋਖੇ ਦੀ ਆਕਾਰ ਤਬਦੀਲੀ ਸਮਾਪਤ Comment[pl]=Okno skończyło zmieniać rozmiar Comment[pt]=Uma janela acabou de mudar de tamanho Comment[pt_BR]=Uma janela foi redimensionada Comment[ro]=O fereastră şi-a terminat redimensionarea Comment[ru]=Изменение размеров окна завершено Comment[se]=Láse lea geargan sturrodaga rievdadeames Comment[sk]=Zmena veľkosti okna je ukončená Comment[sl]=Spreminjanje velikosti okna je končano Comment[sr]=Прозор је завршио промену величине Comment[sr@Latn]=Prozor je završio promenu veličine Comment[sv]=Storleksändring av ett fönster har avslutats Comment[ta]=சாளரத்தின் அளவு மாற்றுதல் முடிந்தது Comment[tr]=Bir pencerenin yeniden boyutlandırma işlemi bitti Comment[uk]=Завершення зміни розміру вікна Comment[uz]=Ойнанинг ўлчами ўзгариб бўлди Comment[wa]=On purnea a fini d' candjî s' grandeu Comment[xx]=xxA window has finished resizingxx default_presentation=0 + +[demandsattentioncurrent] +Name=Window On Current Desktop Demands Attention +Comment=A window on the current virtual desktop demands attention +default_presentation=64 + +[demandsattentionother] +Name=Window On Other Desktop Demands Attention +Comment=A window on an inactive virtual desktop demands attention +default_presentation=64 diff --git a/kcmkwin/kwinoptions/windows.cpp b/kcmkwin/kwinoptions/windows.cpp index 8ebd63b7f..0735c2c58 100644 --- a/kcmkwin/kwinoptions/windows.cpp +++ b/kcmkwin/kwinoptions/windows.cpp @@ -1,1605 +1,1608 @@ /* * windows.cpp * * Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca * Copyright (c) 2001 Waldo Bastian bastian@kde.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "windows.h" // kwin config keywords #define KWIN_FOCUS "FocusPolicy" #define KWIN_PLACEMENT "Placement" #define KWIN_MOVE "MoveMode" #define KWIN_MINIMIZE_ANIM "AnimateMinimize" #define KWIN_MINIMIZE_ANIM_SPEED "AnimateMinimizeSpeed" #define KWIN_RESIZE_OPAQUE "ResizeMode" #define KWIN_GEOMETRY "GeometryTip" #define KWIN_AUTORAISE_INTERVAL "AutoRaiseInterval" #define KWIN_AUTORAISE "AutoRaise" #define KWIN_DELAYFOCUS_INTERVAL "DelayFocusInterval" #define KWIN_DELAYFOCUS "DelayFocus" #define KWIN_CLICKRAISE "ClickRaise" #define KWIN_ANIMSHADE "AnimateShade" #define KWIN_MOVE_RESIZE_MAXIMIZED "MoveResizeMaximizedWindows" #define KWIN_ALTTABMODE "AltTabStyle" #define KWIN_TRAVERSE_ALL "TraverseAll" #define KWIN_SHOW_POPUP "ShowPopup" #define KWIN_ROLL_OVER_DESKTOPS "RollOverDesktops" #define KWIN_SHADEHOVER "ShadeHover" #define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" #define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" #define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" // kwm config keywords #define KWM_ELECTRIC_BORDER "ElectricBorders" #define KWM_ELECTRIC_BORDER_DELAY "ElectricBorderDelay" //CT 15mar 98 - magics #define KWM_BRDR_SNAP_ZONE "BorderSnapZone" #define KWM_BRDR_SNAP_ZONE_DEFAULT 10 #define KWM_WNDW_SNAP_ZONE "WindowSnapZone" #define KWM_WNDW_SNAP_ZONE_DEFAULT 10 #define MAX_BRDR_SNAP 100 #define MAX_WNDW_SNAP 100 #define MAX_EDGE_RES 1000 KFocusConfig::~KFocusConfig () { if (standAlone) delete config; } // removed the LCD display over the slider - this is not good GUI design :) RNolden 051701 KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent, const char *) : KCModule(parent, "kcmkwm"), config(_config), standAlone(_standAlone) { QString wtstr; QBoxLayout *lay = new QVBoxLayout (this, 0, KDialog::spacingHint()); //iTLabel = new QLabel(i18n(" Allowed overlap:\n" // "(% of desktop space)"), // plcBox); //iTLabel->setAlignment(AlignTop|AlignHCenter); //pLay->addWidget(iTLabel,1,1); //interactiveTrigger = new QSpinBox(0, 500, 1, plcBox); //pLay->addWidget(interactiveTrigger,1,2); //pLay->addRowSpacing(2,KDialog::spacingHint()); //lay->addWidget(plcBox); // focus policy fcsBox = new QButtonGroup(i18n("Focus"),this); fcsBox->setColumnLayout( 0, Qt::Horizontal ); QBoxLayout *fLay = new QVBoxLayout(fcsBox->layout(), KDialog::spacingHint()); QBoxLayout *cLay = new QHBoxLayout(fLay); QLabel *fLabel = new QLabel(i18n("&Policy:"), fcsBox); cLay->addWidget(fLabel, 0); focusCombo = new QComboBox(false, fcsBox); focusCombo->insertItem(i18n("Click to Focus"), CLICK_TO_FOCUS); focusCombo->insertItem(i18n("Focus Follows Mouse"), FOCUS_FOLLOWS_MOUSE); focusCombo->insertItem(i18n("Focus Under Mouse"), FOCUS_UNDER_MOUSE); focusCombo->insertItem(i18n("Focus Strictly Under Mouse"), FOCUS_STRICTLY_UNDER_MOUSE); cLay->addWidget(focusCombo,1 ,Qt::AlignLeft); fLabel->setBuddy(focusCombo); // FIXME, when more policies have been added to KWin wtstr = i18n("The focus policy is used to determine the active window, i.e." " the window you can work in.
    " "
  • Click to focus: A window becomes active when you click into it." " This is the behavior you might know from other operating systems.
  • " "
  • Focus follows mouse: Moving the mouse pointer actively on to a" " normal window activates it. New windows will receive the focus," " without you having to point the mouse at them explicitly." " Very practical if you are using the mouse a lot.
  • " "
  • Focus under mouse: The window that happens to be under the" " mouse pointer is active. If the mouse points nowhere, the last window" " that was under the mouse has focus." " New windows will not automatically receive the focus.
  • " "
  • Focus strictly under mouse: Only the window under the mouse pointer is" " active. If the mouse points nowhere, nothing has focus." "
" "Note that 'Focus under mouse' and 'Focus strictly under mouse' prevent certain" " features such as the Alt+Tab walk through windows dialog in the KDE mode" " from working properly." ); QWhatsThis::add( focusCombo, wtstr); QWhatsThis::add(fLabel, wtstr); connect(focusCombo, SIGNAL(activated(int)), this, SLOT(setAutoRaiseEnabled()) ); // autoraise delay autoRaiseOn = new QCheckBox(i18n("Auto &raise"), fcsBox); fLay->addWidget(autoRaiseOn); connect(autoRaiseOn,SIGNAL(toggled(bool)), this, SLOT(autoRaiseOnTog(bool))); autoRaise = new KIntNumInput(500, fcsBox); autoRaise->setLabel(i18n("Dela&y:"), Qt::AlignVCenter|Qt::AlignLeft); autoRaise->setRange(0, 3000, 100, true); autoRaise->setSteps(100,100); autoRaise->setSuffix(i18n(" msec")); fLay->addWidget(autoRaise); connect(focusCombo, SIGNAL(activated(int)), this, SLOT(setDelayFocusEnabled()) ); delayFocusOn = new QCheckBox(i18n("Delay focus"), fcsBox); fLay->addWidget(delayFocusOn); connect(delayFocusOn,SIGNAL(toggled(bool)), this, SLOT(delayFocusOnTog(bool))); delayFocus = new KIntNumInput(500, fcsBox); delayFocus->setLabel(i18n("Dela&y:"), Qt::AlignVCenter|Qt::AlignLeft); delayFocus->setRange(0, 3000, 100, true); delayFocus->setSteps(100,100); delayFocus->setSuffix(i18n(" msec")); fLay->addWidget(delayFocus); clickRaiseOn = new QCheckBox(i18n("C&lick raise active window"), fcsBox); connect(clickRaiseOn,SIGNAL(toggled(bool)), this, SLOT(clickRaiseOnTog(bool))); fLay->addWidget(clickRaiseOn); // fLay->addColSpacing(0,QMAX(autoRaiseOn->sizeHint().width(), // clickRaiseOn->sizeHint().width()) + 15); QWhatsThis::add( autoRaiseOn, i18n("When this option is enabled, a window in the background will automatically" " come to the front when the mouse pointer has been over it for some time.") ); wtstr = i18n("This is the delay after which the window that the mouse pointer is over will automatically" " come to the front."); QWhatsThis::add( autoRaise, wtstr ); QWhatsThis::add( clickRaiseOn, i18n("When this option is enabled, the active window will be brought to the" " front when you click somewhere into the window contents. To change" " it for inactive windows, you need to change the settings" " in the Actions tab.") ); QWhatsThis::add( delayFocusOn, i18n("When this option is enabled, there will be a delay after which the" " window the mouse pointer is over will become active (receive focus).") ); QWhatsThis::add( delayFocus, i18n("This is the delay after which the window the mouse pointer is over" " will automatically receive focus.") ); lay->addWidget(fcsBox); kbdBox = new QButtonGroup(i18n("Navigation"), this); kbdBox->setColumnLayout( 0, Qt::Horizontal ); QVBoxLayout *kLay = new QVBoxLayout(kbdBox->layout(), KDialog::spacingHint()); altTabPopup = new QCheckBox( i18n("Show window list while switching windows"), kbdBox ); kLay->addWidget( altTabPopup ); wtstr = i18n("Hold down the Alt key and press the Tab key repeatedly to walk" " through the windows on the current desktop (the Alt+Tab" " combination can be reconfigured).\n\n" "If this checkbox is checked" " a popup widget is shown, displaying the icons of all windows to" " walk through and the title of the currently selected one.\n\n" "Otherwise, the focus is passed to a new window each time Tab" " is pressed, with no popup widget. In addition, the previously" " activated window will be sent to the back in this mode."); QWhatsThis::add( altTabPopup, wtstr ); traverseAll = new QCheckBox( i18n( "&Traverse windows on all desktops" ), kbdBox ); kLay->addWidget( traverseAll ); wtstr = i18n( "Leave this option disabled if you want to limit walking through" " windows to the current desktop." ); QWhatsThis::add( traverseAll, wtstr ); rollOverDesktops = new QCheckBox( i18n("Desktop navi&gation wraps around"), kbdBox ); kLay->addWidget(rollOverDesktops); wtstr = i18n( "Enable this option if you want keyboard or active desktop border navigation beyond" " the edge of a desktop to take you to the opposite edge of the new desktop." ); QWhatsThis::add( rollOverDesktops, wtstr ); showPopupinfo = new QCheckBox( i18n("Popup desktop name on desktop &switch"), kbdBox ); kLay->addWidget(showPopupinfo); wtstr = i18n( "Enable this option if you wish to see the current desktop" " name popup whenever the current desktop is changed." ); QWhatsThis::add( showPopupinfo, wtstr ); lay->addWidget(kbdBox); lay->addStretch(); // Any changes goes to slotChanged() connect(focusCombo, SIGNAL(activated(int)), SLOT(changed())); connect(fcsBox, SIGNAL(clicked(int)), SLOT(changed())); connect(autoRaise, SIGNAL(valueChanged(int)), SLOT(changed())); connect(delayFocus, SIGNAL(valueChanged(int)), SLOT(changed())); connect(altTabPopup, SIGNAL(clicked()), SLOT(changed())); connect(traverseAll, SIGNAL(clicked()), SLOT(changed())); connect(rollOverDesktops, SIGNAL(clicked()), SLOT(changed())); connect(showPopupinfo, SIGNAL(clicked()), SLOT(changed())); load(); } int KFocusConfig::getFocus() { return focusCombo->currentItem(); } void KFocusConfig::setFocus(int foc) { focusCombo->setCurrentItem(foc); // this will disable/hide the auto raise delay widget if focus==click setAutoRaiseEnabled(); } void KFocusConfig::setAutoRaiseInterval(int tb) { autoRaise->setValue(tb); } void KFocusConfig::setDelayFocusInterval(int tb) { delayFocus->setValue(tb); } int KFocusConfig::getAutoRaiseInterval() { return autoRaise->value(); } int KFocusConfig::getDelayFocusInterval() { return delayFocus->value(); } void KFocusConfig::setAutoRaise(bool on) { autoRaiseOn->setChecked(on); } void KFocusConfig::setDelayFocus(bool on) { delayFocusOn->setChecked(on); } void KFocusConfig::setClickRaise(bool on) { clickRaiseOn->setChecked(on); } void KFocusConfig::setAutoRaiseEnabled() { // the auto raise related widgets are: autoRaise if ( focusCombo->currentItem() != CLICK_TO_FOCUS ) { autoRaiseOn->setEnabled(true); autoRaiseOnTog(autoRaiseOn->isChecked()); } else { autoRaiseOn->setEnabled(false); autoRaiseOnTog(false); } } void KFocusConfig::setDelayFocusEnabled() { // the delayed focus related widgets are: delayFocus if ( focusCombo->currentItem() != CLICK_TO_FOCUS ) { delayFocusOn->setEnabled(true); delayFocusOnTog(delayFocusOn->isChecked()); } else { delayFocusOn->setEnabled(false); delayFocusOnTog(false); } } void KFocusConfig::autoRaiseOnTog(bool a) { autoRaise->setEnabled(a); clickRaiseOn->setEnabled( !a ); } void KFocusConfig::delayFocusOnTog(bool a) { delayFocus->setEnabled(a); } void KFocusConfig::clickRaiseOnTog(bool ) { } void KFocusConfig::setAltTabMode(bool a) { altTabPopup->setChecked(a); } void KFocusConfig::setTraverseAll(bool a) { traverseAll->setChecked(a); } void KFocusConfig::setRollOverDesktops(bool a) { rollOverDesktops->setChecked(a); } void KFocusConfig::setShowPopupinfo(bool a) { showPopupinfo->setChecked(a); } void KFocusConfig::load( void ) { QString key; config->setGroup( "Windows" ); key = config->readEntry(KWIN_FOCUS); if( key == "ClickToFocus") setFocus(CLICK_TO_FOCUS); else if( key == "FocusFollowsMouse") setFocus(FOCUS_FOLLOWS_MOUSE); else if(key == "FocusUnderMouse") setFocus(FOCUS_UNDER_MOUSE); else if(key == "FocusStrictlyUnderMouse") setFocus(FOCUS_STRICTLY_UNDER_MOUSE); int k = config->readNumEntry(KWIN_AUTORAISE_INTERVAL,750); setAutoRaiseInterval(k); k = config->readNumEntry(KWIN_DELAYFOCUS_INTERVAL,750); setDelayFocusInterval(k); key = config->readEntry(KWIN_AUTORAISE); setAutoRaise(key == "on"); key = config->readEntry(KWIN_DELAYFOCUS); setDelayFocus(key == "on"); key = config->readEntry(KWIN_CLICKRAISE); setClickRaise(key != "off"); setAutoRaiseEnabled(); // this will disable/hide the auto raise delay widget if focus==click setDelayFocusEnabled(); key = config->readEntry(KWIN_ALTTABMODE, "KDE"); setAltTabMode(key == "KDE"); setRollOverDesktops( config->readBoolEntry(KWIN_ROLL_OVER_DESKTOPS, true )); config->setGroup( "PopupInfo" ); setShowPopupinfo( config->readBoolEntry(KWIN_SHOW_POPUP, false )); config->setGroup( "TabBox" ); setTraverseAll( config->readBoolEntry(KWIN_TRAVERSE_ALL, false )); config->setGroup("Desktops"); emit KCModule::changed(false); } void KFocusConfig::save( void ) { int v; config->setGroup( "Windows" ); v = getFocus(); if (v == CLICK_TO_FOCUS) config->writeEntry(KWIN_FOCUS,"ClickToFocus"); else if (v == FOCUS_UNDER_MOUSE) config->writeEntry(KWIN_FOCUS,"FocusUnderMouse"); else if (v == FOCUS_STRICTLY_UNDER_MOUSE) config->writeEntry(KWIN_FOCUS,"FocusStrictlyUnderMouse"); else config->writeEntry(KWIN_FOCUS,"FocusFollowsMouse"); v = getAutoRaiseInterval(); if (v <0) v = 0; config->writeEntry(KWIN_AUTORAISE_INTERVAL,v); v = getDelayFocusInterval(); if (v <0) v = 0; config->writeEntry(KWIN_DELAYFOCUS_INTERVAL,v); if (autoRaiseOn->isChecked()) config->writeEntry(KWIN_AUTORAISE, "on"); else config->writeEntry(KWIN_AUTORAISE, "off"); if (delayFocusOn->isChecked()) config->writeEntry(KWIN_DELAYFOCUS, "on"); else config->writeEntry(KWIN_DELAYFOCUS, "off"); if (clickRaiseOn->isChecked()) config->writeEntry(KWIN_CLICKRAISE, "on"); else config->writeEntry(KWIN_CLICKRAISE, "off"); if (altTabPopup->isChecked()) config->writeEntry(KWIN_ALTTABMODE, "KDE"); else config->writeEntry(KWIN_ALTTABMODE, "CDE"); config->writeEntry( KWIN_ROLL_OVER_DESKTOPS, rollOverDesktops->isChecked()); config->setGroup( "PopupInfo" ); config->writeEntry( KWIN_SHOW_POPUP, showPopupinfo->isChecked()); config->setGroup( "TabBox" ); config->writeEntry( KWIN_TRAVERSE_ALL , traverseAll->isChecked()); config->setGroup("Desktops"); if (standAlone) { config->sync(); if ( !kapp->dcopClient()->isAttached() ) kapp->dcopClient()->attach(); kapp->dcopClient()->send("kwin*", "", "reconfigure()", ""); } emit KCModule::changed(false); } void KFocusConfig::defaults() { setAutoRaiseInterval(0); setDelayFocusInterval(0); setFocus(CLICK_TO_FOCUS); setAutoRaise(false); setDelayFocus(false); setClickRaise(true); setAltTabMode(true); setTraverseAll( false ); setRollOverDesktops(true); setShowPopupinfo(false); emit KCModule::changed(true); } KAdvancedConfig::~KAdvancedConfig () { if (standAlone) delete config; } KAdvancedConfig::KAdvancedConfig (bool _standAlone, KConfig *_config, QWidget *parent, const char *) : KCModule(parent, "kcmkwm"), config(_config), standAlone(_standAlone) { QString wtstr; QBoxLayout *lay = new QVBoxLayout (this, 0, KDialog::spacingHint()); //iTLabel = new QLabel(i18n(" Allowed overlap:\n" // "(% of desktop space)"), // plcBox); //iTLabel->setAlignment(AlignTop|AlignHCenter); //pLay->addWidget(iTLabel,1,1); //interactiveTrigger = new QSpinBox(0, 500, 1, plcBox); //pLay->addWidget(interactiveTrigger,1,2); //pLay->addRowSpacing(2,KDialog::spacingHint()); //lay->addWidget(plcBox); shBox = new QVButtonGroup(i18n("Shading"), this); animateShade = new QCheckBox(i18n("Anima&te"), shBox); QWhatsThis::add(animateShade, i18n("Animate the action of reducing the window to its titlebar (shading)" " as well as the expansion of a shaded window") ); shadeHoverOn = new QCheckBox(i18n("&Enable hover"), shBox); connect(shadeHoverOn, SIGNAL(toggled(bool)), this, SLOT(shadeHoverChanged(bool))); shadeHover = new KIntNumInput(500, shBox); shadeHover->setLabel(i18n("Dela&y:"), Qt::AlignVCenter|Qt::AlignLeft); shadeHover->setRange(0, 3000, 100, true); shadeHover->setSteps(100, 100); shadeHover->setSuffix(i18n(" msec")); QWhatsThis::add(shadeHoverOn, i18n("If Shade Hover is enabled, a shaded window will un-shade automatically " "when the mouse pointer has been over the title bar for some time.")); wtstr = i18n("Sets the time in milliseconds before the window unshades " "when the mouse pointer goes over the shaded window."); QWhatsThis::add(shadeHover, wtstr); lay->addWidget(shBox); // Any changes goes to slotChanged() connect(animateShade, SIGNAL(toggled(bool)), SLOT(changed())); connect(shadeHoverOn, SIGNAL(toggled(bool)), SLOT(changed())); connect(shadeHover, SIGNAL(valueChanged(int)), SLOT(changed())); electricBox = new QVButtonGroup(i18n("Active Desktop Borders"), this); electricBox->setMargin(15); QWhatsThis::add( electricBox, i18n("If this option is enabled, moving the mouse to a screen border" " will change your desktop. This is e.g. useful if you want to drag windows from one desktop" " to the other.") ); active_disable = new QRadioButton(i18n("D&isabled"), electricBox); active_move = new QRadioButton(i18n("Only &when moving windows"), electricBox); active_always = new QRadioButton(i18n("A&lways enabled"), electricBox); delays = new KIntNumInput(10, electricBox); delays->setRange(0, MAX_EDGE_RES, 50, true); delays->setSuffix(i18n(" msec")); delays->setLabel(i18n("Desktop &switch delay:")); QWhatsThis::add( delays, i18n("Here you can set a delay for switching desktops using the active" " borders feature. Desktops will be switched after the mouse has been pushed against a screen border" " for the specified number of milliseconds.") ); connect( electricBox, SIGNAL(clicked(int)), this, SLOT(setEBorders())); // Any changes goes to slotChanged() connect(electricBox, SIGNAL(clicked(int)), SLOT(changed())); connect(delays, SIGNAL(valueChanged(int)), SLOT(changed())); lay->addWidget(electricBox); QHBoxLayout* focusStealingLayout = new QHBoxLayout( lay,KDialog::spacingHint()); QLabel* focusStealingLabel = new QLabel( i18n( "Focus stealing prevention level:" ), this ); focusStealing = new QComboBox( this ); focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "None" )); focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "Low" )); focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "Normal" )); focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "High" )); focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "Extreme" )); focusStealingLabel->setBuddy( focusStealing ); focusStealingLayout->addWidget( focusStealingLabel ); focusStealingLayout->addWidget( focusStealing, AlignLeft ); - wtstr = i18n( "This option specifies how much KWin will try to prevent unwanted focus stealing " + wtstr = i18n( "

This option specifies how much KWin will try to prevent unwanted focus stealing " "caused by unexpected activation of new windows. (Note: This feature does not " "work with the Focus Under Mouse or Focus Strictly Under Mouse focus policies.)" "

    " "
  • None: Prevention is turned off " "and new windows always become activated.
  • " "
  • Low: Prevention is enabled; when some window does not have support " "for the underlying mechanism and KWin cannot reliably decide whether to " "activate the window or not, it will be activated. This setting may have both " "worse and better results than normal level, depending on the applications.
  • " "
  • Normal: Prevention is enabled.
  • " "
  • High: New windows get activated only if no window is currently active " "or if they belong to the currently active application. This setting is probably " "not really usable when not using mouse focus policy.
  • " "
  • Extreme: All windows must be explicitly activated by the user.
  • " - "
" ); + "

" + "

Windows that are prevented from stealing focus are marked as demanding attention, " + "which by default means their taskbar entry will be highlighted. This can be changed " + "in the Notifications control module.

" ); QWhatsThis::add( focusStealing, wtstr ); QWhatsThis::add( focusStealingLabel, wtstr ); connect(focusStealing, SIGNAL(activated(int)), SLOT(changed())); hideUtilityWindowsForInactive = new QCheckBox( i18n( "Hide utility windows for inactive applications" ), this ); QWhatsThis::add( hideUtilityWindowsForInactive, i18n( "When turned on, utility windows (tool windows, torn-off menus,...) of inactive applications will be" " hidden and will be shown only when the application becomes active. Note that applications" " have to mark the windows with the proper window type for this feature to work." )); connect(hideUtilityWindowsForInactive, SIGNAL(toggled(bool)), SLOT(changed())); lay->addWidget( hideUtilityWindowsForInactive ); lay->addStretch(); load(); } void KAdvancedConfig::setShadeHover(bool on) { shadeHoverOn->setChecked(on); shadeHover->setEnabled(on); } void KAdvancedConfig::setShadeHoverInterval(int k) { shadeHover->setValue(k); } int KAdvancedConfig::getShadeHoverInterval() { return shadeHover->value(); } void KAdvancedConfig::shadeHoverChanged(bool a) { shadeHover->setEnabled(a); } void KAdvancedConfig::setAnimateShade(bool a) { animateShade->setChecked(a); } void KAdvancedConfig::setFocusStealing(int l) { l = KMAX( 0, KMIN( 4, l )); focusStealing->setCurrentItem(l); } void KAdvancedConfig::setHideUtilityWindowsForInactive(bool s) { hideUtilityWindowsForInactive->setChecked( s ); } void KAdvancedConfig::load( void ) { config->setGroup( "Windows" ); setAnimateShade(config->readBoolEntry(KWIN_ANIMSHADE, true)); setShadeHover(config->readBoolEntry(KWIN_SHADEHOVER, false)); setShadeHoverInterval(config->readNumEntry(KWIN_SHADEHOVER_INTERVAL, 250)); setElectricBorders(config->readNumEntry(KWM_ELECTRIC_BORDER, false)); setElectricBorderDelay(config->readNumEntry(KWM_ELECTRIC_BORDER_DELAY, 150)); // setFocusStealing( config->readNumEntry(KWIN_FOCUS_STEALING, 2 )); // TODO default to low for now setFocusStealing( config->readNumEntry(KWIN_FOCUS_STEALING, 1 )); setHideUtilityWindowsForInactive( config->readBoolEntry( KWIN_HIDE_UTILITY, true )); emit KCModule::changed(false); } void KAdvancedConfig::save( void ) { int v; config->setGroup( "Windows" ); config->writeEntry(KWIN_ANIMSHADE, animateShade->isChecked()); if (shadeHoverOn->isChecked()) config->writeEntry(KWIN_SHADEHOVER, "on"); else config->writeEntry(KWIN_SHADEHOVER, "off"); v = getShadeHoverInterval(); if (v<0) v = 0; config->writeEntry(KWIN_SHADEHOVER_INTERVAL, v); config->writeEntry(KWM_ELECTRIC_BORDER, getElectricBorders()); config->writeEntry(KWM_ELECTRIC_BORDER_DELAY,getElectricBorderDelay()); config->writeEntry(KWIN_FOCUS_STEALING, focusStealing->currentItem()); config->writeEntry(KWIN_HIDE_UTILITY, hideUtilityWindowsForInactive->isChecked()); if (standAlone) { config->sync(); if ( !kapp->dcopClient()->isAttached() ) kapp->dcopClient()->attach(); kapp->dcopClient()->send("kwin*", "", "reconfigure()", ""); } emit KCModule::changed(false); } void KAdvancedConfig::defaults() { setAnimateShade(true); setShadeHover(false); setShadeHoverInterval(250); setElectricBorders(0); setElectricBorderDelay(150); // setFocusStealing(2); // TODO default to low for now setFocusStealing(1); setHideUtilityWindowsForInactive( true ); emit KCModule::changed(true); } void KAdvancedConfig::setEBorders() { delays->setEnabled(!active_disable->isChecked()); } int KAdvancedConfig::getElectricBorders() { if (active_move->isChecked()) return 1; if (active_always->isChecked()) return 2; return 0; } int KAdvancedConfig::getElectricBorderDelay() { return delays->value(); } void KAdvancedConfig::setElectricBorders(int i){ switch(i) { case 1: active_move->setChecked(true); break; case 2: active_always->setChecked(true); break; default: active_disable->setChecked(true); break; } setEBorders(); } void KAdvancedConfig::setElectricBorderDelay(int delay) { delays->setValue(delay); } KMovingConfig::~KMovingConfig () { if (standAlone) delete config; } KMovingConfig::KMovingConfig (bool _standAlone, KConfig *_config, QWidget *parent, const char *) : KCModule(parent, "kcmkwm"), config(_config), standAlone(_standAlone) { QString wtstr; QBoxLayout *lay = new QVBoxLayout (this, 0, KDialog::spacingHint()); windowsBox = new QButtonGroup(i18n("Windows"), this); windowsBox->setColumnLayout( 0, Qt::Horizontal ); QBoxLayout *wLay = new QVBoxLayout (windowsBox->layout(), KDialog::spacingHint()); QBoxLayout *bLay = new QVBoxLayout; wLay->addLayout(bLay); opaque = new QCheckBox(i18n("Di&splay content in moving windows"), windowsBox); bLay->addWidget(opaque); QWhatsThis::add( opaque, i18n("Enable this option if you want a window's content to be fully shown" " while moving it, instead of just showing a window 'skeleton'. The result may not be satisfying" " on slow machines without graphic acceleration.") ); resizeOpaqueOn = new QCheckBox(i18n("Display content in &resizing windows"), windowsBox); bLay->addWidget(resizeOpaqueOn); QWhatsThis::add( resizeOpaqueOn, i18n("Enable this option if you want a window's content to be shown" " while resizing it, instead of just showing a window 'skeleton'. The result may not be satisfying" " on slow machines.") ); geometryTipOn = new QCheckBox(i18n("Display window &geometry when moving or resizing"), windowsBox); bLay->addWidget(geometryTipOn); QWhatsThis::add(geometryTipOn, i18n("Enable this option if you want a window's geometry to be displayed" " while it is being moved or resized. The window position relative" " to the top-left corner of the screen is displayed together with" " its size.")); QGridLayout *rLay = new QGridLayout(2,3); bLay->addLayout(rLay); rLay->setColStretch(0,0); rLay->setColStretch(1,1); minimizeAnimOn = new QCheckBox(i18n("Animate minimi&ze and restore"), windowsBox); QWhatsThis::add( minimizeAnimOn, i18n("Enable this option if you want an animation shown when" " windows are minimized or restored." ) ); rLay->addWidget(minimizeAnimOn,0,0); minimizeAnimSlider = new QSlider(0,10,10,0,QSlider::Horizontal, windowsBox); minimizeAnimSlider->setSteps(1, 1); // QSlider::Below clashes with a X11/X.h #define #undef Below minimizeAnimSlider->setTickmarks(QSlider::Below); rLay->addMultiCellWidget(minimizeAnimSlider,0,0,1,2); connect(minimizeAnimOn, SIGNAL(toggled(bool)), this, SLOT(setMinimizeAnim(bool))); connect(minimizeAnimSlider, SIGNAL(valueChanged(int)), this, SLOT(setMinimizeAnimSpeed(int))); minimizeAnimSlowLabel= new QLabel(i18n("Slow"),windowsBox); minimizeAnimSlowLabel->setAlignment(Qt::AlignTop|Qt::AlignLeft); rLay->addWidget(minimizeAnimSlowLabel,1,1); minimizeAnimFastLabel= new QLabel(i18n("Fast"),windowsBox); minimizeAnimFastLabel->setAlignment(Qt::AlignTop|Qt::AlignRight); rLay->addWidget(minimizeAnimFastLabel,1,2); wtstr = i18n("Here you can set the speed of the animation shown when windows are" " minimized and restored. "); QWhatsThis::add( minimizeAnimSlider, wtstr ); QWhatsThis::add( minimizeAnimSlowLabel, wtstr ); QWhatsThis::add( minimizeAnimFastLabel, wtstr ); moveResizeMaximized = new QCheckBox( i18n("Allow moving and resizing o&f maximized windows"), windowsBox); bLay->addWidget(moveResizeMaximized); QWhatsThis::add(moveResizeMaximized, i18n("When enabled, this feature activates the border of maximized windows" " and allows you to move or resize them," " just like for normal windows")); QBoxLayout *vLay = new QHBoxLayout(bLay); QLabel *plcLabel = new QLabel(i18n("&Placement:"),windowsBox); placementCombo = new QComboBox(false, windowsBox); placementCombo->insertItem(i18n("Smart"), SMART_PLACEMENT); placementCombo->insertItem(i18n("Cascade"), CASCADE_PLACEMENT); placementCombo->insertItem(i18n("Random"), RANDOM_PLACEMENT); placementCombo->insertItem(i18n("Centered"), CENTERED_PLACEMENT); placementCombo->insertItem(i18n("Zero-Cornered"), ZEROCORNERED_PLACEMENT); // CT: disabling is needed as long as functionality misses in kwin //placementCombo->insertItem(i18n("Interactive"), INTERACTIVE_PLACEMENT); //placementCombo->insertItem(i18n("Manual"), MANUAL_PLACEMENT); placementCombo->setCurrentItem(SMART_PLACEMENT); // FIXME, when more policies have been added to KWin wtstr = i18n("The placement policy determines where a new window" " will appear on the desktop." "
    " "
  • Smart will try to achieve a minimum overlap of windows
  • " "
  • Cascade will cascade the windows
  • " "
  • Random will use a random position
  • " "
  • Centered will place the window centered
  • " "
  • Zero-Cornered will place the window in the top-left corner
  • " "
") ; QWhatsThis::add( plcLabel, wtstr); QWhatsThis::add( placementCombo, wtstr); plcLabel->setBuddy(placementCombo); vLay->addWidget(plcLabel, 0); vLay->addWidget(placementCombo, 1, Qt::AlignLeft); bLay->addSpacing(10); lay->addWidget(windowsBox); //iTLabel = new QLabel(i18n(" Allowed overlap:\n" // "(% of desktop space)"), // plcBox); //iTLabel->setAlignment(AlignTop|AlignHCenter); //pLay->addWidget(iTLabel,1,1); //interactiveTrigger = new QSpinBox(0, 500, 1, plcBox); //pLay->addWidget(interactiveTrigger,1,2); //pLay->addRowSpacing(2,KDialog::spacingHint()); //lay->addWidget(plcBox); //CT 15mar98 - add EdgeResistance, BorderAttractor, WindowsAttractor config MagicBox = new QVButtonGroup(i18n("Snap Zones"), this); MagicBox->setMargin(15); BrdrSnap = new KIntNumInput(10, MagicBox); BrdrSnap->setSpecialValueText( i18n("none") ); BrdrSnap->setRange( 0, MAX_BRDR_SNAP); BrdrSnap->setLabel(i18n("&Border snap zone:")); BrdrSnap->setSuffix(i18n(" pixels")); BrdrSnap->setSteps(1,10); QWhatsThis::add( BrdrSnap, i18n("Here you can set the snap zone for screen borders, i.e." " the 'strength' of the magnetic field which will make windows snap to the border when" " moved near it.") ); WndwSnap = new KIntNumInput(10, MagicBox); WndwSnap->setSpecialValueText( i18n("none") ); WndwSnap->setRange( 0, MAX_WNDW_SNAP); WndwSnap->setLabel(i18n("&Window snap zone:")); WndwSnap->setSuffix( i18n(" pixels")); BrdrSnap->setSteps(1,10); QWhatsThis::add( WndwSnap, i18n("Here you can set the snap zone for windows, i.e." " the 'strength' of the magnetic field which will make windows snap to each other when" " they're moved near another window.") ); OverlapSnap=new QCheckBox(i18n("Snap windows onl&y when overlapping"),MagicBox); QWhatsThis::add( OverlapSnap, i18n("Here you can set that windows will be only" " snapped if you try to overlap them, i.e. they will not be snapped if the windows" " comes only near another window or border.") ); lay->addWidget(MagicBox); lay->addStretch(); load(); // Any changes goes to slotChanged() connect( opaque, SIGNAL(clicked()), SLOT(changed())); connect( resizeOpaqueOn, SIGNAL(clicked()), SLOT(changed())); connect( geometryTipOn, SIGNAL(clicked()), SLOT(changed())); connect( minimizeAnimOn, SIGNAL(clicked() ), SLOT(changed())); connect( minimizeAnimSlider, SIGNAL(valueChanged(int)), SLOT(changed())); connect( moveResizeMaximized, SIGNAL(toggled(bool)), SLOT(changed())); connect( placementCombo, SIGNAL(activated(int)), SLOT(changed())); connect( BrdrSnap, SIGNAL(valueChanged(int)), SLOT(changed())); connect( WndwSnap, SIGNAL(valueChanged(int)), SLOT(changed())); connect( OverlapSnap, SIGNAL(clicked()), SLOT(changed())); } int KMovingConfig::getMove() { return (opaque->isChecked())? OPAQUE : TRANSPARENT; } void KMovingConfig::setMove(int trans) { opaque->setChecked(trans == OPAQUE); } void KMovingConfig::setGeometryTip(bool showGeometryTip) { geometryTipOn->setChecked(showGeometryTip); } bool KMovingConfig::getGeometryTip() { return geometryTipOn->isChecked(); } // placement policy --- CT 31jan98 --- int KMovingConfig::getPlacement() { return placementCombo->currentItem(); } void KMovingConfig::setPlacement(int plac) { placementCombo->setCurrentItem(plac); } bool KMovingConfig::getMinimizeAnim() { return minimizeAnimOn->isChecked(); } int KMovingConfig::getMinimizeAnimSpeed() { return minimizeAnimSlider->value(); } void KMovingConfig::setMinimizeAnim(bool anim) { minimizeAnimOn->setChecked( anim ); minimizeAnimSlider->setEnabled( anim ); minimizeAnimSlowLabel->setEnabled( anim ); minimizeAnimFastLabel->setEnabled( anim ); } void KMovingConfig::setMinimizeAnimSpeed(int speed) { minimizeAnimSlider->setValue(speed); } int KMovingConfig::getResizeOpaque() { return (resizeOpaqueOn->isChecked())? RESIZE_OPAQUE : RESIZE_TRANSPARENT; } void KMovingConfig::setResizeOpaque(int opaque) { resizeOpaqueOn->setChecked(opaque == RESIZE_OPAQUE); } void KMovingConfig::setMoveResizeMaximized(bool a) { moveResizeMaximized->setChecked(a); } void KMovingConfig::load( void ) { QString key; config->setGroup( "Windows" ); key = config->readEntry(KWIN_MOVE, "Opaque"); if( key == "Transparent") setMove(TRANSPARENT); else if( key == "Opaque") setMove(OPAQUE); //CT 17Jun1998 - variable animation speed from 0 (none!!) to 10 (max) bool anim = config->readBoolEntry(KWIN_MINIMIZE_ANIM, true ); int animSpeed = config->readNumEntry(KWIN_MINIMIZE_ANIM_SPEED, 5); if( animSpeed < 1 ) animSpeed = 0; if( animSpeed > 10 ) animSpeed = 10; setMinimizeAnim( anim ); setMinimizeAnimSpeed( animSpeed ); // DF: please keep the default consistent with kwin (options.cpp line 145) key = config->readEntry(KWIN_RESIZE_OPAQUE, "Opaque"); if( key == "Opaque") setResizeOpaque(RESIZE_OPAQUE); else if ( key == "Transparent") setResizeOpaque(RESIZE_TRANSPARENT); //KS 10Jan2003 - Geometry Tip during window move/resize bool showGeomTip = config->readBoolEntry(KWIN_GEOMETRY, false); setGeometryTip( showGeomTip ); // placement policy --- CT 19jan98 --- key = config->readEntry(KWIN_PLACEMENT); //CT 13mar98 interactive placement // if( key.left(11) == "interactive") { // setPlacement(INTERACTIVE_PLACEMENT); // int comma_pos = key.find(','); // if (comma_pos < 0) // interactiveTrigger->setValue(0); // else // interactiveTrigger->setValue (key.right(key.length() // - comma_pos).toUInt(0)); // iTLabel->setEnabled(true); // interactiveTrigger->show(); // } // else { // interactiveTrigger->setValue(0); // iTLabel->setEnabled(false); // interactiveTrigger->hide(); if( key == "Random") setPlacement(RANDOM_PLACEMENT); else if( key == "Cascade") setPlacement(CASCADE_PLACEMENT); //CT 31jan98 //CT 31mar98 manual placement else if( key == "manual") setPlacement(MANUAL_PLACEMENT); else if( key == "Centered") setPlacement(CENTERED_PLACEMENT); else if( key == "ZeroCornered") setPlacement(ZEROCORNERED_PLACEMENT); else setPlacement(SMART_PLACEMENT); // } setMoveResizeMaximized(config->readBoolEntry(KWIN_MOVE_RESIZE_MAXIMIZED, false)); int v; v = config->readNumEntry(KWM_BRDR_SNAP_ZONE, KWM_BRDR_SNAP_ZONE_DEFAULT); if (v > MAX_BRDR_SNAP) setBorderSnapZone(MAX_BRDR_SNAP); else if (v < 0) setBorderSnapZone (0); else setBorderSnapZone(v); v = config->readNumEntry(KWM_WNDW_SNAP_ZONE, KWM_WNDW_SNAP_ZONE_DEFAULT); if (v > MAX_WNDW_SNAP) setWindowSnapZone(MAX_WNDW_SNAP); else if (v < 0) setWindowSnapZone (0); else setWindowSnapZone(v); OverlapSnap->setChecked(config->readBoolEntry("SnapOnlyWhenOverlapping",false)); emit KCModule::changed(false); } void KMovingConfig::save( void ) { int v; config->setGroup( "Windows" ); v = getMove(); if (v == TRANSPARENT) config->writeEntry(KWIN_MOVE,"Transparent"); else config->writeEntry(KWIN_MOVE,"Opaque"); config->writeEntry(KWIN_GEOMETRY, getGeometryTip()); // placement policy --- CT 31jan98 --- v =getPlacement(); if (v == RANDOM_PLACEMENT) config->writeEntry(KWIN_PLACEMENT, "Random"); else if (v == CASCADE_PLACEMENT) config->writeEntry(KWIN_PLACEMENT, "Cascade"); else if (v == CENTERED_PLACEMENT) config->writeEntry(KWIN_PLACEMENT, "Centered"); else if (v == ZEROCORNERED_PLACEMENT) config->writeEntry(KWIN_PLACEMENT, "ZeroCornered"); //CT 13mar98 manual and interactive placement // else if (v == MANUAL_PLACEMENT) // config->writeEntry(KWIN_PLACEMENT, "Manual"); // else if (v == INTERACTIVE_PLACEMENT) { // QString tmpstr = QString("Interactive,%1").arg(interactiveTrigger->value()); // config->writeEntry(KWIN_PLACEMENT, tmpstr); // } else config->writeEntry(KWIN_PLACEMENT, "Smart"); config->writeEntry(KWIN_MINIMIZE_ANIM, getMinimizeAnim()); config->writeEntry(KWIN_MINIMIZE_ANIM_SPEED, getMinimizeAnimSpeed()); v = getResizeOpaque(); if (v == RESIZE_OPAQUE) config->writeEntry(KWIN_RESIZE_OPAQUE, "Opaque"); else config->writeEntry(KWIN_RESIZE_OPAQUE, "Transparent"); config->writeEntry(KWIN_MOVE_RESIZE_MAXIMIZED, moveResizeMaximized->isChecked()); config->writeEntry(KWM_BRDR_SNAP_ZONE,getBorderSnapZone()); config->writeEntry(KWM_WNDW_SNAP_ZONE,getWindowSnapZone()); config->writeEntry("SnapOnlyWhenOverlapping",OverlapSnap->isChecked()); if (standAlone) { config->sync(); if ( !kapp->dcopClient()->isAttached() ) kapp->dcopClient()->attach(); kapp->dcopClient()->send("kwin*", "", "reconfigure()", ""); } emit KCModule::changed(false); } void KMovingConfig::defaults() { setMove(OPAQUE); setResizeOpaque(RESIZE_TRANSPARENT); setGeometryTip(false); setPlacement(SMART_PLACEMENT); setMoveResizeMaximized(false); //copied from kcontrol/konq/kwindesktop, aleXXX setWindowSnapZone(KWM_WNDW_SNAP_ZONE_DEFAULT); setBorderSnapZone(KWM_BRDR_SNAP_ZONE_DEFAULT); OverlapSnap->setChecked(false); setMinimizeAnim( true ); setMinimizeAnimSpeed( 5 ); emit KCModule::changed(true); } int KMovingConfig::getBorderSnapZone() { return BrdrSnap->value(); } void KMovingConfig::setBorderSnapZone(int pxls) { BrdrSnap->setValue(pxls); } int KMovingConfig::getWindowSnapZone() { return WndwSnap->value(); } void KMovingConfig::setWindowSnapZone(int pxls) { WndwSnap->setValue(pxls); } KTranslucencyConfig::~KTranslucencyConfig () { if (standAlone) delete config; if (kompmgr) kompmgr->detach(); } KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, KConfig *_config, QWidget *parent, const char *) : KCModule(parent, "kcmkwm"), config(_config), standAlone(_standAlone) { kompmgr = 0L; resetKompmgr_ = FALSE; QVBoxLayout *lay = new QVBoxLayout (this); kompmgrAvailable_ = kompmgrAvailable(); if (!kompmgrAvailable_){ KActiveLabel *label = new KActiveLabel(i18n("It seems that alpha channel support is not available.

" "Please make sure you have " "Xorg ≥ 6.8," " and installed the kompmgr that came with kwin.
" "Also, make sure you have the following entries in your XConfig (e.g. /etc/X11/xorg.conf):

" "Section \"Extensions\"
" "Option \"Composite\" \"Enable\"
" "EndSection


" "And if your GPU provides hardware-accelerated Xrender support (mainly nVidia cards):

" "Option \"RenderAccel\" \"true\"
" "In Section \"Device\"
"), this); lay->addWidget(label); } else { QTabWidget *tabW = new QTabWidget(this); QWidget *tGroup = new QWidget(tabW); QVBoxLayout *vLay = new QVBoxLayout (tGroup,KDialog::marginHint(), KDialog::spacingHint()); vLay->addSpacing(11); // to get the proper gb top offset QHBoxLayout *hLay = new QHBoxLayout(vLay); QLabel *label0 = new QLabel(i18n("Apply translucency on"),tGroup); hLay->addWidget(label0); transMode = new QComboBox(tGroup); transMode->insertItem (i18n("The whole window")); transMode->insertItem (i18n("The titlebar only")); transMode->insertItem (i18n("The content only")); hLay->addWidget(transMode); hLay->addStretch(); vLay->addSpacing(11); QGridLayout *gLay = new QGridLayout(vLay,4,2,KDialog::spacingHint()); gLay->setColStretch(1,1); activeWindowTransparency = new QCheckBox(i18n("Active windows:"),tGroup); gLay->addWidget(activeWindowTransparency,0,0); activeWindowOpacity = new KIntNumInput(100, tGroup); activeWindowOpacity->setRange(0,100); activeWindowOpacity->setSuffix("%"); gLay->addWidget(activeWindowOpacity,0,1); inactiveWindowTransparency = new QCheckBox(i18n("Inactive windows:"),tGroup); gLay->addWidget(inactiveWindowTransparency,1,0); inactiveWindowOpacity = new KIntNumInput(100, tGroup); inactiveWindowOpacity->setRange(0,100); inactiveWindowOpacity->setSuffix("%"); gLay->addWidget(inactiveWindowOpacity,1,1); movingWindowTransparency = new QCheckBox(i18n("Moving windows:"),tGroup); gLay->addWidget(movingWindowTransparency,2,0); movingWindowOpacity = new KIntNumInput(100, tGroup); movingWindowOpacity->setRange(0,100); movingWindowOpacity->setSuffix("%"); gLay->addWidget(movingWindowOpacity,2,1); dockWindowTransparency = new QCheckBox(i18n("Dock windows:"),tGroup); gLay->addWidget(dockWindowTransparency,3,0); dockWindowOpacity = new KIntNumInput(100, tGroup); dockWindowOpacity->setRange(0,100); dockWindowOpacity->setSuffix("%"); gLay->addWidget(dockWindowOpacity,3,1); vLay->addSpacing(11); keepAboveAsActive = new QCheckBox(i18n("Treat 'keep above' windows as active ones"),tGroup); vLay->addWidget(keepAboveAsActive); disableARGB = new QCheckBox(i18n("Disable ARGB windows (ignores window alpha maps, fixes gtk1 apps)"),tGroup); vLay->addWidget(disableARGB); vLay->addStretch(); tabW->addTab(tGroup, i18n("Opacity")); QWidget *sGroup = new QWidget(tabW); // sGroup->setCheckable(TRUE); QVBoxLayout *vLay2 = new QVBoxLayout (sGroup,11,6); vLay2->addSpacing(11); // to get the proper gb top offset useShadows = new QCheckBox(i18n("Use shadows"),sGroup); vLay2->addWidget(useShadows); vLay2->addSpacing(11); QGridLayout *gLay2 = new QGridLayout(vLay2,6,2); gLay2->setColStretch(1,1); QLabel *label1 = new QLabel(i18n("Active window size:"),sGroup); gLay2->addWidget(label1,0,0); activeWindowShadowSize = new KIntNumInput(12,sGroup); activeWindowShadowSize->setRange(0,32); // activeWindowShadowSize->setSuffix("px"); gLay2->addWidget(activeWindowShadowSize,0,1); QLabel *label2 = new QLabel(i18n("Inactive window size:"),sGroup); gLay2->addWidget(label2,1,0); inactiveWindowShadowSize = new KIntNumInput(6,sGroup); inactiveWindowShadowSize->setRange(0,32); // inactiveWindowShadowSize->setSuffix("px"); gLay2->addWidget(inactiveWindowShadowSize,1,1); QLabel *label3 = new QLabel(i18n("Dock window size:"),sGroup); gLay2->addWidget(label3,2,0); dockWindowShadowSize = new KIntNumInput(6,sGroup); dockWindowShadowSize->setRange(0,32); // dockWindowShadowSize->setSuffix("px"); gLay2->addWidget(dockWindowShadowSize,2,1); QLabel *label4 = new QLabel(i18n("Vertical offset:"),sGroup); gLay2->addWidget(label4,3,0); shadowTopOffset = new KIntNumInput(80,sGroup); shadowTopOffset->setSuffix("%"); shadowTopOffset->setRange(-200,200); gLay2->addWidget(shadowTopOffset,3,1); QLabel *label5 = new QLabel(i18n("Horizontal offset:"),sGroup); gLay2->addWidget(label5,4,0); shadowLeftOffset = new KIntNumInput(0,sGroup); shadowLeftOffset->setSuffix("%"); shadowLeftOffset->setRange(-200,200); gLay2->addWidget(shadowLeftOffset,4,1); QLabel *label6 = new QLabel(i18n("Shadow color:"),sGroup); gLay2->addWidget(label6,5,0); shadowColor = new KColorButton(Qt::black,sGroup); gLay2->addWidget(shadowColor,5,1); gLay2->setColStretch(1,1); vLay2->addSpacing(11); removeShadowsOnMove = new QCheckBox(i18n("Remove shadows on move"),sGroup); vLay2->addWidget(removeShadowsOnMove); removeShadowsOnResize = new QCheckBox(i18n("Remove shadows on resize"),sGroup); vLay2->addWidget(removeShadowsOnResize); vLay2->addStretch(); tabW->addTab(sGroup, i18n("Shadows")); QWidget *eGroup = new QWidget(this); QVBoxLayout *vLay3 = new QVBoxLayout (eGroup,11,6); fadeInWindows = new QCheckBox(i18n("Fade-in windows (including popups)"),eGroup); fadeOnOpacityChange = new QCheckBox(i18n("Fade between opacity changes"),eGroup); fadeInSpeed = new KIntNumInput(100, eGroup); fadeInSpeed->setRange(1,100); fadeInSpeed->setLabel("Fade-in speed:"); fadeOutSpeed = new KIntNumInput(100, eGroup); fadeOutSpeed->setRange(1,100); fadeOutSpeed->setLabel("Fade-out speed:"); vLay3->addWidget(fadeInWindows); vLay3->addWidget(fadeOnOpacityChange); vLay3->addWidget(fadeInSpeed); vLay3->addWidget(fadeOutSpeed); vLay3->addStretch(); tabW->addTab(eGroup, i18n("Effects")); useTranslucency = new QCheckBox(i18n("Use translucency/shadows"),this); lay->addWidget(useTranslucency); lay->addWidget(tabW); connect(useTranslucency, SIGNAL(toggled(bool)), tabW, SLOT(setEnabled(bool))); connect(activeWindowTransparency, SIGNAL(toggled(bool)), activeWindowOpacity, SLOT(setEnabled(bool))); connect(inactiveWindowTransparency, SIGNAL(toggled(bool)), inactiveWindowOpacity, SLOT(setEnabled(bool))); connect(movingWindowTransparency, SIGNAL(toggled(bool)), movingWindowOpacity, SLOT(setEnabled(bool))); connect(dockWindowTransparency, SIGNAL(toggled(bool)), dockWindowOpacity, SLOT(setEnabled(bool))); connect(useTranslucency, SIGNAL(toggled(bool)), SLOT(changed())); connect(transMode, SIGNAL(activated(int)), SLOT(changed())); connect(activeWindowTransparency, SIGNAL(toggled(bool)), SLOT(changed())); connect(inactiveWindowTransparency, SIGNAL(toggled(bool)), SLOT(changed())); connect(movingWindowTransparency, SIGNAL(toggled(bool)), SLOT(changed())); connect(dockWindowTransparency, SIGNAL(toggled(bool)), SLOT(changed())); connect(keepAboveAsActive, SIGNAL(toggled(bool)), SLOT(changed())); connect(disableARGB, SIGNAL(toggled(bool)), SLOT(changed())); connect(useShadows, SIGNAL(toggled(bool)), SLOT(changed())); connect(removeShadowsOnResize, SIGNAL(toggled(bool)), SLOT(changed())); connect(removeShadowsOnMove, SIGNAL(toggled(bool)), SLOT(changed())); connect(activeWindowOpacity, SIGNAL(valueChanged(int)), SLOT(changed())); connect(inactiveWindowOpacity, SIGNAL(valueChanged(int)), SLOT(changed())); connect(movingWindowOpacity, SIGNAL(valueChanged(int)), SLOT(changed())); connect(dockWindowOpacity, SIGNAL(valueChanged(int)), SLOT(changed())); connect(dockWindowShadowSize, SIGNAL(valueChanged(int)), SLOT(changed())); connect(activeWindowShadowSize, SIGNAL(valueChanged(int)), SLOT(changed())); connect(inactiveWindowShadowSize, SIGNAL(valueChanged(int)), SLOT(changed())); connect(shadowTopOffset, SIGNAL(valueChanged(int)), SLOT(changed())); connect(shadowLeftOffset, SIGNAL(valueChanged(int)), SLOT(changed())); connect(shadowColor, SIGNAL(changed(const QColor&)), SLOT(changed())); connect(fadeInWindows, SIGNAL(toggled(bool)), SLOT(changed())); connect(fadeOnOpacityChange, SIGNAL(toggled(bool)), SLOT(changed())); connect(fadeInSpeed, SIGNAL(valueChanged(int)), SLOT(changed())); connect(fadeOutSpeed, SIGNAL(valueChanged(int)), SLOT(changed())); connect(useShadows, SIGNAL(toggled(bool)), dockWindowShadowSize, SLOT(setEnabled(bool))); connect(useShadows, SIGNAL(toggled(bool)), activeWindowShadowSize, SLOT(setEnabled(bool))); connect(useShadows, SIGNAL(toggled(bool)), inactiveWindowShadowSize, SLOT(setEnabled(bool))); connect(useShadows, SIGNAL(toggled(bool)), shadowTopOffset, SLOT(setEnabled(bool))); connect(useShadows, SIGNAL(toggled(bool)), shadowLeftOffset, SLOT(setEnabled(bool))); connect(useShadows, SIGNAL(toggled(bool)), shadowColor, SLOT(setEnabled(bool))); load(); tabW->setEnabled(useTranslucency->isChecked()); connect(useTranslucency, SIGNAL(toggled(bool)), this, SLOT(showWarning(bool))); // handle kompmgr restarts if necessary connect(useTranslucency, SIGNAL(toggled(bool)), SLOT(resetKompmgr())); connect(transMode, SIGNAL(activated(int)), SLOT(resetKompmgr())); connect(disableARGB, SIGNAL(toggled(bool)), SLOT(resetKompmgr())); connect(useShadows, SIGNAL(toggled(bool)), SLOT(resetKompmgr())); connect(inactiveWindowShadowSize, SIGNAL(valueChanged(int)), SLOT(resetKompmgr())); connect(shadowTopOffset, SIGNAL(valueChanged(int)), SLOT(resetKompmgr())); connect(shadowLeftOffset, SIGNAL(valueChanged(int)), SLOT(resetKompmgr())); connect(shadowColor, SIGNAL(changed(const QColor&)), SLOT(resetKompmgr())); connect(fadeInWindows, SIGNAL(toggled(bool)), SLOT(resetKompmgr())); connect(fadeOnOpacityChange, SIGNAL(toggled(bool)), SLOT(resetKompmgr())); connect(fadeInSpeed, SIGNAL(valueChanged(int)), SLOT(resetKompmgr())); connect(fadeOutSpeed, SIGNAL(valueChanged(int)), SLOT(resetKompmgr())); } } void KTranslucencyConfig::resetKompmgr() { resetKompmgr_ = TRUE; } void KTranslucencyConfig::load( void ) { if (!kompmgrAvailable_) return; config->setGroup( "Notification Messages" ); useTranslucency->setChecked(config->readBoolEntry("UseTranslucency",false)); config->setGroup( "Translucency" ); activeWindowTransparency->setChecked(config->readBoolEntry("TranslucentActiveWindows",false)); inactiveWindowTransparency->setChecked(config->readBoolEntry("TranslucentInactiveWindows",true)); movingWindowTransparency->setChecked(config->readBoolEntry("TranslucentMovingWindows",false)); removeShadowsOnMove->setChecked(config->readBoolEntry("RemoveShadowsOnMove",FALSE)); removeShadowsOnResize->setChecked(config->readBoolEntry("RemoveShadowsOnResize",FALSE)); dockWindowTransparency->setChecked(config->readBoolEntry("TranslucentDocks",true)); keepAboveAsActive->setChecked(config->readBoolEntry("TreatKeepAboveAsActive",true)); activeWindowOpacity->setValue(config->readNumEntry("ActiveWindowOpacity",100)); inactiveWindowOpacity->setValue(config->readNumEntry("InactiveWindowOpacity",75)); movingWindowOpacity->setValue(config->readNumEntry("MovingWindowOpacity",25)); dockWindowOpacity->setValue(config->readNumEntry("DockOpacity",80)); int ass, iss, dss; dss = config->readNumEntry("DockShadowSize", 50); ass = config->readNumEntry("ActiveWindowShadowSize", 200); iss = config->readNumEntry("InactiveWindowShadowSize", 100); activeWindowOpacity->setEnabled(activeWindowTransparency->isChecked()); inactiveWindowOpacity->setEnabled(inactiveWindowTransparency->isChecked()); movingWindowOpacity->setEnabled(movingWindowTransparency->isChecked()); dockWindowOpacity->setEnabled(dockWindowTransparency->isChecked()); KConfig conf_(QDir::homeDirPath() + "/.xcompmgrrc"); conf_.setGroup("xcompmgr"); QString modeString = conf_.readEntry("TransMode","All"); transMode->setCurrentItem(!modeString.compare("Content")?2:!modeString.compare("Title")?1:0); disableARGB->setChecked(conf_.readBoolEntry("DisableARGB",FALSE)); useShadows->setChecked(conf_.readEntry("Compmode","CompClientShadows").compare("CompClientShadows") == 0); shadowTopOffset->setValue(-1*(conf_.readNumEntry("ShadowOffsetY",-80))); shadowLeftOffset->setValue(-1*(conf_.readNumEntry("ShadowOffsetX",0))); int ss = conf_.readNumEntry("ShadowRadius",6); dockWindowShadowSize->setValue((int)(dss*ss/100.0)); activeWindowShadowSize->setValue((int)(ass*ss/100.0)); inactiveWindowShadowSize->setValue((int)(iss*ss/100.0)); QString hex = conf_.readEntry("ShadowColor","#000000"); uint r, g, b; r = g = b = 256; if (sscanf(hex.latin1(), "0x%02x%02x%02x", &r, &g, &b)!=3 || r > 255 || g > 255 || b > 255) shadowColor->setColor(Qt::black); else shadowColor->setColor(QColor(r,g,b)); fadeInWindows->setChecked(conf_.readBoolEntry("FadeWindows",TRUE)); fadeOnOpacityChange->setChecked(conf_.readBoolEntry("FadeTrans",FALSE)); fadeInSpeed->setValue((int)(conf_.readDoubleNumEntry("FadeInStep",0.020)*1000.0)); fadeOutSpeed->setValue((int)(conf_.readDoubleNumEntry("FadeOutStep",0.070)*1000.0)); emit KCModule::changed(false); } void KTranslucencyConfig::save( void ) { if (!kompmgrAvailable_) return; config->setGroup( "Notification Messages" ); config->writeEntry("UseTranslucency",useTranslucency->isChecked()); config->setGroup( "Translucency" ); config->writeEntry("TranslucentActiveWindows",activeWindowTransparency->isChecked()); config->writeEntry("TranslucentInactiveWindows",inactiveWindowTransparency->isChecked()); config->writeEntry("TranslucentMovingWindows",movingWindowTransparency->isChecked()); config->writeEntry("TranslucentDocks",dockWindowTransparency->isChecked()); config->writeEntry("TreatKeepAboveAsActive",keepAboveAsActive->isChecked()); config->writeEntry("ActiveWindowOpacity",activeWindowOpacity->value()); config->writeEntry("InactiveWindowOpacity",inactiveWindowOpacity->value()); config->writeEntry("MovingWindowOpacity",movingWindowOpacity->value()); config->writeEntry("DockOpacity",dockWindowOpacity->value()); // for simplification: // xcompmgr supports a general shadow radius and additionally lets external apps set a multiplicator for each window // (speed reasons, so the shadow matrix hasn't to be recreated for every window) // we set inactive windows to 100%, the radius to the inactive window value and adjust the multiplicators for docks and active windows // this way the user can set the three values without caring about the radius/multiplicator stuff config->writeEntry("DockShadowSize",(int)(100.0*dockWindowShadowSize->value()/inactiveWindowShadowSize->value())); config->writeEntry("ActiveWindowShadowSize",(int)(100.0*activeWindowShadowSize->value()/inactiveWindowShadowSize->value())); config->writeEntry("InctiveWindowShadowSize",100); config->writeEntry("RemoveShadowsOnMove",removeShadowsOnMove->isChecked()); config->writeEntry("RemoveShadowsOnResize",removeShadowsOnResize->isChecked()); config->writeEntry("ResetKompmgr",resetKompmgr_); KConfig *conf_ = new KConfig(QDir::homeDirPath() + "/.xcompmgrrc"); conf_->setGroup("xcompmgr"); conf_->writeEntry("Compmode",useShadows->isChecked()?"CompClientShadows":""); conf_->writeEntry("DisableARGB",disableARGB->isChecked()); conf_->writeEntry("ShadowOffsetY",-1*shadowTopOffset->value()); conf_->writeEntry("ShadowOffsetX",-1*shadowLeftOffset->value()); conf_->writeEntry("TransMode",transMode->currentItem()==0?"All":transMode->currentItem()==1?"Title":"Content"); int r, g, b; shadowColor->color().rgb( &r, &g, &b ); QString hex; hex.sprintf("0x%02X%02X%02X", r,g,b); conf_->writeEntry("ShadowColor",hex); conf_->writeEntry("ShadowRadius",inactiveWindowShadowSize->value()); conf_->writeEntry("FadeWindows",fadeInWindows->isChecked()); conf_->writeEntry("FadeTrans",fadeOnOpacityChange->isChecked()); conf_->writeEntry("FadeInStep",fadeInSpeed->value()/1000.0); conf_->writeEntry("FadeOutStep",fadeOutSpeed->value()/1000.0); delete conf_; if (standAlone) { config->sync(); if ( !kapp->dcopClient()->isAttached() ) kapp->dcopClient()->attach(); kapp->dcopClient()->send("kwin*", "", "reconfigure()", ""); } emit KCModule::changed(false); } void KTranslucencyConfig::defaults() { if (!kompmgrAvailable_) return; useTranslucency->setChecked(false); transMode->setCurrentItem(0); activeWindowTransparency->setChecked(false); inactiveWindowTransparency->setChecked(true); movingWindowTransparency->setChecked(false); dockWindowTransparency->setChecked(true); keepAboveAsActive->setChecked(true); disableARGB->setChecked(false); activeWindowOpacity->setValue(100); inactiveWindowOpacity->setValue(75); movingWindowOpacity->setValue(25); dockWindowOpacity->setValue(80); dockWindowShadowSize->setValue(6); activeWindowShadowSize->setValue(12); inactiveWindowShadowSize->setValue(6); shadowTopOffset->setValue(80); shadowLeftOffset->setValue(0); activeWindowOpacity->setEnabled(false); inactiveWindowOpacity->setEnabled(true); movingWindowOpacity->setEnabled(false); dockWindowOpacity->setEnabled(true); useShadows->setChecked(TRUE); removeShadowsOnMove->setChecked(FALSE); removeShadowsOnResize->setChecked(FALSE); shadowColor->setColor(Qt::black); fadeInWindows->setChecked(TRUE); fadeOnOpacityChange->setChecked(FALSE); fadeInSpeed->setValue(70); fadeOutSpeed->setValue(20); emit KCModule::changed(true); } bool KTranslucencyConfig::kompmgrAvailable() { bool ret; KProcess proc; proc << "kompmgr" << "-v"; ret = proc.start(KProcess::DontCare, KProcess::AllOutput); proc.detach(); return ret; } void KTranslucencyConfig::showWarning(bool alphaActivated) { if (alphaActivated) KMessageBox::information(this, i18n("Translucency support is new and may cause problems
including crashes (sometimes the translucency engine, seldom even X).
"), i18n("Warning")); } #include "windows.moc" diff --git a/notifications.cpp b/notifications.cpp index ce1ea7e9d..53a804c3e 100644 --- a/notifications.cpp +++ b/notifications.cpp @@ -1,95 +1,121 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 1999, 2000 Matthias Ettrich Copyright (C) 2003 Lubos Lunak You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #include "notifications.h" #include +#include "client.h" + namespace KWinInternal { -void Notify::raise( Event e ) +QString Notify::eventToName( Event e ) { - static bool forgetIt = FALSE; - if ( forgetIt ) - return; // no connection was possible, don't try each time - QString event; switch ( e ) { case Activate: event = "activate"; break; case Close: event = "close"; break; case Minimize: event = "minimize"; break; case UnMinimize: event = "unminimize"; break; case Maximize: event = "maximize"; break; case UnMaximize: event = "unmaximize"; break; case OnAllDesktops: event = "on_all_desktops"; break; case NotOnAllDesktops: event = "not_on_all_desktops"; break; case New: event = "new"; break; case Delete: event = "delete"; break; case TransNew: event = "transnew"; break; case TransDelete: event = "transdelete"; break; case ShadeUp: event = "shadeup"; break; case ShadeDown: event = "shadedown"; break; case MoveStart: event = "movestart"; break; case MoveEnd: event = "moveend"; break; case ResizeStart: event = "resizestart"; break; case ResizeEnd: event = "resizeend"; break; + case DemandAttentionCurrent: + event = "demandsattentioncurrent"; + break; + case DemandAttentionOther: + event = "demandsattentionother"; + break; default: if ((e > DesktopChange) && (e <= DesktopChange+20)) { event = QString("desktop%1").arg(e-DesktopChange); } break; } + return event; + } +bool Notify::raise( Event e, const QString& message, Client* c ) + { + static bool forgetIt = FALSE; + if ( forgetIt ) + return false; // no connection was possible, don't try each time + + QString event = eventToName( e ); if ( !event ) - return; + return false; + + forgetIt= !KNotifyClient::event( c ? c->window() : 0, event, message ); - forgetIt= !KNotifyClient::event( 0, event, event ); + return !forgetIt; + } + +bool Notify::makeDemandAttention( Event e ) + { + QString event = eventToName( e ); + if( !event ) + return false; + int rep = KNotifyClient::getPresentation( event ); + if( rep == -1 ) + rep = KNotifyClient::getDefaultPresentation( event ); + return rep != -1 && ( rep & KNotifyClient::Taskbar ); } } // namespace diff --git a/notifications.h b/notifications.h index b8fe4c733..478d15a6a 100644 --- a/notifications.h +++ b/notifications.h @@ -1,50 +1,60 @@ /***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 1999, 2000 Matthias Ettrich Copyright (C) 2003 Lubos Lunak You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #ifndef KWIN_NOTIFICATIONS_H #define KWIN_NOTIFICATIONS_H +#include +#include + namespace KWinInternal { +class Client; + class Notify { public: enum Event { Activate, Close, Minimize, UnMinimize, Maximize, UnMaximize, OnAllDesktops, NotOnAllDesktops, New, Delete, TransNew, TransDelete, ShadeUp, ShadeDown, MoveStart, MoveEnd, ResizeStart, ResizeEnd, + DemandAttentionCurrent, + DemandAttentionOther, DesktopChange = 100 }; - static void raise( Event ); + static bool raise( Event, const QString& message = QString::null, Client* c = NULL ); + static bool makeDemandAttention( Event ); + private: + static QString eventToName( Event ); }; } // namespace #endif