1 /****************************************************************************
5 Copyright (C) 1999-2001 Lubos Lunak <l.lunak@kde.org>
7 Distributed under the terms of the GNU General Public License version 2.
9 ****************************************************************************/
20 #include <kconfiggroup.h>
22 #include <kwindowsystem.h>
25 #include "khotkeysglobal.h"
28 #include <X11/Xutil.h>
36 Windows::Windows( bool enable_signal_P
, QObject
* parent_P
)
37 : QObject( parent_P
), signals_enabled( enable_signal_P
),
42 connect( KWindowSystem::self(), SIGNAL( windowAdded( WId
)), SLOT( window_added_slot( WId
)));
43 connect( KWindowSystem::self(), SIGNAL( windowRemoved( WId
)), SLOT( window_removed_slot( WId
)));
44 connect( KWindowSystem::self(), SIGNAL( activeWindowChanged( WId
)),
45 SLOT( active_window_changed_slot( WId
)));
53 void Windows::window_added_slot( WId window_P
)
56 emit
window_added( window_P
);
57 // CHECKME tyhle i dalsi by asi mely jit nastavit, jestli aktivuji vsechny, nebo jen jeden
58 // pripojeny slot ( stejne jako u Kdb, kde by to take melo jit nastavit )
61 void Windows::window_removed_slot( WId window_P
)
64 emit
window_removed( window_P
);
65 if( window_P
== _action_window
)
69 void Windows::active_window_changed_slot( WId window_P
)
72 emit
active_window_changed( window_P
);
75 void Windows::window_changed_slot( WId window_P
)
78 emit
window_changed( window_P
);
81 void Windows::window_changed_slot( WId window_P
, unsigned int flags_P
)
84 emit
window_changed( window_P
, flags_P
);
87 QString
Windows::get_window_role( WId id_P
)
89 // TODO this is probably just a hack
90 return KWindowSystem::windowInfo( id_P
, 0, NET::WM2WindowRole
).windowRole();
93 QString
Windows::get_window_class( WId id_P
)
96 if( XGetClassHint( QX11Info::display(), id_P
, &hints_ret
) == 0 ) // 0 means error
98 QString
ret( hints_ret
.res_name
);
100 ret
+= hints_ret
.res_class
;
101 XFree( hints_ret
.res_name
);
102 XFree( hints_ret
.res_class
);
106 WId
Windows::active_window()
108 return KWindowSystem::activeWindow();
111 WId
Windows::action_window()
113 return _action_window
;
116 void Windows::set_action_window( WId window_P
)
118 _action_window
= window_P
;
121 WId
Windows::find_window( const Windowdef_list
* window_P
)
123 for( QList
< WId
>::const_iterator it
= KWindowSystem::windows().begin();
124 it
!= KWindowSystem::windows().end();
127 Window_data
tmp( *it
);
128 if( window_P
->match( tmp
))
134 WId
Windows::window_at_position( int x
, int y
)
137 Window parent
= QX11Info::appRootWindow();
138 Atom wm_state
= XInternAtom( QX11Info::display(), "WM_STATE", False
);
144 // find child at that position
145 if( !XTranslateCoordinates( QX11Info::display(), parent
, parent
, x
, y
, &destx
, &desty
, &child
)
148 // and now transform coordinates to the child
149 if( !XTranslateCoordinates( QX11Info::display(), parent
, child
, x
, y
, &destx
, &desty
, &dummy
))
155 unsigned long nitems
, after
;
157 if( XGetWindowProperty( QX11Info::display(), child
, wm_state
, 0, 0, False
, AnyPropertyType
,
158 &type
, &format
, &nitems
, &after
, &prop
) == Success
)
171 void Windows::activate_window( WId id_P
)
173 KWindowSystem::forceActiveWindow( id_P
);
178 Window_data::Window_data( WId id_P
)
179 : type( NET::Unknown
)
181 KWindowInfo kwin_info
= KWindowSystem::windowInfo( id_P
, NET::WMName
| NET::WMWindowType
); // TODO optimize
182 if( kwin_info
.valid())
184 title
= kwin_info
.name();
185 role
= windows_handler
->get_window_role( id_P
);
186 wclass
= windows_handler
->get_window_class( id_P
);
187 type
= kwin_info
.windowType( SUPPORTED_WINDOW_TYPES_MASK
);
188 if( type
== NET::Override
) // HACK consider non-NETWM fullscreens to be normal too
190 if( type
== NET::Unknown
)
197 void Windowdef::cfg_write( KConfigGroup
& cfg_P
) const
199 cfg_P
.writeEntry( "Type", "ERROR" );
200 cfg_P
.writeEntry( "Comment", comment());
203 Windowdef::Windowdef( KConfigGroup
& cfg_P
)
205 _comment
= cfg_P
.readEntry( "Comment" );
208 Windowdef
* Windowdef::create_cfg_read( KConfigGroup
& cfg_P
)
210 QString type
= cfg_P
.readEntry( "Type" );
211 if( type
== "SIMPLE" )
212 return new Windowdef_simple( cfg_P
);
213 kWarning() << "Unknown Windowdef type read from cfg file\n";
219 Windowdef_list::Windowdef_list( KConfigGroup
& cfg_P
)
220 : Q3PtrList
< Windowdef
>()
222 setAutoDelete( true );
223 _comment
= cfg_P
.readEntry( "Comment" );
224 int cnt
= cfg_P
.readEntry( "WindowsCount", 0 );
229 KConfigGroup
windowGroup( cfg_P
.config(), cfg_P
.name() + QString::number( i
));
230 Windowdef
* window
= Windowdef::create_cfg_read( windowGroup
);
236 void Windowdef_list::cfg_write( KConfigGroup
& cfg_P
) const
239 for( Iterator
it( *this );
243 KConfigGroup
itGroup( cfg_P
.config(), cfg_P
.name() + QString::number( i
) );
244 it
.current()->cfg_write( itGroup
);
246 cfg_P
.writeEntry( "WindowsCount", i
);
247 cfg_P
.writeEntry( "Comment", comment());
250 Windowdef_list
* Windowdef_list::copy() const
252 Windowdef_list
* ret
= new Windowdef_list( comment());
253 for( Iterator
it( *this );
256 ret
->append( it
.current()->copy());
261 bool Windowdef_list::match( const Window_data
& window_P
) const
263 if( count() == 0 ) // CHECKME no windows to match => ok
265 for( Iterator
it( *this );
268 if( it
.current()->match( window_P
))
275 Windowdef_simple::Windowdef_simple( const QString
& comment_P
, const QString
& title_P
,
276 substr_type_t title_type_P
, const QString
& wclass_P
, substr_type_t wclass_type_P
,
277 const QString
& role_P
, substr_type_t role_type_P
, int window_types_P
)
278 : Windowdef( comment_P
), _title( title_P
), title_type( title_type_P
),
279 _wclass( wclass_P
), wclass_type( wclass_type_P
), _role( role_P
),
280 role_type( role_type_P
), _window_types( window_types_P
)
284 Windowdef_simple::Windowdef_simple( KConfigGroup
& cfg_P
)
287 _title
= cfg_P
.readEntry( "Title" );
288 title_type
= static_cast< substr_type_t
>( cfg_P
.readEntry( "TitleType",0 ));
289 _wclass
= cfg_P
.readEntry( "Class" );
290 wclass_type
= static_cast< substr_type_t
>( cfg_P
.readEntry( "ClassType",0 ));
291 _role
= cfg_P
.readEntry( "Role" );
292 role_type
= static_cast< substr_type_t
>( cfg_P
.readEntry( "RoleType", 0 ));
293 _window_types
= cfg_P
.readEntry( "WindowTypes",0 );
296 void Windowdef_simple::cfg_write( KConfigGroup
& cfg_P
) const
298 base::cfg_write( cfg_P
);
299 cfg_P
.writeEntry( "Title", title());
300 cfg_P
.writeEntry( "TitleType", int(title_type
) );
301 cfg_P
.writeEntry( "Class", wclass());
302 cfg_P
.writeEntry( "ClassType", int(wclass_type
) );
303 cfg_P
.writeEntry( "Role", role());
304 cfg_P
.writeEntry( "RoleType", int(role_type
) );
305 cfg_P
.writeEntry( "WindowTypes", window_types());
306 cfg_P
.writeEntry( "Type", "SIMPLE" ); // overwrites value set in base::cfg_write()
309 bool Windowdef_simple::match( const Window_data
& window_P
)
311 if( !type_match( window_P
.type
))
313 if( !is_substr_match( window_P
.title
, title(), title_type
))
315 if( !is_substr_match( window_P
.wclass
, wclass(), wclass_type
))
317 if( !is_substr_match( window_P
.role
, role(), role_type
))
319 kDebug() << "window match:" << window_P
.title
<< ":OK";
323 bool Windowdef_simple::is_substr_match( const QString
& str1_P
, const QString
& str2_P
,
324 substr_type_t type_P
)
331 return str1_P
.contains( str2_P
) > 0;
333 return str1_P
== str2_P
;
336 QRegExp
rg( str2_P
);
337 return rg
.indexIn( str1_P
) >= 0;
340 return str1_P
.contains( str2_P
) == 0;
342 return str1_P
!= str2_P
;
345 QRegExp
rg( str2_P
);
346 return rg
.indexIn( str1_P
) < 0;
352 Windowdef
* Windowdef_simple::copy() const
354 return new Windowdef_simple( comment(), title(), title_match_type(), wclass(),
355 wclass_match_type(), role(), role_match_type(), window_types());
358 const QString
Windowdef_simple::description() const
360 return i18n( "Window simple: " ) + comment();
363 } // namespace KHotKeys
365 #include "windows.moc"