~and471/slickpanel/trunk

« back to all changes in this revision

Viewing changes to panel/items/windowlist/windowlist.vala

  • Committer: Andrew Higginson
  • Date: 2014-12-29 17:48:31 UTC
  • Revision ID: at.higginson@gmail.com-20141229174831-bukedaw8kny4aq8t
updating

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2010 Andrew Higginson
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or modify
 
4
 * it under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
*/
 
8
 
 
9
namespace SlickPanel {
 
10
 
 
11
private Wnck.Screen screen;
 
12
private Gdk.Screen gdk_screen;
 
13
 
 
14
public class WindowList : Item {
 
15
    
 
16
    private Gtk.Builder builder;
 
17
    private Gee.ArrayList<Wnck.Window> windows = new Gee.ArrayList<Wnck.Window>();
 
18
 
 
19
    public WindowList() {
 
20
        this.type_ = Settings.ItemType.WINDOW_LIST;
 
21
        this.widget = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
 
22
 
 
23
        screen = Wnck.Screen.get_default();
 
24
        gdk_screen = Gdk.Screen.get_default();
 
25
        screen.window_opened.connect(this.on_screen_window_opened);
 
26
        screen.window_closed.connect(this.on_screen_window_closed);
 
27
        screen.active_window_changed.connect(this.on_screen_active_window_changed);
 
28
        screen.active_workspace_changed.connect(this.on_active_workspace_changed);
 
29
        Timeout.add(100, (SourceFunc) this.on_workspace_checker_timeout);
 
30
    }
 
31
    
 
32
    
 
33
    public override void set_orientation(Gtk.Orientation orientation) {
 
34
        var box = new Gtk.Box(orientation, 0);
 
35
        box.set_homogeneous(true);
 
36
        
 
37
        foreach (var window in this.windows) {
 
38
            var button = this.get_button_for_window(window);
 
39
            (this.widget as Gtk.Box).remove(button);
 
40
            box.pack_start(button, false, false);
 
41
        }
 
42
        this.widget = box;
 
43
        this.pack_widget();
 
44
    }
 
45
    
 
46
    public override void set_settings(Settings.Item item_settings) {
 
47
        //do something
 
48
    }
 
49
 
 
50
    /* Private Functions */
 
51
    private void update_window_buttons() {
 
52
        foreach (var window in this.windows) {
 
53
            if (!this.window_should_be_shown(window)) {
 
54
                var button = this.get_button_for_window(window);
 
55
                if (button != null) {
 
56
                    (this.widget as Gtk.Box).remove(button);
 
57
                    button.destroy();
 
58
                }
 
59
            } else if (this.get_button_for_window(window) == null) {
 
60
                this.add_window_button(window);
 
61
            }
 
62
        }
 
63
    }
 
64
    
 
65
    private WindowButton? get_button_for_window(Wnck.Window window) {
 
66
        foreach (var widget in (this.widget as Gtk.Box).get_children()) {
 
67
            var button = widget as WindowButton;
 
68
            if (button.window == window) {
 
69
                return button;
 
70
            }
 
71
        }
 
72
        return null;
 
73
    }
 
74
    
 
75
    private bool window_should_be_shown(Wnck.Window window) {
 
76
        bool show_in_tasklist = !window.is_skip_tasklist();
 
77
        bool in_same_workspace = window.get_workspace() == screen.get_active_workspace();
 
78
        if (screen.get_active_workspace() == null) {
 
79
            in_same_workspace = true;
 
80
        }
 
81
        bool in_same_monitor = true;
 
82
        
 
83
        if (gdk_screen.get_n_monitors() > 1) {
 
84
            int x, y, width, height;
 
85
            window.get_geometry(out x, out y, out width, out height);
 
86
            
 
87
            var panel_monitor = gdk_screen.get_monitor_at_window(this.widget.get_window());
 
88
            var window_monitor = gdk_screen.get_monitor_at_point(x+(width/2), y+(height /2));
 
89
            
 
90
            if (panel_monitor != window_monitor) {
 
91
                in_same_monitor = false;
 
92
            }
 
93
        }
 
94
        
 
95
        return (show_in_tasklist && in_same_workspace && in_same_monitor);
 
96
    }
 
97
    
 
98
    private void add_window_button(Wnck.Window window) {
 
99
        var button = new WindowButton(window);
 
100
        button.window = window;
 
101
 
 
102
        (this.widget as Gtk.Box).pack_start(button, false, false);
 
103
        button.show();
 
104
        
 
105
        this.update_window_icon_geometries();
 
106
    }
 
107
    
 
108
    private void add_window(Wnck.Window window) {
 
109
        this.add_window_button(window);
 
110
    }
 
111
    
 
112
    private void remove_window(Wnck.Window window) {
 
113
        var button = this.get_button_for_window(window);
 
114
        if (button != null) {
 
115
            (this.widget as Gtk.Box).remove(button);
 
116
            button.destroy();
 
117
            this.update_window_icon_geometries();
 
118
        }
 
119
    }
 
120
    
 
121
    /* Callbacks */
 
122
 
 
123
    private void on_screen_window_opened(Wnck.Window window) {
 
124
        this.windows.add(window);
 
125
        bool window_should_be_shown = this.window_should_be_shown(window);
 
126
        if (window_should_be_shown) {
 
127
            this.add_window(window);
 
128
        } else {
 
129
            this.remove_window(window);
 
130
        }
 
131
        window.workspace_changed.connect(this.on_window_workspace_changed);
 
132
        window.geometry_changed.connect(this.on_window_geometry_changed);
 
133
        window.name_changed.connect(this.on_window_name_changed);
 
134
    }
 
135
    
 
136
    private void on_screen_window_closed(Wnck.Window window) {
 
137
        this.windows.remove(window);
 
138
        window.workspace_changed.disconnect(this.on_window_workspace_changed);
 
139
        window.geometry_changed.disconnect(this.on_window_geometry_changed);
 
140
        window.name_changed.disconnect(this.on_window_name_changed);
 
141
        this.remove_window(window);
 
142
    }
 
143
    
 
144
    private void on_window_geometry_changed(Wnck.Window window) {
 
145
        bool window_should_be_shown = this.window_should_be_shown(window);
 
146
        bool prev_window_should_be_shown = this.get_button_for_window(window) != null;
 
147
        
 
148
        if (window_should_be_shown != prev_window_should_be_shown) {
 
149
            if (window_should_be_shown) {
 
150
                this.add_window(window);
 
151
            } else {
 
152
                this.remove_window(window);
 
153
            }
 
154
        }
 
155
    }
 
156
    
 
157
    private void on_screen_active_window_changed(Wnck.Window? previous_active_window) {
 
158
        if (previous_active_window != null) {
 
159
            var button_previous_active = this.get_button_for_window(previous_active_window);
 
160
            if (button_previous_active != null) {
 
161
                button_previous_active.unset_state_flags(Gtk.StateFlags.SELECTED);
 
162
            }
 
163
        }
 
164
    
 
165
        var active_window = screen.get_active_window();
 
166
        if (active_window != null) {
 
167
            var button = this.get_button_for_window(active_window);
 
168
            if (button != null) {
 
169
                button.set_state_flags(Gtk.StateFlags.SELECTED, false);
 
170
            }
 
171
        }
 
172
    }
 
173
    
 
174
    private void on_window_name_changed(Wnck.Window window) {
 
175
        var button = this.get_button_for_window(window);
 
176
        if (button != null) {
 
177
            button.label.set_text(window.get_name());
 
178
        }
 
179
    }
 
180
    
 
181
    private void on_window_workspace_changed(Wnck.Window window) {
 
182
        bool window_should_be_shown = this.window_should_be_shown(window);
 
183
        bool prev_window_should_be_shown = this.get_button_for_window(window) != null;
 
184
        
 
185
        if (window_should_be_shown != prev_window_should_be_shown) {
 
186
            if (window_should_be_shown) {
 
187
                this.add_window(window);
 
188
            } else {
 
189
                this.remove_window(window);
 
190
            }
 
191
        }
 
192
    }
 
193
    
 
194
    private void on_active_workspace_changed() {
 
195
        this.update_window_buttons();
 
196
    }
 
197
 
 
198
    private bool on_workspace_checker_timeout() {
 
199
        if (screen.get_active_workspace() == null) {
 
200
            return true;
 
201
        } else {
 
202
            this.update_window_buttons();
 
203
            return false;
 
204
        }
 
205
    }
 
206
    
 
207
    private void update_window_icon_geometries() {
 
208
        foreach (var child in (this.widget as Gtk.Box).get_children()) {
 
209
            var button = child as WindowButton;
 
210
            Gtk.Allocation allocation;
 
211
            button.get_allocation(out allocation);
 
212
            
 
213
            int x, y, width, height;
 
214
            button.get_parent_window().get_origin(out x, out y);
 
215
            
 
216
            x += allocation.x;
 
217
            y += allocation.y;
 
218
            width = allocation.width;
 
219
            height = allocation.height;
 
220
            
 
221
            Log.info("(%d, %d)  %d x %d".printf(x, y, width, height));
 
222
            button.window.set_icon_geometry(x, y, width, height);
 
223
        }
 
224
    }
 
225
 
 
226
    /* Public Functions */
 
227
    public override bool set_xml_property(string name, string value) {
 
228
        bool handled = base.set_xml_property(name, value);
 
229
        if (handled) {
 
230
            return true;
 
231
        }
 
232
        switch (name) {
 
233
            case "ellipsis":
 
234
                return true;
 
235
            default:
 
236
                return false;
 
237
        }
 
238
    }
 
239
}
 
240
}