Merge lp:~skokec/dockbar/win7ish-feel into lp:dockbar

Proposed by skokec
Status: Needs review
Proposed branch: lp:~skokec/dockbar/win7ish-feel
Merge into: lp:dockbar
Diff against target: 1548 lines (+532/-292)
7 files modified
dbx_preference.py (+61/-6)
dockbarx/cairowidgets.py (+0/-1)
dockbarx/common.py (+31/-26)
dockbarx/dockbar.py (+8/-7)
dockbarx/groupbutton.py (+370/-181)
dockbarx/iconfactory.py (+7/-13)
dockbarx/windowbutton.py (+55/-58)
To merge this branch: bzr merge lp:~skokec/dockbar/win7ish-feel
Reviewer Review Type Date Requested Status
Dockbar Main Group Pending
Review via email: mp+29224@code.launchpad.net

Description of the change

Added some options that mimic some of the behavior of win7 taskbar.

To post a comment you must log in.

Unmerged revisions

234. By Domen Tabernik

Merged new options for more win7 feel.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dbx_preference.py'
2--- dbx_preference.py 2010-06-21 04:19:21 +0000
3+++ dbx_preference.py 2010-07-05 16:50:40 +0000
4@@ -1,4 +1,4 @@
5-#!/usr/bin/python
6+#!/usr/bin/python2.6
7
8 # dbx_preference.py
9 #
10@@ -274,6 +274,24 @@
11 table.attach(label, 0, 1, row, row + 1, xpadding = 5)
12 table.attach(self.wb_combos[text], 1, 2, row, row + 1 )
13
14+
15+ self.gb_close_popup_on_click_checkbutton_names = ['windowbutton_close_popup_on_left_click',
16+ 'windowbutton_close_popup_on_shift_and_left_click',
17+ 'windowbutton_close_popup_on_middle_click',
18+ 'windowbutton_close_popup_on_shift_and_middle_click',
19+ 'windowbutton_close_popup_on_right_click',
20+ 'windowbutton_close_popup_on_shift_and_right_click',
21+ 'windowbutton_close_popup_on_scroll_up',
22+ 'windowbutton_close_popup_on_scroll_down']
23+ self.gb_close_popup_on_click_checkbutton = {}
24+
25+ for i in range(len(self.gb_close_popup_on_click_checkbutton_names)):
26+ name = self.gb_close_popup_on_click_checkbutton_names[i]
27+ self.gb_close_popup_on_click_checkbutton[name] = gtk.CheckButton('Close popup on click')
28+
29+ self.gb_close_popup_on_click_checkbutton[name].connect('toggled', self.checkbutton_toggled, name)
30+ table.attach(self.gb_close_popup_on_click_checkbutton[name], 2, 3, i, i + 1, xpadding = 5 )
31+
32 hbox.pack_start(table, False)
33 frame.add(hbox)
34 windowbutton_box.pack_start(frame, False, padding=5)
35@@ -385,6 +403,11 @@
36 'no_popup_for_one_window')
37 popup_box.pack_start(self.no_popup_cb, False, padding=5)
38
39+ self.close_popup_on_click_cb = gtk.CheckButton('Close popup on any mouse click outside of focus (instead of when out of focus)')
40+ self.close_popup_on_click_cb.connect('toggled', self.checkbutton_toggled, 'close_popup_on_click')
41+ popup_box.pack_start(self.close_popup_on_click_cb, False, padding=5)
42+
43+
44 # Alignment
45 vbox = gtk.VBox()
46 label1 = gtk.Label("<b><big>%s</big></b>"%_("Alignment"))
47@@ -417,6 +440,17 @@
48 spinbox.pack_start(spinlabel, False)
49 spinbox.pack_start(self.delay_spin, False, padding=5)
50 vbox.pack_start(spinbox, False)
51+
52+ spinbox = gtk.HBox()
53+ spinlabel = gtk.Label("Second delay when already opened by first delay:")
54+ spinlabel.set_alignment(0,0.5)
55+ adj = gtk.Adjustment(0, 0, 2000, 1, 50)
56+ self.delay_second_spin = gtk.SpinButton(adj, 0.5, 0)
57+ adj.connect("value_changed", self.adjustment_changed, 'popup_delay_second')
58+ spinbox.pack_start(spinlabel, False)
59+ spinbox.pack_start(self.delay_second_spin, False, padding=5)
60+ vbox.pack_start(spinbox, False)
61+
62 popup_box.pack_start(vbox, False, padding=5)
63
64 # Previews
65@@ -440,7 +474,23 @@
66 vbox.pack_start(spinbox, False)
67 popup_box.pack_start(vbox, False, padding=5)
68
69-
70+ # On group button action
71+ vbox = gtk.VBox()
72+ label2 = gtk.Label("<b>When group button is executed action:</b>")
73+ label2.set_alignment(0,0.5)
74+ label2.set_use_markup(True)
75+ vbox.pack_start(label2,False)
76+
77+ self.disable_popup_on_gbbutton_click_cb = gtk.CheckButton('Disable popup delay if popup not opened')
78+ self.disable_popup_on_gbbutton_click_cb.connect('toggled', self.checkbutton_toggled, 'disable_popup_on_groupbutton_click')
79+ vbox.pack_start(self.disable_popup_on_gbbutton_click_cb, False)
80+
81+ self.close_popup_on_gbbutton_click_cb = gtk.CheckButton('Close popup if popup is opened (ignored on "show popup" action)')
82+ self.close_popup_on_gbbutton_click_cb.connect('toggled', self.checkbutton_toggled, 'close_popup_on_groupbutton_click')
83+ vbox.pack_start(self.close_popup_on_gbbutton_click_cb, False)
84+
85+ popup_box.pack_start(vbox, False, padding=5)
86+
87 #--- Groupbutton page
88 frame = gtk.Frame(_("Groupbutton actions"))
89 frame.set_border_width(5)
90@@ -759,8 +809,11 @@
91
92 # Popup
93 self.delay_spin.set_value(self.globals.settings['popup_delay'])
94- self.no_popup_cb.set_active(
95- self.globals.settings['no_popup_for_one_window'])
96+ self.delay_second_spin.set_value(self.globals.settings['popup_delay_second'])
97+ self.no_popup_cb.set_active(self.globals.settings['no_popup_for_one_window'])
98+ self.close_popup_on_click_cb.set_active(self.globals.settings['close_popup_on_click'])
99+ self.disable_popup_on_gbbutton_click_cb.set_active(self.globals.settings['disable_popup_on_groupbutton_click'])
100+ self.close_popup_on_gbbutton_click_cb.set_active(self.globals.settings['close_popup_on_groupbutton_click'])
101
102 # Group button keys
103 for cb_name, setting_name in self.gb_labels_and_settings.items():
104@@ -783,8 +836,10 @@
105 break
106
107 for name in self.gb_doubleclick_checkbutton_names:
108- self.gb_doubleclick_checkbutton[name].set_active(
109- self.globals.settings[name])
110+ self.gb_doubleclick_checkbutton[name].set_active(self.globals.settings[name])
111+
112+ for name in self.gb_close_popup_on_click_checkbutton_names:
113+ self.gb_close_popup_on_click_checkbutton[name].set_active(self.globals.settings[name])
114
115 # Opacify
116 self.opacify_cb.set_active(self.globals.settings['opacify'])
117
118=== modified file 'dockbarx/__init__.py' (properties changed: -x to +x)
119=== modified file 'dockbarx/cairowidgets.py' (properties changed: -x to +x)
120--- dockbarx/cairowidgets.py 2010-05-25 15:06:34 +0000
121+++ dockbarx/cairowidgets.py 2010-07-05 16:50:40 +0000
122@@ -209,4 +209,3 @@
123 ctx.set_source_rgba(0.0, 0.0, 0.0, alpha)
124 ctx.set_line_width(1)
125 ctx.stroke()
126-
127
128=== modified file 'dockbarx/common.py' (properties changed: -x to +x)
129--- dockbarx/common.py 2010-06-29 16:11:43 +0000
130+++ dockbarx/common.py 2010-07-05 16:50:40 +0000
131@@ -140,6 +140,7 @@
132 return False
133
134
135+
136 class Globals(gobject.GObject):
137 """ Globals is a signletron containing all the "global" variables of dockbarx.
138
139@@ -156,38 +157,37 @@
140 'gkey-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,())
141 }
142
143- DEFAULT_SETTINGS = {
144- "theme": "default",
145+ DEFAULT_SETTINGS = { "theme": "default",
146 "groupbutton_attention_notification_type": "red",
147 "workspace_behavior": "switch",
148 "popup_delay": 250,
149+ "popup_delay_second": 30,
150+ "close_popup_on_click": False,
151+ "disable_popup_on_groupbutton_click":False,
152+ "close_popup_on_groupbutton_click":False,
153 "popup_align": "center",
154 "no_popup_for_one_window": False,
155 "show_only_current_desktop": False,
156 "preview": False,
157+ "remember_previews": False,
158 "preview_size": 230,
159-
160+
161 "select_one_window": "select or minimize window",
162 "select_multiple_windows": "select all",
163-
164+
165 "opacify": False,
166 "opacify_group": False,
167 "opacify_alpha": 11,
168-
169+
170 "separate_wine_apps": True,
171 "separate_ooo_apps": True,
172-
173- "groupbutton_left_click_action": \
174- "select or minimize group",
175- "groupbutton_shift_and_left_click_action": \
176- "launch application",
177- "groupbutton_middle_click_action": \
178- "close all windows",
179- "groupbutton_shift_and_middle_click_action": \
180- "no action",
181+
182+ "groupbutton_left_click_action":"select or minimize group",
183+ "groupbutton_shift_and_left_click_action":"launch application",
184+ "groupbutton_middle_click_action":"close all windows",
185+ "groupbutton_shift_and_middle_click_action": "no action",
186 "groupbutton_right_click_action": "show menu",
187- "groupbutton_shift_and_right_click_action": \
188- "no action",
189+ "groupbutton_shift_and_right_click_action": "no action",
190 "groupbutton_scroll_up": "select next window",
191 "groupbutton_scroll_down": "select previous window",
192 "groupbutton_left_click_double": False,
193@@ -196,19 +196,22 @@
194 "groupbutton_shift_and_middle_click_double": False,
195 "groupbutton_right_click_double": False,
196 "groupbutton_shift_and_right_click_double": False,
197- "windowbutton_left_click_action": \
198- "select or minimize window",
199- "windowbutton_shift_and_left_click_action": \
200- "no action",
201- "windowbutton_middle_click_action": \
202- "close window",
203- "windowbutton_shift_and_middle_click_action": \
204- "no action",
205+ "windowbutton_left_click_action":"select or minimize window",
206+ "windowbutton_shift_and_left_click_action":"no action",
207+ "windowbutton_middle_click_action":"close window",
208+ "windowbutton_shift_and_middle_click_action": "no action",
209 "windowbutton_right_click_action": "show menu",
210- "windowbutton_shift_and_right_click_action": \
211- "no action",
212+ "windowbutton_shift_and_right_click_action": "no action",
213 "windowbutton_scroll_up": "shade window",
214 "windowbutton_scroll_down": "unshade window",
215+ "windowbutton_close_popup_on_left_click": False,
216+ "windowbutton_close_popup_on_shift_and_left_click": False,
217+ "windowbutton_close_popup_on_middle_click": False,
218+ "windowbutton_close_popup_on_shift_and_middle_click": False,
219+ "windowbutton_close_popup_on_right_click": False,
220+ "windowbutton_close_popup_on_shift_and_right_click": False,
221+ "windowbutton_close_popup_on_scroll_up": False,
222+ "windowbutton_close_popup_on_scroll_down": False,
223
224 "gkeys_select_next_group": False,
225 "gkeys_select_next_group_keystr": '<super>Tab',
226@@ -257,6 +260,8 @@
227 self.orient = 'h'
228 self.apps_by_id = {}
229 self.theme_name = None
230+ # link to current popup being shown
231+ self.popup_showing = None
232
233 # Get gconf settings
234 self.settings = self.DEFAULT_SETTINGS.copy()
235
236=== modified file 'dockbarx/dockbar.py' (properties changed: -x to +x)
237--- dockbarx/dockbar.py 2010-07-03 14:15:35 +0000
238+++ dockbarx/dockbar.py 2010-07-05 16:50:40 +0000
239@@ -257,7 +257,7 @@
240 self.windows = None
241 self.container = None
242 self.theme = None
243-
244+ self.popup_showing = None
245 self.gkeys = {
246 'gkeys_select_next_group': None,
247 'gkeys_select_previous_group': None,
248@@ -453,9 +453,8 @@
249
250
251 def reset_all_surfaces(self):
252- # Removes all saved pixbufs with active glow in groupbuttons
253- # iconfactories. Use this def when the looks of active glow
254- # has been changed.
255+ # Removes all saved pixbufs with active glow in groupbuttons iconfactories.
256+ # Use this def when the looks of active glow has been changed.
257 for group in self.groups.get_groups():
258 group.icon_factory.reset_surfaces()
259
260@@ -475,6 +474,9 @@
261
262 #### Applet events
263 def on_ppm_pref(self,event=None,data=None):
264+ # close any popup list before
265+ if self.popup_showing is not None:
266+ self.popup_showing.hide_list()
267 # Starts the preference dialog
268 os.spawnlp(os.P_NOWAIT,'/usr/bin/dbx_preference.py',
269 '/usr/bin/dbx_preference.py')
270@@ -1013,8 +1015,7 @@
271 entry = combobox.get_child()
272 if identifier:
273 entry.set_text(identifier)
274- # Fill the popdown list with the names of all class
275- # names of buttons that hasn't got a launcher already
276+ # Fill the popdown list with the names of all class names of buttons that hasn't got a launcher already
277 for name in self.groups.get_non_launcher_names():
278 combobox.append_text(name)
279 entry = combobox.get_child()
280@@ -1211,4 +1212,4 @@
281 gr.action_select_next_with_popup(previous=previous)
282
283 def gkey_select_previous_window_in_group(self):
284- self.gkey_select_next_window_in_group(previous=True)
285\ No newline at end of file
286+ self.gkey_select_next_window_in_group(previous=True)
287
288=== modified file 'dockbarx/groupbutton.py' (properties changed: -x to +x)
289--- dockbarx/groupbutton.py 2010-06-22 11:05:20 +0000
290+++ dockbarx/groupbutton.py 2010-07-05 16:50:40 +0000
291@@ -112,12 +112,14 @@
292 uri = uri.replace("%20","\ ")
293 uri = unquote(uri)
294 self.execute("%s %s"%(self.desktop_entry.getExec(), uri))
295-
296+ exe = exe[:exe.rfind('.')]
297+ return exe
298
299 def launch(self):
300 os.chdir(os.path.expanduser('~'))
301 if self.app:
302 print "Executing", self.app.get_name()
303+
304 return self.app.launch(None, None)
305 else:
306 print 'Executing %s'%self.desktop_entry.getExec()
307@@ -187,7 +189,6 @@
308 "Can't initiate Group button without identifier or launcher."
309
310
311-
312 # Variables
313 self.windows = {}
314 self.minimized_windows_count = 0
315@@ -205,7 +206,7 @@
316 # Compiz sends out false mouse enter messages after button is pressed.
317 # This works around that bug.
318 self.button_pressed = False
319-
320+ self.button_pressed_left = False
321 self.screen = wnck.screen_get_default()
322 self.root_xid = int(gtk.gdk.screen_get_default().get_root_window().xid)
323
324@@ -219,13 +220,11 @@
325
326
327 # Button events
328- self.button.connect("enter-notify-event", self.on_button_mouse_enter)
329- self.button.connect("leave-notify-event", self.on_button_mouse_leave)
330- self.button.connect("button-release-event",
331- self.on_group_button_release_event)
332- self.button.connect("button-press-event",
333- self.on_group_button_press_event)
334- self.button.connect("scroll-event", self.on_group_button_scroll_event)
335+ self.button.connect("enter-notify-event",self.on_button_mouse_enter)
336+ self.button.connect("leave-notify-event",self.on_button_mouse_leave)
337+ self.button.connect("button-release-event",self.on_group_button_release_event)
338+ self.button.connect("button-press-event",self.on_group_button_press_event)
339+ self.button.connect("scroll-event",self.on_group_button_scroll_event)
340 self.button.connect("size-allocate", self.on_sizealloc)
341 self.button_old_alloc = self.button.get_allocation()
342
343@@ -251,6 +250,16 @@
344 self.winlist = None
345 self.on_show_previews_changed()
346
347+
348+ self.popup = cairo_popup.window
349+ self.popup_showing = False
350+ self.popup_showing_by_delay = False
351+ self.popup_just_closed_by_group_button = False
352+ self.popup_delay_request_id = None
353+ self.disable_popup_delay = False
354+ self.delay_hide_list_request_id = None
355+ self.delay_hide_list_done = False
356+ self.popup.connect("leave-notify-event",self.on_popup_mouse_leave)
357 self.popup.add(self.popup_box)
358
359
360@@ -322,7 +331,7 @@
361 return False
362
363 #### State
364- def update_popup_label(self, arg=None):
365+ def update_popup_label(self):
366 self.popup_label.set_text(
367 "<span foreground='%s'>"%self.globals.colors['color2'] + \
368 "<big><b>%s</b></big></span>"%self.name
369@@ -369,15 +378,13 @@
370 else:
371 icon_effect = 0
372
373- if self.mouse_over:
374- mouse_over = IconFactory.MOUSE_OVER
375- elif self.button_drag_entered and not self.launcher_drag:
376- # Mouse over effect on other drag and drop
377- # than launcher dnd.
378+ if self.button_pressed_left is True:
379+ mouse_over = IconFactory.MOUSE_BUTTON_DOWN
380+ elif self.mouse_over:
381 mouse_over = IconFactory.MOUSE_OVER
382 else:
383 mouse_over = 0
384-
385+
386 if self.launch_effect:
387 launch_effect = IconFactory.LAUNCH_EFFECT
388 else:
389@@ -702,19 +709,27 @@
390
391
392 #### Show/hide list
393- def show_list_request(self):
394+ def show_list_request(self, request_by_popup_delay = False):
395+ # ignore request if just closed popup
396+ #if self.popup_just_closed_by_group_button is True:
397+ if self.disable_popup_delay is True:
398+ return False
399 # If mouse cursor is over the button, show popup window.
400 b_m_x,b_m_y = self.button.get_pointer()
401 b_r = self.button.get_allocation()
402- if self.popup_showing \
403- or ((b_m_x>=0 and b_m_x<b_r.width) \
404- and (b_m_y >= 0 and b_m_y < b_r.height) \
405- and not self.globals.right_menu_showing \
406- and not self.globals.dragging):
407- self.show_list()
408+ if self.popup_showing is False and ((b_m_x>=0 and b_m_x<b_r.width) and (b_m_y >= 0 and b_m_y < b_r.height) \
409+ and not self.globals.right_menu_showing and not self.globals.dragging):
410+ self.show_list(request_by_popup_delay)
411 return False
412
413- def show_list(self):
414+ def show_list(self, request_by_popup_delay = False):
415+ # set what kind of request we have
416+ # tist must even if popup already showing so that it will be known what is last request
417+ self.popup_showing_by_delay = request_by_popup_delay
418+ # no need to do anything if alreay showing popup
419+ if self.popup_showing is True:
420+ return
421+
422 # Move popup to it's right spot and show it.
423 offset = 3
424
425@@ -780,10 +795,17 @@
426 self.popup.move(x - w - offset,y)
427 else:
428 self.popup.move(x + b_alloc.width + offset,y)
429+
430 self.popup.show()
431 self.popup_showing = True
432- self.on_set_icongeo_win()
433- # The popup must be shown before the
434+ self.delay_hide_list_done = False
435+
436+ # close any others current popups
437+ if self.globals.popup_showing is not None:
438+ self.globals.popup_showing.hide_list()
439+ # and define this one as current popup
440+ self.globals.popup_showing = self
441+ self.on_set_icongeo_win()
442 # preview can be set. Iterate gtk events.
443 while gtk.events_pending():
444 gtk.main_iteration(False)
445@@ -811,73 +833,151 @@
446 previews)
447 return False
448
449- def hide_list_request(self):
450- if self.popup.window == None:
451- return
452- # Checks if mouse cursor really isn't hovering the button
453- # or the popup window anymore and hide the popup window
454- # if so.
455- p_m_x,p_m_y = self.popup.get_pointer()
456- p_w,p_h = self.popup.get_size()
457- b_m_x,b_m_y = self.button.get_pointer()
458- b_r = self.button.get_allocation()
459- r = 6 #radius for the rounded corner of popup window
460-
461- # Make sure that the popup list isn't closed when
462- # howering the gap between button and list.
463- w,h = self.popup.get_size()
464- p_x,p_y = self.popup.window.get_origin()
465- offset = 3
466- b_x,b_y = self.button.window.get_origin()
467- if self.globals.orient == 'h' \
468- and b_m_x >= -8 and b_m_x <= (b_r.width+7):
469- if (p_y < b_y and b_m_y >= -offset and b_m_y <= 0) \
470- or (p_y > b_y and b_m_y >= (b_r.height - 1) \
471- and b_m_y <= (b_r.height - 1 + offset)):
472- gobject.timeout_add(50, self.hide_list_request)
473- return
474- elif self.globals.orient == 'v' \
475- and b_m_y >= -8 and b_m_y <= (b_r.height+7):
476- if (p_x < b_x and b_m_x >= -offset and b_m_x <= 0) \
477- or (p_x > b_x and b_m_x >= (b_r.width - 1) \
478- and b_m_x <= (b_r.width - 1 + offset)):
479- gobject.timeout_add(50, self.hide_list_request)
480- return
481-
482- if p_m_x >= 0 and p_m_x < p_w \
483- and p_m_y >= 0 and p_m_y < p_h:
484- # Mouse pointer is inside the "rectangle"
485- # but check if it's still outside the rounded corners
486- x = None
487- y = None
488- if p_m_x < r:
489- x = r - p_m_x
490- if (p_w - p_m_x) < r:
491- x = p_m_x - (p_w - r)
492- if p_m_y < r:
493- y = r - p_m_y
494- if (p_h - p_m_y) < r:
495- y = p_m_y - (p_h - r)
496- if x == None or y == None \
497- or (x**2 + y**2) < (r-1)**2:
498- # It's inside the rounded corners!
499- return
500- if b_m_x >= 0 and b_m_x < b_r.width \
501- and b_m_y >= 0 and b_m_y < b_r.height:
502- # Mouse pointer is over the group button.
503- gobject.timeout_add(50, self.hide_list_request)
504- # This timeout add is needed if mouse cursor leaves the
505- # screen following the screen edge.
506- return
507+ def delay_hide_list_request(self):
508+ # remove hide_list_request id if was called by timeout
509+ self.delay_hide_list_request_id = None
510+ self.delay_hide_list_done = True
511+
512+
513+ def hide_list_request(self):
514+
515+ # verify that popup window is present and is showing else dont have to do anything
516+ if self.popup.window == None or self.popup_showing is False:
517+ return
518+
519+
520+ # verify validity of request based on close_popup_on_click settings
521+ if self.globals.settings['close_popup_on_click'] is not True:
522+ # Checks if mouse cursor really isn't hovering the button
523+ # or the popup window anymore and hide the popup window
524+ # if so.
525+ p_m_x,p_m_y = self.popup.get_pointer()
526+ p_w,p_h = self.popup.get_size()
527+ b_m_x,b_m_y = self.button.get_pointer()
528+ b_r = self.button.get_allocation()
529+ r = 5 #radius for the rounded corner of popup window
530+
531+ # Make sure that the popup list isn't closed when
532+ # howering the gap between button and list.
533+ w,h = self.popup.get_size()
534+ p_x,p_y = self.popup.window.get_origin()
535+ offset = 3
536+ b_x,b_y = self.button.window.get_origin()
537+ if self.globals.orient == 'h' and b_m_x>=0 and b_m_x<=(b_r.width-1):
538+ if (p_y < b_y and b_m_y>=-offset and b_m_y<=0) \
539+ or (p_y > b_y and b_m_y>=(b_r.height-1) and b_m_y<=(b_r.height-1+offset)):
540+ gobject.timeout_add(50, self.hide_list_request) # org value was 50
541+ return
542+ elif self.globals.orient == 'v' and b_m_y>=0 and b_m_y<=(b_r.height-1):
543+ if (p_x < b_x and b_m_x>=-offset and b_m_x<=0) \
544+ or (p_x > b_x and b_m_x>=(b_r.width-1) and b_m_x<=(b_r.width-1+offset)):
545+ gobject.timeout_add(50, self.hide_list_request) # org value was 50
546+ return
547+
548+ if not ((p_m_x<0 or p_m_x>(p_w-1))or(p_m_y<0 or p_m_y>(p_h-1))):
549+ # Mouse pointer is inside the "rectangle"
550+ # but check if it's still outside the rounded corners
551+ x = None
552+ y = None
553+ if p_m_x < r:
554+ x = r - p_m_x
555+ if (p_w - p_m_x) < r:
556+ x = p_m_x - (p_w - r)
557+ if p_m_y < r:
558+ y = r - p_m_y
559+ if (p_h - p_m_y) < r:
560+ y = p_m_y - (p_h - r)
561+ if x == None or y == None \
562+ or (x**2 + y**2) < (r-1)**2:
563+ # It's inside the rounded corners!
564+ return
565+ if not ((b_m_x<0 or b_m_x>(b_r.width-1)) or (b_m_y<0 or b_m_y>(b_r.height-1))):
566+ # Mouse pointer is over the group button.
567+ gobject.timeout_add(50, self.hide_list_request) # org value was 50
568+ # This timeout add is needed if mouse cursor leaves the
569+ # screen following the screen edge.
570+ return
571+ else:
572+ # if closing popup on mouse click
573+ # then get all global click (desktop global) by getting pointer position and mask
574+ display = gtk.gdk.display_get_default()
575+ pos = display.get_pointer()
576+ # if button modifiers are clicked then check if should realy close popup
577+ if pos[3] == gtk.gdk.BUTTON1_MASK or pos[3] == gtk.gdk.BUTTON2_MASK \
578+ or pos[3] == gtk.gdk.BUTTON3_MASK or pos[3] == gtk.gdk.BUTTON4_MASK \
579+ or pos[3] == gtk.gdk.BUTTON5_MASK or (self.popup_showing_by_delay is True and self.delay_hide_list_done is True):
580+ # close popup only if mouse position is not on list or on group button
581+ p_m_x,p_m_y = self.popup.get_pointer()
582+ p_w,p_h = self.popup.get_size()
583+ b_m_x,b_m_y = self.button.get_pointer()
584+ b_r = self.button.get_allocation()
585+ r = 5 #radius for the rounded corner of popup window
586+
587+ # Make sure that the popup list isn't closed when
588+ # howering the gap between button and list.
589+ w,h = self.popup.get_size()
590+ p_x,p_y = self.popup.window.get_origin()
591+ offset = 3
592+ b_x,b_y = self.button.window.get_origin()
593+ if self.globals.orient == 'h' and b_m_x>=0 and b_m_x<=(b_r.width-1):
594+ if (p_y < b_y and b_m_y>=-offset and b_m_y<=0) \
595+ or (p_y > b_y and b_m_y>=(b_r.height-1) and b_m_y<=(b_r.height-1+offset)):
596+ ##gobject.timeout_add(10, self.hide_list_request)
597+ #print "waiting for new on click ..."
598+ return
599+ elif self.globals.orient == 'v' and b_m_y>=0 and b_m_y<=(b_r.height-1):
600+ if (p_x < b_x and b_m_x>=-offset and b_m_x<=0) \
601+ or (p_x > b_x and b_m_x>=(b_r.width-1) and b_m_x<=(b_r.width-1+offset)):
602+ ##gobject.timeout_add(10, self.hide_list_request)
603+ #print "waiting for new on click ..."
604+ return
605+
606+ if not ((p_m_x<0 or p_m_x>(p_w-1))or(p_m_y<0 or p_m_y>(p_h-1))):
607+ # Mouse pointer is inside the "rectangle"
608+ # but check if it's still outside the rounded corners
609+ x = None
610+ y = None
611+ if p_m_x < r:
612+ x = r - p_m_x
613+ if (p_w - p_m_x) < r:
614+ x = p_m_x - (p_w - r)
615+ if p_m_y < r:
616+ y = r - p_m_y
617+ if (p_h - p_m_y) < r:
618+ y = p_m_y - (p_h - r)
619+ if x == None or y == None \
620+ or (x**2 + y**2) < (r-1)**2:
621+ # It's inside the rounded corners!
622+ return
623+ if not ((b_m_x<0 or b_m_x>(b_r.width-1)) or (b_m_y<0 or b_m_y>(b_r.height-1))):
624+ # click inside of group button - just ignore this request
625+ # new request will be made when mouse leaves group button so
626+ # there is no need to call timout
627+ ##gobject.timeout_add(10, self.hide_list_request)
628+ return
629+ else:
630+ # no click yet - continute waiting
631+ gobject.timeout_add(10, self.hide_list_request)
632+ #print "waiting for click ", self.global_click_id, " ..."
633+ return
634+
635 self.hide_list()
636 return
637
638 def hide_list(self):
639+ print "request to close popup"
640 self.popup.hide()
641 self.popup_showing = False
642+ self.popup_showing_by_delay = False
643+ self.globals.popup_showing = None
644+ self.delay_hide_list_done = False
645+
646+ if self.mouse_over is True:
647+ self.disable_popup_delay = True
648+
649 self.on_set_icongeo_grp()
650 if self.globals.settings["preview"]:
651- # Remove preview icon to save memory
652+ # Remove previews to save memory.
653 for win in self.get_windows():
654 self.windows[win].clear_preview_image()
655 gc.collect()
656@@ -950,16 +1050,12 @@
657 if self.globals.opacity_values == None:
658 return False
659 try:
660- compiz_call('obs/screen0/opacity_values','set',
661- self.globals.opacity_values)
662- compiz_call('obs/screen0/opacity_matches','set',
663- self.globals.opacity_matches)
664+ compiz_call('obs/screen0/opacity_values','set', self.globals.opacity_values)
665+ compiz_call('obs/screen0/opacity_matches','set', self.globals.opacity_matches)
666 except:
667 try:
668- compiz_call('core/screen0/opacity_values','set',
669- self.globals.opacity_values)
670- compiz_call('core/screen0/opacity_matches','set',
671- self.globals.opacity_matches)
672+ compiz_call('core/screen0/opacity_values','set', self.globals.opacity_values)
673+ compiz_call('core/screen0/opacity_matches','set', self.globals.opacity_matches)
674 except:
675 print "Error: Couldn't set opacity back to normal."
676 self.globals.opacity_values = None
677@@ -1131,8 +1227,7 @@
678 self.on_set_icongeo_grp()
679
680 def on_button_mouse_enter (self, widget, event):
681- # In compiz there is a enter and a leave event
682- # before a button_press event.
683+ # In compiz there is a enter and a leave event before a button_press event.
684 if self.button_pressed :
685 return
686 self.mouse_over = True
687@@ -1152,69 +1247,123 @@
688 if self.globals.settings["popup_delay"]>0:
689 self.on_set_icongeo_delay()
690 if not self.globals.right_menu_showing and not self.globals.dragging:
691- gobject.timeout_add(self.globals.settings['popup_delay'],
692- self.show_list_request)
693+ # if already showing some other popup then make request only if showing by group button delay
694+ if self.globals.popup_showing is not None and self.globals.popup_showing.popup_showing_by_delay is True:
695+ #make request with lower delay
696+ gobject.timeout_add(self.globals.settings['popup_delay_second'], self.show_list_request, True)
697+ elif self.globals.popup_showing is None:
698+ gobject.timeout_add(self.globals.settings['popup_delay'], self.show_list_request, True)
699
700 def on_button_mouse_leave (self, widget, event):
701- # In compiz there is a enter and
702- # a leave event before a button_press event.
703+ # In compiz there is a enter and a leave event before a button_press event.
704 self.button_pressed = False
705 self.mouse_over = False
706+ self.disable_popup_delay = False
707+
708 self.update_state()
709- self.hide_list_request()
710+ if self.popup_showing is True:
711+ # also remove and previous hide_list_request's so that timout will be correct
712+ if self.delay_hide_list_request_id is not None:
713+ gobject.source_remove(self.delay_hide_list_request_id)
714+
715+ # clear delay hide_list request flag
716+ self.delay_hide_list_done = False
717+
718+ # request for popup list to hide
719+ # if closing popup on click then should delay request
720+ if self.popup_showing_by_delay is True and self.globals.settings['close_popup_on_click']:
721+
722+ # make request
723+ request_timeout = 600
724+ self.delay_hide_list_request_id = gobject.timeout_add(request_timeout,self.delay_hide_list_request)
725+
726+ self.hide_list_request()
727+
728+ elif self.popup_delay_request_id is not None:
729+ gobject.source_remove(self.popup_delay_request_id)
730+ self.popup_delay_request_id = None
731 if self.popup.window == None:
732 # self.hide_list takes care of 'set-icongeo-grp' normally
733 # but if no popup window exist its taken care of here.
734 self.on_set_icongeo_grp()
735- if self.globals.settings["opacify"] \
736- and self.globals.settings["opacify_group"]:
737+ if self.globals.settings["opacify"] and self.globals.settings["opacify_group"]:
738 self.deopacify_request()
739
740 def on_popup_mouse_leave (self,widget,event):
741+ # request for popup list to hide
742+
743+ # remove any previous hide_list_request's o that timout will be correct
744+ if self.delay_hide_list_request_id is not None:
745+ gobject.source_remove(self.delay_hide_list_request_id)
746+
747+ # clear delay hide_list request flag
748+ self.delay_hide_list_done = False
749+
750+ # if closing popup on click then should delay request
751+ if self.popup_showing_by_delay is True and self.globals.settings['close_popup_on_click']:
752+ # make request
753+ request_timeout = 600
754+ self.delay_hide_list_request_id = gobject.timeout_add(request_timeout,self.delay_hide_list_request)
755+
756 self.hide_list_request()
757+ return
758
759 def on_group_button_scroll_event (self,widget,event):
760+ disable_popup = True
761 if event.direction == gtk.gdk.SCROLL_UP:
762 action = self.globals.settings['groupbutton_scroll_up']
763 self.action_function_dict[action](self, widget, event)
764 elif event.direction == gtk.gdk.SCROLL_DOWN:
765 action = self.globals.settings['groupbutton_scroll_down']
766 self.action_function_dict[action](self, widget, event)
767+ else:
768+ disable_popup = False
769+
770+ # disbale popup list to be shown by delay when mouse clicked and action executed
771+ if self.globals.settings['disable_popup_on_groupbutton_click'] is True:
772+ self.disable_popup_delay = disable_popup;
773
774 def on_group_button_release_event(self, widget, event):
775+ disable_popup = True
776+ self.button_pressed = False
777+ self.button_pressed_left = False
778+ self.update_state()
779+
780 # Check that the mouse still is over the group button.
781 b_m_x,b_m_y = self.button.get_pointer()
782 b_r = self.button.get_allocation()
783 if b_m_x < 0 or b_m_x >= b_r.width or b_m_y < 0 or b_m_y >= b_r.height:
784 return
785-
786 # If a drag and drop just finnished set self.draggin to false
787 # so that left clicking works normally again
788 if event.button == 1 and self.globals.dragging:
789 self.globals.dragging = False
790 return
791+
792
793- if not event.button in (1, 2, 3):
794- return
795- button = {1:'left', 2: 'middle', 3: 'right'}[event.button]
796- if event.state & gtk.gdk.SHIFT_MASK:
797- mod = 'shift_and_'
798+ if event.button in (1, 2, 3):
799+ button = {1:'left', 2: 'middle', 3: 'right'}[event.button]
800+ if event.state & gtk.gdk.SHIFT_MASK:
801+ mod = 'shift_and_'
802+ else:
803+ mod = ''
804+ if not self.globals.settings[
805+ 'groupbutton_%s%s_click_double'%(mod, button)]:
806+ # No double click required, go ahead and do the action.
807+ action = self.globals.settings[
808+ 'groupbutton_%s%s_click_action'%(mod, button)]
809+ self.action_function_dict[action](self, widget, event)
810 else:
811- mod = ''
812- if not self.globals.settings[
813- 'groupbutton_%s%s_click_double'%(mod, button)]:
814- # No double click required, go ahead and do the action.
815- action = self.globals.settings[
816- 'groupbutton_%s%s_click_action'%(mod, button)]
817- self.action_function_dict[action](self, widget, event)
818+ disable_popup = False
819
820+ # disbale popup list to be shown by delay when mouse clicked and action executed
821+ if self.globals.settings['disable_popup_on_groupbutton_click'] is True:
822+ self.disable_popup_delay = disable_popup;
823
824 def on_group_button_press_event(self,widget,event):
825- # In compiz there is a enter and a leave
826- # event before a button_press event.
827+ # In compiz there is a enter and a leave event before a button_press event.
828 # self.button_pressed is used to stop functions started with
829- # gobject.timeout_add from self.button_mouse_enter
830- # or self.on_button_mouse_leave.
831+ # gobject.timeout_add from self.button_mouse_enter or self.on_button_mouse_leave.
832 self.button_pressed = True
833 gobject.timeout_add(600, self.set_button_pressed_false)
834
835@@ -1237,10 +1386,15 @@
836 elif event.button == 1:
837 # Return False so that a drag-and-drop can be initiated if needed.
838 return False
839+
840+ # disbale popup list to be shown by delay when mouse clicked and action executed
841+ if self.globals.settings['disable_popup_on_groupbutton_click'] is True:
842+ self.disable_popup_delay = True;
843+
844 return True
845
846 def set_button_pressed_false(self):
847- # Helper function to group_button_press_event.
848+ # Helper function to group_button_press_event
849 self.button_pressed = False
850 return False
851
852@@ -1286,6 +1440,7 @@
853
854 #### Actions
855 def action_select(self, widget, event):
856+ should_close_popup = self.globals.settings['close_popup_on_groupbutton_click']
857 wins = self.get_windows()
858 if (self.launcher and not wins):
859 self.action_launch_application()
860@@ -1293,29 +1448,24 @@
861 elif len(wins) == 1:
862 sow = self.globals.settings["select_one_window"]
863 if sow == "select window":
864- self.windows[wins[0]].action_select_window(widget, event)
865+ self.windows[wins[0]].action_select_window(widget, event, close_popup = should_close_popup)
866 elif sow == "select or minimize window":
867- self.windows[wins[0]].action_select_or_minimize_window(widget,
868- event)
869+ self.windows[wins[0]].action_select_or_minimize_window(widget, event, close_popup = should_close_popup)
870 # Multiple windows
871 elif len(wins) > 1:
872 smw = self.globals.settings["select_multiple_windows"]
873 if smw == "select all":
874- self.action_select_or_minimize_group(widget, event,
875- minimize=False)
876+ self.action_select_or_minimize_group(widget, event, minimize=False)
877 elif smw == "select or minimize all":
878- self.action_select_or_minimize_group(widget, event,
879- minimize=True)
880+ self.action_select_or_minimize_group(widget, event, minimize=True)
881 elif smw == "compiz scale":
882 umw = self.get_unminimized_windows()
883 if len(umw) == 1:
884 sow = self.globals.settings["select_one_window"]
885 if sow == "select window":
886- self.windows[umw[0]].action_select_window(widget,
887- event)
888+ self.windows[umw[0]].action_select_window(widget, event, close_popup = should_close_popup)
889 elif sow == "select or minimize window":
890- self.windows[umw[0]].action_select_or_minimize_window(
891- widget, event)
892+ self.windows[umw[0]].action_select_or_minimize_window(widget, event, close_popup = should_close_popup)
893 elif len(umw) == 0:
894 self.action_select_or_minimize_group(widget, event)
895 else:
896@@ -1326,7 +1476,7 @@
897 self.action_select_popup(widget, event)
898
899 def action_select_popup(self, widget, event):
900- if self.popup_showing is True:
901+ if self.popup_showing is True and self.popup_showing_by_delay is not True:
902 self.hide_list()
903 else:
904 self.show_list()
905@@ -1348,6 +1498,9 @@
906 wingr = False
907 active_workspace = screen.get_active_workspace()
908
909+ # close popup if at least one window gets activated
910+ close_popup = False
911+
912 # Check if there are any uminimized windows, unminimize
913 # them (unless they are on another workspace and work-
914 # space behavior is somehting other than move) and
915@@ -1358,7 +1511,7 @@
916 if win.is_minimized():
917 ignored = False
918 if not win.is_pinned() and win.get_workspace() != None \
919- and screen.get_active_workspace() != win.get_workspace():
920+ and screen.get_active_workspace() != win.get_workspace():
921 if mode == 'move':
922 ws = screen.get_active_workspace()
923 win.move_to_workspace(ws)
924@@ -1375,7 +1528,11 @@
925 if not ignored:
926 win.unminimize(event.time)
927 unminimized = True
928+ close_popup = True
929 if unminimized:
930+ # before returing also close popup if at least one window got shown
931+ if close_popup is True and self.globals.settings['close_popup_on_groupbutton_click'] is True:
932+ self.hide_list()
933 return
934
935 # Make a list of the windows in group with the bottom most
936@@ -1386,8 +1543,7 @@
937 # topmost windows.
938 for win in windows_stacked:
939 if (not win.is_skip_tasklist()) and (not win.is_minimized()) \
940- and (win.get_window_type() in [wnck.WINDOW_NORMAL,
941- wnck.WINDOW_DIALOG]):
942+ and (win.get_window_type() in [wnck.WINDOW_NORMAL,wnck.WINDOW_DIALOG]):
943 if win in self.windows:
944 ignored = False
945 if not win.is_pinned() and win.get_workspace() != None \
946@@ -1420,9 +1576,8 @@
947 grtop = False
948
949 if not grp_win_stacked and mode == 'switch':
950- # Put the windows in dictionaries according to workspace and
951- # viewport so we can compare which workspace and viewport that
952- # has most windows.
953+ # Put the windows in dictionaries according to workspace and viewport
954+ # so we can compare which workspace and viewport that has most windows.
955 workspaces ={}
956 for win in self.windows:
957 if win.get_workspace() == None:
958@@ -1457,8 +1612,8 @@
959 grp_win_stacked = vp
960 elif nr == max:
961 # Check wether this workspace or previous workspace
962- # with the same amount of windows has been
963- # activated later.
964+ # with the same amount of windows has been activated
965+ # later.
966 for win in ignorelist:
967 if win in grp_win_stacked:
968 break
969@@ -1479,7 +1634,11 @@
970 if win.is_minimized():
971 win.unminimize(event.time)
972 unminimized = True
973+ close_popup = True
974 if unminimized:
975+ # before returing also close popup if at least one window got shown
976+ if close_popup is True and self.globals.settings['close_popup_on_groupbutton_click'] is True:
977+ self.hide_list()
978 return
979 ordered_list = []
980 ignorelist.reverse() #Bottommost window fist again.
981@@ -1491,9 +1650,15 @@
982 if grtop and not moved and minimize:
983 for win in grp_win_stacked:
984 self.windows[win].window.minimize()
985+ close_popup = False
986 if not grtop:
987 for win in grp_win_stacked:
988 self.windows[win].window.activate(event.time)
989+ close_popup = True
990+
991+ # before returing also close popup if at least one window got shown
992+ if close_popup is True and self.globals.settings['close_popup_on_groupbutton_click'] is True:
993+ self.hide_list()
994
995 def action_select_only(self, widget, event):
996 self.action_select_or_minimize_group(widget, event, False)
997@@ -1503,13 +1668,19 @@
998 if len(wins) > 1:
999 self.action_compiz_scale_windows(widget, event)
1000 elif len(wins) == 1:
1001- self.windows[wins[0]].action_select_window(widget, event)
1002+ self.windows[wins[0]].action_select_window(widget, event, close_popup = True)
1003
1004 def action_minimize_all_windows(self,widget=None, event=None):
1005+ # no need to hide list - user can that way select any specific window when all minimized
1006+ #self.hide_list()
1007+
1008 for window in self.get_windows():
1009 window.minimize()
1010
1011 def action_maximize_all_windows(self,widget=None, event=None):
1012+ # should hide popup list first
1013+ if self.globals.settings['close_popup_on_groupbutton_click'] is True:
1014+ self.hide_list()
1015 try:
1016 action_maximize = wnck.WINDOW_ACTION_MAXIMIZE
1017 except:
1018@@ -1559,7 +1730,10 @@
1019 # Just a safety check
1020 if not win in self.windows:
1021 return
1022+
1023 self.windows[win].action_select_window(widget, event)
1024+ # do not know if it is better to close popup or leave it open
1025+ #self.windows[win].action_select_window(widget, event, close_popup = True)
1026 if previous:
1027 self.nextlist.insert(0, win)
1028 else:
1029@@ -1578,6 +1752,8 @@
1030 self.hide_list_request)
1031
1032 def action_close_all_windows(self, widget=None, event=None):
1033+ # should hide popup list first
1034+ self.hide_list()
1035 if event:
1036 t = event.time
1037 else:
1038@@ -1586,6 +1762,9 @@
1039 window.close(t)
1040
1041 def action_launch_application(self, widget=None, event=None):
1042+ # should hide popup list first
1043+ if self.globals.settings['close_popup_on_groupbutton_click'] is True:
1044+ self.hide_list()
1045 if self.lastlaunch != None \
1046 and time() - self.lastlaunch < 2:
1047 return
1048@@ -1599,11 +1778,9 @@
1049 self.launch_effect = True
1050 self.update_state()
1051 if self.windows:
1052- self.launch_effect_timeout = gobject.timeout_add(2000,
1053- self.remove_launch_effect)
1054+ self.launch_effect_timeout = gobject.timeout_add(2000, self.remove_launch_effect)
1055 else:
1056- self.launch_effect_timeout = gobject.timeout_add(10000,
1057- self.remove_launch_effect)
1058+ self.launch_effect_timeout = gobject.timeout_add(10000, self.remove_launch_effect)
1059
1060
1061 def action_show_menu(self, widget, event):
1062@@ -1625,15 +1802,13 @@
1063 #Launch program item
1064 launch_program_item = gtk.MenuItem(_('_Launch application'))
1065 menu.append(launch_program_item)
1066- launch_program_item.connect("activate",
1067- self.action_launch_application)
1068+ launch_program_item.connect("activate", self.action_launch_application)
1069 launch_program_item.show()
1070 if self.launcher:
1071 #Remove launcher item
1072 remove_launcher_item = gtk.MenuItem(_('Unpin application'))
1073 menu.append(remove_launcher_item)
1074- remove_launcher_item.connect("activate",
1075- self.action_remove_launcher)
1076+ remove_launcher_item.connect("activate", self.action_remove_launcher)
1077 remove_launcher_item.show()
1078 #Edit identifier item
1079 edit_identifier_item = gtk.MenuItem(_('Edit Identifier'))
1080@@ -1683,7 +1858,6 @@
1081 sep = gtk.SeparatorMenuItem()
1082 menu.append(sep)
1083 sep.show()
1084- # Windows stuff
1085 win_nr = self.get_windows_count()
1086 if win_nr:
1087 if win_nr == 1:
1088@@ -1723,13 +1897,14 @@
1089 # Close all
1090 close_all_windows_item = gtk.MenuItem('%s%s'%(_("_Close"), t))
1091 menu.append(close_all_windows_item)
1092- close_all_windows_item.connect("activate",
1093- self.action_close_all_windows)
1094+ close_all_windows_item.connect("activate", self.action_close_all_windows)
1095 close_all_windows_item.show()
1096 menu.popup(None, None, None, event.button, event.time)
1097 self.globals.right_menu_showing = True
1098
1099 def action_remove_launcher(self, widget=None, event=None):
1100+ # should hide popup list first
1101+ self.hide_list()
1102 print 'Removing launcher ', self.identifier
1103 if self.identifier:
1104 name = self.identifier
1105@@ -1756,7 +1931,7 @@
1106 if not self.class_group or not wins:
1107 return
1108 if len(wins) == 1:
1109- self.windows[wins[0]].action_select_window(widget, event)
1110+ self.windows[wins[0]].action_select_window(widget, event, close_popup = True)
1111 return
1112 if self.globals.settings['show_only_current_desktop']:
1113 path = 'scale/allscreens/initiate_key'
1114@@ -1769,15 +1944,20 @@
1115 return
1116 # A new button enter signal is sent when compiz is called,
1117 # a delay is therefor needed.
1118- gobject.timeout_add(self.globals.settings['popup_delay'] + 200,
1119- self.hide_list)
1120+ if self.globals.settings['disable_popup_on_groupbutton_click'] is True:
1121+ # there is no problem with aditional compiz call since popup list
1122+ # is disabled on any click (self.disable_popup_delay)
1123+ self.hide_list()
1124+ else:
1125+ gobject.timeout_add(settings['popup_delay'] + 200, self.hide_list)
1126+
1127
1128 def action_compiz_shift_windows(self, widget, event):
1129 wins = self.get_unminimized_windows()
1130 if not self.class_group or not wins:
1131 return
1132 if len(wins) == 1:
1133- self.windows[wins[0]].action_select_window(widget, event)
1134+ self.windows[wins[0]].action_select_window(widget, event, close_popup = True)
1135 return
1136
1137 if self.globals.settings['show_only_current_desktop']:
1138@@ -1791,42 +1971,51 @@
1139 return
1140 # A new button enter signal is sent when compiz is called,
1141 # a delay is therefor needed.
1142- gobject.timeout_add(self.globals.settings['popup_delay']+ 200,
1143- self.hide_list)
1144+ if self.globals.settings['disable_popup_on_groupbutton_click'] is True:
1145+ # there is no problem with aditional compiz call since popup list
1146+ # is disabled on any click (self.disable_popup_delay)
1147+ self.hide_list()
1148+ else:
1149+ gobject.timeout_add(settings['popup_delay']+ 200, self.hide_list)
1150
1151 def action_compiz_scale_all(self, widget, event):
1152 try:
1153- compiz_call('scale/allscreens/initiate_key', 'activate',
1154- 'root', self.root_xid)
1155+ compiz_call('scale/allscreens/initiate_key','activate','root', self.root_xid)
1156 except:
1157 return
1158 # A new button enter signal is sent when compiz is called,
1159 # a delay is therefor needed.
1160- gobject.timeout_add(self.globals.settings['popup_delay']+ 200,
1161- self.hide_list)
1162+ if self.globals.settings['disable_popup_on_groupbutton_click'] is True:
1163+ # there is no problem with aditional compiz call since popup list
1164+ # is disabled on any click (self.disable_popup_delay)
1165+ self.hide_list()
1166+ else:
1167+ gobject.timeout_add(settings['popup_delay']+ 200, self.hide_list)
1168
1169 def action_dbpref (self,widget=None, event=None):
1170 # Preferences dialog
1171 self.emit('launch-preference')
1172
1173 def action_none(self, widget = None, event = None):
1174+ # if there is no action then reenable popup list
1175+ self.disable_popup_delay = False
1176 pass
1177
1178- action_function_dict = \
1179- ODict((
1180- ("select", action_select),
1181- ("close all windows", action_close_all_windows),
1182- ("minimize all windows", action_minimize_all_windows),
1183- ("maximize all windows", action_maximize_all_windows),
1184- ("launch application", action_launch_application),
1185- ("show menu", action_show_menu),
1186- ("remove launcher", action_remove_launcher),
1187- ("select next window", action_select_next),
1188- ("select previous window", action_select_previous),
1189- ("minimize all other groups", action_minimize_all_other_groups),
1190- ("compiz scale windows", action_compiz_scale_windows),
1191- ("compiz shift windows", action_compiz_shift_windows),
1192- ("compiz scale all", action_compiz_scale_all),
1193- ("show preference dialog", action_dbpref),
1194- ("no action", action_none)
1195- ))
1196\ No newline at end of file
1197+ action_function_dict = ODict((
1198+ ("select", action_select),
1199+ ("close all windows", action_close_all_windows),
1200+ ("minimize all windows", action_minimize_all_windows),
1201+ ("maximize all windows", action_maximize_all_windows),
1202+ ("launch application", action_launch_application),
1203+ ("show menu", action_show_menu),
1204+ ("remove launcher", action_remove_launcher),
1205+ ("select next window", action_select_next),
1206+ ("select previous window", action_select_previous),
1207+ ("minimize all other groups", action_minimize_all_other_groups),
1208+ ("compiz scale windows", action_compiz_scale_windows),
1209+ ("compiz shift windows", action_compiz_shift_windows),
1210+ ("compiz scale all", action_compiz_scale_all),
1211+ ("show preference dialog", action_dbpref),
1212+ ("no action", action_none)
1213+ ))
1214+
1215
1216=== modified file 'dockbarx/i18n.py' (properties changed: -x to +x)
1217=== modified file 'dockbarx/iconfactory.py' (properties changed: -x to +x)
1218--- dockbarx/iconfactory.py 2010-06-29 16:11:43 +0000
1219+++ dockbarx/iconfactory.py 2010-07-05 16:50:40 +0000
1220@@ -45,6 +45,7 @@
1221 LAUNCHER = 1<<6
1222 # Icon effects
1223 MOUSE_OVER = 1<<7
1224+ MOUSE_BUTTON_DOWN = 1<<13
1225 NEEDS_ATTENTION = 1<<8
1226 BLINK = 1<<9
1227 # ACTIVE_WINDOW
1228@@ -56,6 +57,7 @@
1229 'all_minimized':ALL_MINIMIZED,
1230 'launcher':LAUNCHER,
1231 'mouse_over':MOUSE_OVER,
1232+ 'mouse_button_down':MOUSE_BUTTON_DOWN,
1233 'needs_attention':NEEDS_ATTENTION,
1234 'blink':BLINK,
1235 'active':ACTIVE,
1236@@ -104,9 +106,6 @@
1237
1238
1239 def set_size(self, size):
1240- if size <= 0:
1241- # To avoid chrashes.
1242- size = 15
1243 self.size = size
1244 self.surfaces = {}
1245 self.average_color = None
1246@@ -120,8 +119,7 @@
1247
1248
1249 def surface_update(self, type = 0):
1250- # Checks if the requested pixbuf is already
1251- # drawn and returns it if it is.
1252+ # Checks if the requested pixbuf is already drawn and returns it if it is.
1253 # Othervice the surface is drawn, saved and returned.
1254 self.win_nr = type & 15
1255 if self.win_nr > self.max_win_nr:
1256@@ -445,8 +443,7 @@
1257 def find_icon_pixbuf(self, size):
1258 # Returns the icon pixbuf for the program. Uses the following metods:
1259
1260- # 1) If it is a launcher, return the icon from the
1261- # launcher's desktopfile
1262+ # 1) If it is a launcher, return the icon from the launcher's desktopfile
1263 # 2) Get the icon from the gio app
1264 # 3) Check if the res_class fits an themed icon.
1265 # 4) Search in path after a icon matching reclass.
1266@@ -464,8 +461,7 @@
1267 icon = self.app.get_icon()
1268 if icon.__class__ == gio.FileIcon:
1269 if icon.get_file().query_exists(None):
1270- pixbuf = self.icon_from_file_name(
1271- icon.get_file().get_path(), size)
1272+ pixbuf = self.icon_from_file_name(icon.get_file().get_path(), size)
1273 if pixbuf != None:
1274 return pixbuf
1275 elif icon.__class__ == gio.ThemedIcon:
1276@@ -504,8 +500,7 @@
1277 # If no pixbuf has been found (can only happen for an unlaunched
1278 # launcher), make an empty pixbuf and show a warning.
1279 if self.icon_theme.has_icon('application-default-icon'):
1280- pixbuf = self.icon_theme.load_icon('application-default-icon',
1281- size, 0)
1282+ pixbuf = self.icon_theme.load_icon('application-default-icon',size,0)
1283 else:
1284 pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, size,size)
1285 pixbuf.fill(0x00000000)
1286@@ -529,8 +524,7 @@
1287 def icon_from_file_name(self, icon_name, icon_size = -1):
1288 if os.path.isfile(icon_name):
1289 try:
1290- return gtk.gdk.pixbuf_new_from_file_at_size(icon_name, -1,
1291- icon_size)
1292+ return gtk.gdk.pixbuf_new_from_file_at_size(icon_name, -1, icon_size)
1293 except:
1294 pass
1295 return None
1296
1297=== modified file 'dockbarx/theme.py' (properties changed: -x to +x)
1298=== modified file 'dockbarx/windowbutton.py' (properties changed: -x to +x)
1299--- dockbarx/windowbutton.py 2010-06-22 11:15:41 +0000
1300+++ dockbarx/windowbutton.py 2010-07-05 16:50:40 +0000
1301@@ -78,22 +78,14 @@
1302
1303
1304 #--- Events
1305- self.window_button.connect("enter-notify-event",
1306- self.on_button_mouse_enter)
1307- self.window_button.connect("leave-notify-event",
1308- self.on_button_mouse_leave)
1309- self.window_button.connect("button-press-event",
1310- self.on_window_button_press_event)
1311- self.window_button.connect("button-release-event",
1312- self.on_window_button_release_event)
1313- self.window_button.connect("scroll-event",
1314- self.on_window_button_scroll_event)
1315- self.state_changed_event = self.window.connect("state-changed",
1316- self.on_window_state_changed)
1317- self.icon_changed_event = self.window.connect("icon-changed",
1318- self.on_window_icon_changed)
1319- self.name_changed_event = self.window.connect("name-changed",
1320- self.on_window_name_changed)
1321+ self.window_button.connect("enter-notify-event",self.on_button_mouse_enter)
1322+ self.window_button.connect("leave-notify-event",self.on_button_mouse_leave)
1323+ self.window_button.connect("button-press-event",self.on_window_button_press_event)
1324+ self.window_button.connect("button-release-event",self.on_window_button_release_event)
1325+ self.window_button.connect("scroll-event",self.on_window_button_scroll_event)
1326+ self.state_changed_event = self.window.connect("state-changed",self.on_window_state_changed)
1327+ self.icon_changed_event = self.window.connect("icon-changed",self.on_window_icon_changed)
1328+ self.name_changed_event = self.window.connect("name-changed",self.on_window_name_changed)
1329
1330 #--- D'n'D
1331 self.window_button.drag_dest_set(gtk.DEST_DEFAULT_HIGHLIGHT, [], 0)
1332@@ -103,6 +95,7 @@
1333 self.dnd_select_window = None
1334
1335
1336+
1337 def set_button_active(self, mode):
1338 self.is_active_window = mode
1339 self.update_label_state()
1340@@ -280,22 +273,18 @@
1341 # to this windowbutton transparent.
1342 if self.globals.opacity_values == None:
1343 try:
1344- self.globals.opacity_values = compiz_call(
1345- 'obs/screen0/opacity_values','get')
1346+ self.dockbar.opacity_values = compiz_call('obs/screen0/opacity_values','get')
1347 except:
1348 try:
1349- self.globals.opacity_values = compiz_call(
1350- 'core/screen0/opacity_values','get')
1351+ self.dockbar.opacity_values = compiz_call('core/screen0/opacity_values','get')
1352 except:
1353 return
1354 if self.globals.opacity_matches == None:
1355 try:
1356- self.globals.opacity_matches = compiz_call(
1357- 'obs/screen0/opacity_matches','get')
1358+ self.dockbar.opacity_matches = compiz_call('obs/screen0/opacity_matches','get')
1359 except:
1360 try:
1361- self.globals.opacity_matches = compiz_call(
1362- 'core/screen0/opacity_matches','get')
1363+ self.dockbar.opacity_values = compiz_call('core/screen0/opacity_matches','get')
1364 except:
1365 return
1366 self.globals.opacified = True
1367@@ -339,16 +328,12 @@
1368 if self.globals.opacity_values == None:
1369 return False
1370 try:
1371- compiz_call('obs/screen0/opacity_values','set',
1372- self.globals.opacity_values)
1373- compiz_call('obs/screen0/opacity_matches','set',
1374- self.globals.opacity_matches)
1375+ compiz_call('obs/screen0/opacity_values','set', self.dockbar.opacity_values)
1376+ compiz_call('obs/screen0/opacity_matches','set', self.dockbar.opacity_matches)
1377 except:
1378 try:
1379- compiz_call('core/screen0/opacity_values','set',
1380- self.globals.opacity_values)
1381- compiz_call('core/screen0/opacity_matches','set',
1382- self.globals.opacity_matches)
1383+ compiz_call('core/screen0/opacity_values','set', self.dockbar.opacity_values)
1384+ compiz_call('core/screen0/opacity_matches','set', self.dockbar.opacity_matches)
1385 except:
1386 print "Error: Couldn't set opacity back to normal."
1387 self.globals.opacity_values = None
1388@@ -361,8 +346,7 @@
1389 # Make sure that mouse cursor really has left the window button.
1390 b_m_x,b_m_y = self.window_button.get_pointer()
1391 b_r = self.window_button.get_allocation()
1392- if b_m_x >= 0 and b_m_x < b_r.width \
1393- and b_m_y >= 0 and b_m_y < b_r.height:
1394+ if (b_m_x>=0 and b_m_x<b_r.width) and (b_m_y >= 0 and b_m_y < b_r.height):
1395 return True
1396 self.globals.opacified = False
1397 self.opacified = False
1398@@ -390,8 +374,7 @@
1399
1400 #### Events
1401 def on_button_mouse_enter(self, widget, event):
1402- # In compiz there is a enter and
1403- # a leave event before a button_press event.
1404+ # In compiz there is a enter and a leave event before a button_press event.
1405 # Keep that in mind when coding this def!
1406 if self.button_pressed :
1407 return
1408@@ -402,8 +385,7 @@
1409 gobject.timeout_add(500, self.deopacify_request)
1410
1411 def on_button_mouse_leave(self, widget, event):
1412- # In compiz there is a enter and a leave
1413- # event before a button_press event.
1414+ # In compiz there is a enter and a leave event before a button_press event.
1415 # Keep that in mind when coding this def!
1416 self.button_pressed = False
1417 self.update_label_state(False)
1418@@ -411,11 +393,9 @@
1419 self.deopacify_request()
1420
1421 def on_window_button_press_event(self, widget,event):
1422- # In compiz there is a enter and a leave event before
1423- # a button_press event.
1424+ # In compiz there is a enter and a leave event before a button_press event.
1425 # self.button_pressed is used to stop functions started with
1426- # gobject.timeout_add from self.on_button_mouse_enter
1427- # or self.on_button_mouse_leave.
1428+ # gobject.timeout_add from self.on_button_mouse_enter or self.on_button_mouse_leave.
1429 self.button_pressed = True
1430 gobject.timeout_add(600, self.set_button_pressed_false)
1431
1432@@ -432,9 +412,13 @@
1433 if event.direction == gtk.gdk.SCROLL_UP:
1434 action = self.globals.settings['windowbutton_scroll_up']
1435 self.action_function_dict[action](self, widget, event)
1436+ if self.globals.settings['windowbutton_close_popup_on_scroll_up'] is True:
1437+ self.emit('popup-hide', None)
1438 elif event.direction == gtk.gdk.SCROLL_DOWN:
1439 action = self.globals.settings['windowbutton_scroll_down']
1440 self.action_function_dict[action](self, widget, event)
1441+ if self.globals.settings['windowbutton_close_popup_on_scroll_down'] is True:
1442+ self.emit('popup-hide', None)
1443
1444 def on_window_button_release_event(self, widget,event):
1445 if self.globals.settings["opacify"]and self.opacified:
1446@@ -442,26 +426,36 @@
1447 self.opacified = False
1448 self.deopacify()
1449 if event.button == 1 and event.state & gtk.gdk.SHIFT_MASK :
1450- action = self.globals.settings[
1451- 'windowbutton_shift_and_left_click_action']
1452+ action = self.globals.settings['windowbutton_shift_and_left_click_action']
1453 self.action_function_dict[action](self, widget, event)
1454+ if self.globals.settings['windowbutton_close_popup_on_shift_and_left_click'] is True:
1455+ self.emit('popup-hide', None)
1456 elif event.button == 1:
1457 action = self.globals.settings['windowbutton_left_click_action']
1458 self.action_function_dict[action](self, widget, event)
1459+ if self.globals.settings['windowbutton_close_popup_on_left_click'] is True:
1460+ self.emit('popup-hide', None)
1461 elif event.button == 2 and event.state & gtk.gdk.SHIFT_MASK:
1462- action = self.globals.settings[
1463- 'windowbutton_shift_and_middle_click_action']
1464+ action = self.globals.settings['windowbutton_shift_and_middle_click_action']
1465 self.action_function_dict[action](self, widget,event)
1466+ if self.globals.settings['windowbutton_close_popup_on_shift_and_middle_click'] is True:
1467+ self.emit('popup-hide', None)
1468 elif event.button == 2:
1469 action = self.globals.settings['windowbutton_middle_click_action']
1470 self.action_function_dict[action](self, widget,event)
1471+ if self.globals.settings['windowbutton_close_popup_on_middle_click'] is True:
1472+ self.emit('popup-hide', None)
1473 elif event.button == 3 and event.state & gtk.gdk.SHIFT_MASK:
1474- action = self.globals.settings[
1475- 'windowbutton_shift_and_right_click_action']
1476+ action = self.globals.settings['windowbutton_shift_and_right_click_action']
1477 self.action_function_dict[action](self, widget, event)
1478+ if self.globals.settings['windowbutton_close_popup_on_shift_and_right_click'] is True:
1479+ self.emit('popup-hide', None)
1480 elif event.button == 3:
1481 action = self.globals.settings['windowbutton_right_click_action']
1482 self.action_function_dict[action](self, widget, event)
1483+ if self.globals.settings['windowbutton_close_popup_on_right_click'] is True:
1484+ self.emit('popup-hide', None)
1485+
1486
1487 #### Menu functions
1488 def menu_closed(self, menushell):
1489@@ -475,8 +469,7 @@
1490 self.window.minimize()
1491
1492 #### Actions
1493- def action_select_or_minimize_window(self, widget=None,
1494- event=None, minimize=True):
1495+ def action_select_or_minimize_window(self, widget=None, event=None, minimize=True, close_popup = False):
1496 # The window is activated, unless it is already
1497 # activated, then it's minimized. Minimized
1498 # windows are unminimized. The workspace
1499@@ -491,21 +484,27 @@
1500 self.window.get_workspace().activate(t)
1501 if not self.window.is_in_viewport(self.screen.get_active_workspace()):
1502 win_x,win_y,win_w,win_h = self.window.get_geometry()
1503- self.screen.move_viewport(win_x-(win_x%self.screen.get_width()),
1504- win_y-(win_y%self.screen.get_height()))
1505+ self.screen.move_viewport(win_x-(win_x%self.screen.get_width()),win_y-(win_y%self.screen.get_height()))
1506 # Hide popup since mouse movment won't
1507 # be tracked during compiz move effect
1508 # which means popup list can be left open.
1509- self.emit('popup-hide', 'viewport-change')
1510+ #self.emit('popup-hide', 'viewport-change')
1511+ close_popup = True
1512 if self.window.is_minimized():
1513 self.window.unminimize(t)
1514 elif self.window.is_active() and minimize:
1515 self.window.minimize()
1516+ close_popup = False
1517 else:
1518 self.window.activate(t)
1519
1520- def action_select_window(self, widget = None, event = None):
1521- self.action_select_or_minimize_window(widget, event, False)
1522+ # also close popup list unless if we just minimized window
1523+ # but only if needed by caller or due to compiz
1524+ if close_popup is True:
1525+ self.emit('popup-hide', None)
1526+
1527+ def action_select_window(self, widget = None, event = None, close_popup = False):
1528+ self.action_select_or_minimize_window(widget, event, False, close_popup)
1529
1530 def action_close_window(self, widget=None, event=None):
1531 self.window.close(gtk.get_current_event_time())
1532@@ -570,8 +569,7 @@
1533 pass
1534
1535 action_function_dict = ODict((
1536- ('select or minimize window',
1537- action_select_or_minimize_window),
1538+ ('select or minimize window', action_select_or_minimize_window),
1539 ('select window', action_select_window),
1540 ('maximize window', action_maximize_window),
1541 ('close window', action_close_window),
1542@@ -581,4 +579,3 @@
1543 ('no action', action_none)
1544 ))
1545
1546-
1547
1548=== modified file 'dockbarx/zg.py' (properties changed: -x to +x)

Subscribers

People subscribed via source and target branches