kwin Library API Documentation

main.cpp

00001 /* 00002 * Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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()) // shouldn't really happen 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 // QCString extrarole = ""; // TODO 00081 QCString machine = info.clientMachine().lower(); 00082 Rules* best_match = NULL; 00083 int match_quality = 0; // 0 - no, 1 - generic windowrole or title, 2 - exact match 00084 for( QValueList< Rules* >::ConstIterator it = rules.begin(); 00085 it != rules.end(); 00086 ++it ) 00087 { 00088 // try to find an exact match, i.e. not a generic rule 00089 Rules* rule = *it; 00090 int quality = 0; 00091 bool generic = true; 00092 if( rule->wmclassmatch != Rules::ExactMatch ) 00093 continue; // too generic 00094 if( !rule->matchWMClass( wmclass_class, wmclass_name )) 00095 continue; 00096 // from now on, it matches the app - now try to match for a specific window 00097 if( rule->wmclasscomplete ) 00098 { 00099 quality += 1; 00100 generic = false; // this can be considered specific enough (old X apps) 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 // dlg.edit() creates new Rules instance if edited 00146 Rules* edited_rule = dlg.edit( orig_rule, wid ); 00147 if( edited_rule == NULL ) // cancelled 00148 return 0; 00149 if( edited_rule->isEmpty()) 00150 { 00151 if( orig_rule == NULL ) 00152 { // new, without any settings 00153 delete edited_rule; 00154 return 0; 00155 } 00156 else 00157 { // removed all settings from already existing 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 } // namespace 00180 00181 static const KCmdLineOptions options[] = 00182 { 00183 // no need for I18N_NOOP(), this is not supposed to be used directly 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 }
KDE Logo
This file is part of the documentation for kwin Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 13 21:47:05 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003