main.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <kcmdlineargs.h>
00020 #include <kapplication.h>
00021 #include <dcopclient.h>
00022 #include <kconfig.h>
00023 #include <klocale.h>
00024 #include <kwin.h>
00025
00026 #include <X11/Xlib.h>
00027 #include <fixx11h.h>
00028
00029 #include "ruleswidget.h"
00030 #include "../../rules.h"
00031
00032 namespace KWinInternal
00033 {
00034
00035 static void loadRules( QValueList< Rules* >& rules )
00036 {
00037 KConfig cfg( "kwinrulesrc", true );
00038 cfg.setGroup( "General" );
00039 int count = cfg.readNumEntry( "count" );
00040 for( int i = 1;
00041 i <= count;
00042 ++i )
00043 {
00044 cfg.setGroup( QString::number( i ));
00045 Rules* rule = new Rules( cfg );
00046 rules.append( rule );
00047 }
00048 }
00049
00050 static void saveRules( const QValueList< Rules* >& rules )
00051 {
00052 KConfig cfg( "kwinrulesrc" );
00053 cfg.setGroup( "General" );
00054 cfg.writeEntry( "count", rules.count());
00055 int i = 1;
00056 for( QValueList< Rules* >::ConstIterator it = rules.begin();
00057 it != rules.end();
00058 ++it )
00059 {
00060 cfg.setGroup( QString::number( i ));
00061 (*it)->write( cfg );
00062 ++i;
00063 }
00064 }
00065
00066 static Rules* findRule( const QValueList< Rules* >& rules, Window wid )
00067 {
00068 KWin::WindowInfo info = KWin::windowInfo( wid,
00069 NET::WMName | NET::WMWindowType,
00070 NET::WM2WindowClass | NET::WM2WindowRole | NET::WM2ClientMachine );
00071 if( !info.valid())
00072 return NULL;
00073 QCString wmclass_class = info.windowClassClass().lower();
00074 QCString wmclass_name = info.windowClassName().lower();
00075 QCString role = info.windowRole().lower();
00076 NET::WindowType type = info.windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask
00077 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00078 | NET::UtilityMask | NET::SplashMask );
00079 QString title = info.name().lower();
00080
00081 QCString machine = info.clientMachine().lower();
00082 Rules* best_match = NULL;
00083 int match_quality = 0;
00084 for( QValueList< Rules* >::ConstIterator it = rules.begin();
00085 it != rules.end();
00086 ++it )
00087 {
00088
00089 Rules* rule = *it;
00090 int quality = 0;
00091 bool generic = true;
00092 if( rule->wmclassmatch != Rules::ExactMatch )
00093 continue;
00094 if( !rule->matchWMClass( wmclass_class, wmclass_name ))
00095 continue;
00096
00097 if( rule->wmclasscomplete )
00098 {
00099 quality += 1;
00100 generic = false;
00101 }
00102 if( rule->windowrolematch != Rules::UnimportantMatch )
00103 {
00104 quality += rule->windowrolematch == Rules::ExactMatch ? 5 : 1;
00105 generic = false;
00106 }
00107 if( rule->titlematch != Rules::UnimportantMatch )
00108 {
00109 quality += rule->titlematch == Rules::ExactMatch ? 3 : 1;
00110 generic = false;
00111 }
00112 if( rule->types != NET::AllTypesMask )
00113 {
00114 int bits = 0;
00115 for( int bit = 1;
00116 bit < 1 << 31;
00117 bit <<= 1 )
00118 if( rule->types & bit )
00119 ++bits;
00120 if( bits == 1 )
00121 quality += 2;
00122 }
00123 if( generic )
00124 continue;
00125 if( !rule->matchType( type )
00126 || !rule->matchRole( role )
00127 || !rule->matchTitle( title )
00128 || !rule->matchClientMachine( machine ))
00129 continue;
00130 if( quality > match_quality )
00131 {
00132 best_match = rule;
00133 match_quality = quality;
00134 }
00135 }
00136 return best_match;
00137 }
00138
00139 static int edit( Window wid )
00140 {
00141 QValueList< Rules* > rules;
00142 loadRules( rules );
00143 Rules* orig_rule = findRule( rules, wid );
00144 RulesDialog dlg;
00145
00146 Rules* edited_rule = dlg.edit( orig_rule, wid );
00147 if( edited_rule == NULL )
00148 return 0;
00149 if( edited_rule->isEmpty())
00150 {
00151 if( orig_rule == NULL )
00152 {
00153 delete edited_rule;
00154 return 0;
00155 }
00156 else
00157 {
00158 rules.remove( orig_rule );
00159 delete orig_rule;
00160 delete edited_rule;
00161 }
00162 }
00163 else if( edited_rule != orig_rule )
00164 {
00165 QValueList< Rules* >::Iterator pos = rules.find( orig_rule );
00166 if( pos != rules.end())
00167 *pos = edited_rule;
00168 else
00169 rules.prepend( edited_rule );
00170 delete orig_rule;
00171 }
00172 saveRules( rules );
00173 if( !kapp->dcopClient()->isAttached())
00174 kapp->dcopClient()->attach();
00175 kapp->dcopClient()->send("kwin*", "", "reconfigure()", "");
00176 return 0;
00177 }
00178
00179 }
00180
00181 static const KCmdLineOptions options[] =
00182 {
00183
00184 { "wid <wid>", "WId of the window for special window settings.", 0 },
00185 KCmdLineLastOption
00186 };
00187
00188 extern "C"
00189 int kdemain( int argc, char* argv[] )
00190 {
00191 KLocale::setMainCatalogue( "kcmkwinrules" );
00192 KCmdLineArgs::init( argc, argv, "kwin_rules_dialog", I18N_NOOP( "KWin" ),
00193 I18N_NOOP( "KWin helper utility" ), "1.0" );
00194 KCmdLineArgs::addCmdLineOptions( options );
00195 KApplication app;
00196 KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
00197 bool id_ok = false;
00198 Window id = args->getOption( "wid" ).toULong( &id_ok );
00199 args->clear();
00200 if( !id_ok || id == None )
00201 {
00202 KCmdLineArgs::usage( i18n( "This helper utility is not supposed to be called directly." ));
00203 return 1;
00204 }
00205 return KWinInternal::edit( id );
00206 }
This file is part of the documentation for kwin Library Version 3.3.0.