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