~gestikk/gestikk/main

86 by Friedrich Weber
replaced wnck, netk stuff with netwm. that should work on nearly all window managers!
1
# -*- coding: utf-8 -*-
2
"""
3
    GESTIKK
4
    Version %%VERSION%%
5
6
    Gestikk, a mouse gesture recognition application
7
    Copyright (C) 2007-2008:
8
    Friedrich 'fred.reichbier' Weber, Jonas 'Dauerbaustelle' Haag
9
10
    This program is free software; you can redistribute it and/or
11
    modify it under the terms of the GNU General Public License
12
    as published by the Free Software Foundation; either version 2
13
    of the License, or (at your option) any later version.
14
15
    This program is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
20
    You should have received a copy of the GNU General Public License
21
    along with this program; if not, write to the Free Software
22
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23
"""
24
25
"""
26
    don't use wnck, don't use netk, WE USE NETWM!
27
    http://standards.freedesktop.org/wm-spec/wm-spec-latest.html
28
"""
29
30
import gtk
31
87 by Friedrich Weber
added user-friendly errors for window manager
32
class DesktopException(Exception):
33
    pass
34
86 by Friedrich Weber
replaced wnck, netk stuff with netwm. that should work on nearly all window managers!
35
def get_process_by_pid(pid):
36
    """ get a process name by its pid """
37
    try:
38
        f = file('/proc/%d/status' % pid, 'r')
39
    except IOError:
40
        return '<could not be recognized>'
41
    name = '<could not be recognized>'
42
    while 1:
43
        line = f.readline().lower()
44
        if line.startswith('name'):
45
            name = line[len('name:'):].strip()
46
            break
47
    return name
48
49
class NETWMHandler():
50
    def __init__(self):
51
        self.root = gtk.gdk.get_default_root_window()
87 by Friedrich Weber
added user-friendly errors for window manager
52
        supported = self.root.property_get('_NET_SUPPORTED')[2]
88 by Friedrich Weber
removed PID recommendation because xfce4 has it, but not listed in _NET_SUPPORTED
53
        for prop in ['_NET_ACTIVE_WINDOW', '_NET_WM_NAME', '_NET_CURRENT_DESKTOP']:
87 by Friedrich Weber
added user-friendly errors for window manager
54
            if prop not in supported:
55
                raise DesktopException('Your window manager does not support netwm feature "%s"!' % prop)
86 by Friedrich Weber
replaced wnck, netk stuff with netwm. that should work on nearly all window managers!
56
57
    def get_all(self):
58
        """ get a dict with all values """
59
        return {'activeApplication':self.get_active_app_name(), \
60
                'activeWorkspace':self.get_active_workspace_number(), \
61
                'activeWindowTitle':self.get_active_window_title()}
62
63
    def _get_active_window(self):
64
        """ return current window as gtk.gdk.Window() """
65
        return gtk.gdk.window_foreign_new(self.root.property_get('_NET_ACTIVE_WINDOW')[2][0])
66
67
    def _get_window_name(self, window):
68
        """ return the window name of the gtk.gdk.Window `window` """
89 by Friedrich Weber
added ICCCM for xfce4 support -.-
69
        try:
70
            return window.property_get('_NET_WM_NAME')[2]
71
        except TypeError:
90 by Friedrich Weber
more xfce4 compatibility - i hope
72
            try:
73
                return window.property_get('WM_NAME')[2]
74
            except TypeError:
75
                return window.property_get('WM_CLASS').split('\x00')[1].strip()
86 by Friedrich Weber
replaced wnck, netk stuff with netwm. that should work on nearly all window managers!
76
77
    def _get_window_pid(self, window):
78
        """ return the process id of the current window """
79
        return window.property_get('_NET_WM_PID')[2][0]
80
81
    def get_active_window_title(self):
82
        """ return the active window title as str """
83
        return self._get_window_name(self._get_active_window())
84
85
    def get_active_app_name(self):
86
        """ return the active application name as str """
89 by Friedrich Weber
added ICCCM for xfce4 support -.-
87
        pid = self._get_window_pid(self._get_active_window())
88
        if pid:
89
            return get_process_by_pid(pid)
90
        else: # use ICCCM
91
            cmd = self._get_active_window().property_get('WM_CLASS')
92
            if cmd:
93
                return cmd[2].split('\x00')[0].strip()
86 by Friedrich Weber
replaced wnck, netk stuff with netwm. that should work on nearly all window managers!
94
95
    def get_active_workspace_number(self):
96
        """ return active workspace number starting at 1 """
97
        return self.root.property_get('_NET_CURRENT_DESKTOP')[2][0] + 1
98
        
87 by Friedrich Weber
added user-friendly errors for window manager
99
class Dummy():
100
    def __init__(self):
101
        pass
102
103
    def __getattr__(self):
104
        return ''
105
106
    def get_all(self):
107
        return {}