Revert last revert, dynamic keybidings are back in.

svn path=/trunk/kdebase/kwin/; revision=377118
This commit is contained in:
Luboš Luňák 2005-01-10 09:56:21 +00:00
parent 3c2a0ee242
commit 65c3b55e05
15 changed files with 245 additions and 50 deletions

View file

@ -215,11 +215,8 @@ void Workspace::setActiveClient( Client* c, allowed_t )
{
if ( active_client == c )
return;
if( popup && popup_client != c && set_active_client_recursion == 0 )
{
popup->close();
popup_client = 0;
}
if( active_popup && active_popup_client != c && set_active_client_recursion == 0 )
closeActivePopup();
StackingUpdatesBlocker blocker( this );
++set_active_client_recursion;
if( active_client != NULL )
@ -391,8 +388,7 @@ bool Workspace::activateNextClient( Client* c )
if( !( c == active_client
|| ( should_get_focus.count() > 0 && c == should_get_focus.last())))
return false;
if( popup )
popup->close();
closeActivePopup();
if( c != NULL )
{
if( c == active_client )
@ -836,6 +832,11 @@ void Client::updateUrgency()
demandAttention();
}
void Client::shortcutActivated()
{
workspace()->activateClient( this, true ); // force
}
//****************************************
// Group
//****************************************

View file

@ -18,6 +18,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include <netwm.h>
#include <kdebug.h>
#include <assert.h>
#include <kshortcut.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -210,6 +211,8 @@ class Client : public QObject, public KDecorationDefines
void shrinkVertical();
bool providesContextHelp() const;
KShortcut shortcut() const;
void setShortcut( const KShortcut& cut );
bool performMouseCommand( Options::MouseCommand, QPoint globalPos, bool handled = false );
@ -278,6 +281,7 @@ class Client : public QObject, public KDecorationDefines
private slots:
void autoRaise();
void shadeHover();
void shortcutActivated();
private:
friend class Bridge; // FRAME
@ -495,6 +499,7 @@ class Client : public QObject, public KDecorationDefines
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;
@ -839,6 +844,19 @@ inline Window Client::moveResizeGrabWindow() const
return move_resize_grab_window;
}
inline KShortcut Client::shortcut() const
{
return _shortcut;
}
inline void Client::setShortcut( const KShortcut& cut )
{
if( _shortcut == cut )
return;
_shortcut = cut;
workspace()->clientShortcutUpdated( this );
}
#ifdef NDEBUG
inline
kndbgstream& operator<<( kndbgstream& stream, const Client* ) { return stream; }

View file

@ -24,6 +24,7 @@
#include <kwin.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qcheckbox.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
@ -137,10 +138,7 @@ QString DetectDialog::selectedTitle() const
Rules::StringMatch DetectDialog::titleMatch() const
{
#if KDE_IS_VERSION( 3, 3, 90 )
#warning Offer possibilities here
#endif
return Rules::UnimportantMatch;
return widget->match_title->isChecked() ? Rules::ExactMatch : Rules::UnimportantMatch;
}
bool DetectDialog::selectedWholeApp() const

View file

@ -12,6 +12,9 @@
<height>325</height>
</rect>
</property>
<property name="caption">
<string>Form3</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
@ -201,6 +204,17 @@
<string>With some (non-KDE) applications whole window class can be sufficient for selecting a specific window in an application, as they set whole window class to contain both application and window role.</string>
</property>
</widget>
<widget class="QCheckBox">
<property name="name">
<cstring>match_title</cstring>
</property>
<property name="text">
<string>Match also window &amp;title</string>
</property>
<property name="accel">
<string>Alt+T</string>
</property>
</widget>
</vbox>
</widget>
</grid>

View file

@ -57,6 +57,7 @@
DEF2( "Window Below Other Windows", I18N_NOOP("Keep Window Below Others"),
0, 0, slotWindowBelow() );
DEF( I18N_NOOP("Activate Window Demanding Attention"), CTRL+ALT+Qt::Key_A, 0, slotActivateAttentionWindow());
DEF( I18N_NOOP("Setup Window Shortcut"), 0, 0, slotSetupWindowShortcut());
DEF2( "Window Pack Left", I18N_NOOP("Pack Window to the Left"),
0, 0, slotWindowPackLeft() );
DEF2( "Window Pack Right", I18N_NOOP("Pack Window to the Right"),

View file

@ -97,7 +97,8 @@ public:
LowerOp,
FullScreenOp,
NoBorderOp,
NoOp
NoOp,
SetupWindowShortcutOp
};
/**
* Basic color types that should be recognized by all decoration styles.

View file

@ -131,6 +131,10 @@ bool Client::manage( Window w, bool isMapped )
if( session->userNoBorder )
setUserNoBorder( true );
}
if( session && !session->shortcut.isNull())
setShortcut( session->shortcut );
// TODO use also rules for shortcut
init_minimize = rules()->checkMinimize( init_minimize, !isMapped );
if( rules()->checkNoBorder( false, !isMapped ))

2
sm.cpp
View file

@ -113,6 +113,7 @@ void Workspace::storeSession( KConfig* config, SMSavePhase phase )
config->writeEntry( QString("skipPager")+n, c->skipPager() );
config->writeEntry( QString("userNoBorder")+n, c->isUserNoBorder() );
config->writeEntry( QString("windowType")+n, windowTypeToTxt( c->windowType()));
config->writeEntry( QString("shortcut")+n, c->shortcut().toStringInternal());
}
}
// TODO store also stacking order
@ -177,6 +178,7 @@ void Workspace::loadSessionInfo()
info->skipPager = config->readBoolEntry( QString("skipPager")+n, FALSE );
info->userNoBorder = config->readBoolEntry( QString("userNoBorder")+n, FALSE );
info->windowType = txtToWindowType( config->readEntry( QString("windowType")+n ).latin1());
info->shortcut = KShortcut( config->readEntry( QString("shortcut")+n ));
info->active = ( active_client == i );
}
}

2
sm.h
View file

@ -15,6 +15,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include <X11/SM/SMlib.h>
#include <kapplication.h>
#include <netwm_def.h>
#include <kshortcut.h>
class QSocketNotifier;
@ -45,6 +46,7 @@ struct SessionInfo
bool skipPager;
bool userNoBorder;
NET::WindowType windowType;
KShortcut shortcut;
bool active; // means 'was active in the saved session'
};

View file

@ -844,6 +844,7 @@ bool Workspace::startKDEWalkThroughWindows()
return false;
tab_grab = TRUE;
keys->setEnabled( false );
client_keys->setEnabled( false );
tab_box->setMode( TabBox::WindowsMode );
tab_box->reset();
return TRUE;
@ -855,6 +856,7 @@ bool Workspace::startWalkThroughDesktops( int mode )
return false;
control_grab = TRUE;
keys->setEnabled( false );
client_keys->setEnabled( false );
tab_box->setMode( (TabBox::Mode) mode );
tab_box->reset();
return TRUE;
@ -1006,6 +1008,7 @@ void Workspace::closeTabBox()
removeTabBoxGrab();
tab_box->hide();
keys->setEnabled( true );
client_keys->setEnabled( true );
tab_grab = FALSE;
control_grab = FALSE;
}
@ -1053,6 +1056,7 @@ void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
removeTabBoxGrab();
tab_box->hide();
keys->setEnabled( true );
client_keys->setEnabled( true );
tab_grab = false;
if( Client* c = tab_box->currentClient())
{
@ -1066,6 +1070,7 @@ void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
removeTabBoxGrab();
tab_box->hide();
keys->setEnabled( true );
client_keys->setEnabled( true );
control_grab = False;
if ( tab_box->currentDesktop() != -1 )
{

View file

@ -61,6 +61,8 @@ QPopupMenu* Workspace::clientPopup()
advanced_popup->insertItem( SmallIconSet( "window_fullscreen" ),
i18n("&Fullscreen")+'\t'+keys->shortcut("Window Fullscreen").seq(0).toString(), Options::FullScreenOp );
advanced_popup->insertItem( i18n("&No Border")+'\t'+keys->shortcut("Window No Border").seq(0).toString(), Options::NoBorderOp );
advanced_popup->insertItem( SmallIconSet("key_bindings"),
i18n("Window &Shortcut...")+'\t'+keys->shortcut("Setup Window Shortcut").seq(0).toString(), Options::SetupWindowShortcutOp );
advanced_popup->insertItem( SmallIconSet( "filesave" ), i18n("&Special Window Settings..."), Options::WindowRulesOp );
popup->insertItem(i18n("Ad&vanced"), advanced_popup );
@ -92,7 +94,7 @@ QPopupMenu* Workspace::clientPopup()
*/
void Workspace::clientPopupAboutToShow()
{
if ( !popup_client || !popup )
if ( !active_popup_client || !popup )
return;
if ( numberOfDesktops() == 1 )
@ -105,21 +107,21 @@ void Workspace::clientPopupAboutToShow()
initDesktopPopup();
}
popup->setItemEnabled( Options::ResizeOp, popup_client->isResizable() );
popup->setItemEnabled( Options::MoveOp, popup_client->isMovable() );
popup->setItemEnabled( Options::MaximizeOp, popup_client->isMaximizable() );
popup->setItemChecked( Options::MaximizeOp, popup_client->maximizeMode() == Client::MaximizeFull );
popup->setItemEnabled( Options::ResizeOp, active_popup_client->isResizable() );
popup->setItemEnabled( Options::MoveOp, active_popup_client->isMovable() );
popup->setItemEnabled( Options::MaximizeOp, active_popup_client->isMaximizable() );
popup->setItemChecked( Options::MaximizeOp, active_popup_client->maximizeMode() == Client::MaximizeFull );
// This should be checked also when hover unshaded
popup->setItemChecked( Options::ShadeOp, popup_client->shadeMode() != ShadeNone );
popup->setItemEnabled( Options::ShadeOp, popup_client->isShadeable());
advanced_popup->setItemChecked( Options::KeepAboveOp, popup_client->keepAbove() );
advanced_popup->setItemChecked( Options::KeepBelowOp, popup_client->keepBelow() );
advanced_popup->setItemChecked( Options::FullScreenOp, popup_client->isFullScreen() );
advanced_popup->setItemEnabled( Options::FullScreenOp, popup_client->userCanSetFullScreen() );
advanced_popup->setItemChecked( Options::NoBorderOp, popup_client->noBorder() );
advanced_popup->setItemEnabled( Options::NoBorderOp, popup_client->userCanSetNoBorder() );
popup->setItemEnabled( Options::MinimizeOp, popup_client->isMinimizable() );
popup->setItemEnabled( Options::CloseOp, popup_client->isCloseable() );
popup->setItemChecked( Options::ShadeOp, active_popup_client->shadeMode() != ShadeNone );
popup->setItemEnabled( Options::ShadeOp, active_popup_client->isShadeable());
advanced_popup->setItemChecked( Options::KeepAboveOp, active_popup_client->keepAbove() );
advanced_popup->setItemChecked( Options::KeepBelowOp, active_popup_client->keepBelow() );
advanced_popup->setItemChecked( Options::FullScreenOp, active_popup_client->isFullScreen() );
advanced_popup->setItemEnabled( Options::FullScreenOp, active_popup_client->userCanSetFullScreen() );
advanced_popup->setItemChecked( Options::NoBorderOp, active_popup_client->noBorder() );
advanced_popup->setItemEnabled( Options::NoBorderOp, active_popup_client->userCanSetNoBorder() );
popup->setItemEnabled( Options::MinimizeOp, active_popup_client->isMinimizable() );
popup->setItemEnabled( Options::CloseOp, active_popup_client->isCloseable() );
}
@ -173,7 +175,15 @@ void Workspace::desktopPopupAboutToShow()
}
}
void Workspace::closeActivePopup()
{
if( active_popup )
{
active_popup->close();
active_popup = NULL;
active_popup_client = NULL;
}
}
/*!
Create the global accel object \c keys.
@ -204,10 +214,59 @@ void Workspace::readShortcuts()
}
void Workspace::setupWindowShortcut( Client* c )
{
assert( client_keys_dialog == NULL );
keys->setEnabled( false );
client_keys->setEnabled( false );
client_keys_dialog = new ShortcutDialog( c->shortcut());
client_keys_client = c;
connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
QRect r = clientArea( ScreenArea, c );
QSize size = client_keys_dialog->sizeHint();
QPoint pos = c->pos() + c->clientPos();
if( pos.x() + size.width() >= r.right())
pos.setX( r.right() - size.width());
if( pos.y() + size.height() >= r.bottom())
pos.setY( r.bottom() - size.height());
client_keys_dialog->move( pos );
client_keys_dialog->show();
active_popup = client_keys_dialog;
active_popup_client = c;
}
void Workspace::setupWindowShortcutDone( bool ok )
{
keys->setEnabled( true );
client_keys->setEnabled( true );
if( ok )
{
client_keys_client->setShortcut( client_keys_dialog->shortcut());
}
closeActivePopup();
delete client_keys_dialog;
client_keys_dialog = NULL;
client_keys_client = NULL;
}
void Workspace::clientShortcutUpdated( Client* c )
{
QString key = QString::number( c->window());
client_keys->remove( key );
if( !c->shortcut().isNull())
{
client_keys->insert( key, key );
client_keys->setShortcut( key, c->shortcut());
client_keys->setSlot( key, c, SLOT( shortcutActivated()));
client_keys->setActionEnabled( key, true );
}
client_keys->updateConnections();
}
void Workspace::clientPopupActivated( int id )
{
WindowOperation op = static_cast< WindowOperation >( id );
Client* c = popup_client ? popup_client : active_client;
Client* c = active_popup_client ? active_popup_client : active_client;
QString type;
switch( op )
{
@ -288,6 +347,9 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
case Options::WindowRulesOp:
editWindowRules( c );
break;
case Options::SetupWindowShortcutOp:
setupWindowShortcut( c );
break;
case Options::LowerOp:
lowerClient(c);
break;
@ -607,6 +669,11 @@ void Workspace::slotWindowBelow()
if( active_client )
performWindowOperation( active_client, Options::KeepBelowOp );
}
void Workspace::slotSetupWindowShortcut()
{
if( active_client )
performWindowOperation( active_client, Options::SetupWindowShortcutOp );
}
/*!
Move window to next desktop
@ -721,15 +788,15 @@ void Workspace::slotKillWindow()
*/
void Workspace::slotSendToDesktop( int desk )
{
if ( !popup_client )
if ( !active_popup_client )
return;
if ( desk == 0 )
{ // the 'on_all_desktops' menu entry
popup_client->setOnAllDesktops( !popup_client->isOnAllDesktops());
active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
return;
}
sendClientToDesktop( popup_client, desk, false );
sendClientToDesktop( active_popup_client, desk, false );
}
@ -750,29 +817,30 @@ void Workspace::showWindowMenu( const QRect &pos, Client* cl )
return;
if( !cl )
return;
if( popup_client != NULL ) // recursion
if( active_popup_client != NULL ) // recursion
return;
if ( cl->isDesktop()
|| cl->isDock()
|| cl->isTopMenu())
return;
popup_client = cl;
active_popup_client = cl;
QPopupMenu* p = clientPopup();
active_popup = p;
int x = pos.left();
int y = pos.bottom();
if (y == pos.top()) {
if (y == pos.top())
p->exec( QPoint( x, y ) );
} else {
else
{
QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
int popupHeight = p->sizeHint().height();
if (y + popupHeight < area.height()) {
if (y + popupHeight < area.height())
p->exec( QPoint( x, y ) );
} else {
else
p->exec( QPoint( x, pos.top() - popupHeight ) );
}
}
popup_client = 0;
}
closeActivePopup();
}
/*!

View file

@ -304,6 +304,50 @@ bool isLocalMachine( const QCString& host )
return false;
}
#ifndef KCMRULES
ShortcutDialog::ShortcutDialog( const KShortcut& cut )
: KShortcutDialog( cut, false /*TODO???*/ )
{
// make it a popup, so that it has the grab
XSetWindowAttributes attrs;
attrs.override_redirect = True;
XChangeWindowAttributes( qt_xdisplay(), winId(), CWOverrideRedirect, &attrs );
setWFlags( WType_Popup );
}
void ShortcutDialog::accept()
{
for( int i = 0;
;
++i )
{
KKeySequence seq = shortcut().seq( i );
if( seq.isNull())
break;
if( seq.key( 0 ) == Key_Escape )
{
reject();
return;
}
if( seq.key( 0 ) == Key_Space )
{ // clear
setShortcut( KShortcut());
KShortcutDialog::accept();
return;
}
if( seq.key( 0 ).modFlags() == 0 )
{ // no shortcuts without modifiers
KShortcut cut = shortcut();
cut.setSeq( i, KKeySequence());
setShortcut( cut );
return;
}
}
KShortcutDialog::accept();
}
#endif
} // namespace
#ifndef KCMRULES

19
utils.h
View file

@ -16,6 +16,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include <qwidget.h>
#include <kmanagerselection.h>
#include <netwm_def.h>
#include <kshortcutdialog.h>
namespace KWinInternal
{
@ -242,7 +243,23 @@ Time timestampDiff( Time time1, Time time2 ) // returns time2 - time1
}
bool isLocalMachine( const QCString& host );
#ifndef KCMRULES
// Qt dialogs emit no signal when closed :(
class ShortcutDialog
: public KShortcutDialog
{
Q_OBJECT
public:
ShortcutDialog( const KShortcut& cut );
virtual void accept();
signals:
void dialogDone( bool ok );
protected:
virtual void done( int r ) { KShortcutDialog::done( r ); emit dialogDone( r == Accepted ); }
};
#endif
} // namespace
#endif

View file

@ -64,7 +64,8 @@ Workspace::Workspace( bool restore )
QObject (0, "workspace"),
current_desktop (0),
number_of_desktops(0),
popup_client (0),
active_popup( NULL ),
active_popup_client( NULL ),
desktop_widget (0),
temporaryRulesMessages( "_KDE_NET_WM_TEMPORARY_RULES", NULL, false ),
active_client (0),
@ -86,6 +87,9 @@ Workspace::Workspace( bool restore )
desk_popup (0),
desk_popup_index (0),
keys (0),
client_keys ( NULL ),
client_keys_dialog ( NULL ),
client_keys_client ( NULL ),
root (0),
workspaceInit (true),
startup(0), electric_have_borders(false),
@ -171,6 +175,7 @@ Workspace::Workspace( bool restore )
1
);
client_keys = new KGlobalAccel( this );
initShortcuts();
tab_box = new TabBox( this );
popupinfo = new PopupInfo( );
@ -425,6 +430,7 @@ Workspace::~Workspace()
delete topmenu_watcher;
delete topmenu_selection;
delete topmenu_space;
delete client_keys_dialog;
while( !rules.isEmpty())
{
delete rules.front();
@ -493,10 +499,13 @@ void Workspace::addClient( Client* c, allowed_t )
*/
void Workspace::removeClient( Client* c, allowed_t )
{
if (c == active_client && popup)
popup->close();
if( c == popup_client )
popup_client = 0;
if (c == active_popup_client)
closeActivePopup();
if( client_keys_client == c )
setupWindowShortcutDone( false );
if( !c->shortcut().isNull())
c->setShortcut( KShortcut()); // remove from client_keys
if( c->isDialog())
Notify::raise( Notify::TransDelete );
@ -1013,8 +1022,7 @@ bool Workspace::setCurrentDesktop( int new_desktop )
if (new_desktop < 1 || new_desktop > number_of_desktops )
return false;
if( popup )
popup->close();
closeActivePopup();
++block_focus;
// TODO Q_ASSERT( block_stacking_updates == 0 ); // make sure stacking_order is up to date
StackingUpdatesBlocker blocker( this );

View file

@ -28,6 +28,7 @@ License. See the file "COPYING" for the exact licensing terms.
class QPopupMenu;
class KConfig;
class KGlobalAccel;
class KShortcutDialog;
class KStartupInfo;
class KStartupInfoId;
class KStartupInfoData;
@ -236,6 +237,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void focusToNull(); // SELI public?
bool forcedGlobalMouseGrab() const;
void clientShortcutUpdated( Client* c );
void sessionSaveStarted();
void sessionSaveDone();
@ -325,6 +327,9 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void slotGrabWindow();
void slotGrabDesktop();
void slotSetupWindowShortcut();
void setupWindowShortcutDone( bool );
void updateClientArea();
private slots:
@ -351,6 +356,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void initShortcuts();
void readShortcuts();
void initDesktopPopup();
void setupWindowShortcut( Client* c );
bool startKDEWalkThroughWindows();
bool startWalkThroughDesktops( int mode ); // TabBox::Mode::DesktopMode | DesktopListMode
@ -425,6 +431,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void calcDesktopLayout(int &x, int &y) const;
QPopupMenu* clientPopup();
void closeActivePopup();
void updateClientArea( bool force );
@ -434,7 +441,8 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
int number_of_desktops;
QMemArray<int> desktop_focus_chain;
Client* popup_client;
QWidget* active_popup;
Client* active_popup_client;
QWidget* desktop_widget;
@ -498,6 +506,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
int desk_popup_index;
KGlobalAccel *keys;
KGlobalAccel *client_keys;
KShortcutDialog* client_keys_dialog;
Client* client_keys_client;
WId root;
PluginMgr *mgr;