Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.

Commit beeb27f

Browse files
authored
Merge pull request #38 from nwg-piotr/optimize_dmenu
dmenu: searching optimized
2 parents d69a65d + d76f617 commit beeb27f

File tree

2 files changed

+30
-41
lines changed

2 files changed

+30
-41
lines changed

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def read(f_name):
88

99
setup(
1010
name='sgtk-menu',
11-
version='1.1.0',
11+
version='1.1.3',
1212
description='GTK menu for sway, i3 and some other WMs',
1313
packages=find_packages(),
1414
include_package_data=True,

sgtk_menu/dmenu.py

+29-40
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
# We'll do it for i3 by applying commands to the focused window in open_menu method.
3434
if wm == "sway":
3535
try:
36-
subprocess.run(['swaymsg', 'for_window', '[title=\"~sgtk-menu\"]', 'floating', 'enable'],
36+
subprocess.run(['swaymsg', 'for_window', '[title=\"~sgtk-dmenu\"]', 'floating', 'enable'],
3737
stdout=subprocess.DEVNULL).returncode == 0
3838
except:
3939
pass
@@ -54,8 +54,7 @@
5454

5555
win = None # overlay window
5656
args = None
57-
all_items_list = [] # list of all DesktopMenuItem objects assigned to a .desktop entry
58-
all_copies_list = [] # list of copies of above used while searching (not assigned to a submenu!)
57+
all_items_list = [] # list of all DesktopMenuItem objects assigned to a command
5958
menu_items_list = [] # created / updated with menu.get_children()
6059
filtered_items_list = [] # used in the search method
6160

@@ -142,7 +141,7 @@ def main():
142141

143142
global all_commands_list
144143
all_commands_list = list_commands()
145-
all_commands_list = sorted(all_commands_list)
144+
all_commands_list.sort()
146145

147146
# Overlay window
148147
global win
@@ -202,8 +201,8 @@ def main():
202201
class MainWindow(Gtk.Window):
203202
def __init__(self):
204203
Gtk.Window.__init__(self)
205-
self.set_title('~sgtk-menu')
206-
self.set_role('~sgtk-menu')
204+
self.set_title('~sgtk-dmenu')
205+
self.set_role('~sgtk-dmenu')
207206
self.connect("destroy", Gtk.main_quit)
208207
self.connect('draw', self.draw) # transparency
209208

@@ -256,47 +255,36 @@ def __init__(self):
256255
self.add(outer_box)
257256

258257
def search_items(self, menu, event):
259-
global filtered_items_list
258+
260259
if event.type == Gdk.EventType.KEY_RELEASE:
260+
global filtered_items_list
261261
update = False
262262
# search box only accepts alphanumeric characters, and couple of special ones:
263263
if event.string and event.string.isalnum() or event.string in [' ', '-', '+', '_', '.']:
264264
update = True
265-
# remove menu items, except for search box (item #0)
266-
items = self.menu.get_children()
267-
if len(items) > 1:
268-
for item in items[1:]:
269-
self.menu.remove(item)
270265
self.search_phrase += event.string
271-
self.search_box.set_text(self.search_phrase)
272266

273267
elif event.keyval == 65288: # backspace
274268
update = True
275269
self.search_phrase = self.search_phrase[:-1]
276-
self.search_box.set_text(self.search_phrase)
277-
278-
# If our search result is a single item, we may want to activate the highlighted item with the Enter key,
279-
# but it does not work in GTK3. Here is a workaround:
280-
elif event.keyval == 65293 and len(filtered_items_list) == 1:
281-
filtered_items_list[0].activate()
282270

283271
# filter items by search_phrase
284272
if update:
285-
if len(self.search_phrase) > 0:
286-
filtered_items_list = []
287-
for item in all_copies_list:
288-
self.menu.remove(item)
289-
label = item.get_label()
290-
if " " not in self.search_phrase:
291-
if self.search_phrase.upper() in label.upper():
292-
filtered_items_list.append(item)
293-
else:
294-
# if the string ends with space, search exact 1st word
295-
if self.search_phrase.upper().split()[0] == label.upper():
296-
filtered_items_list.append(item)
297-
298-
for item in self.menu.get_children()[1:]:
299-
self.menu.remove(item)
273+
self.search_box.set_text(self.search_phrase)
274+
if self.search_phrase:
275+
# remove menu items, except for search box (item #0)
276+
items = self.menu.get_children()
277+
if len(items) > 1:
278+
for item in items[1:]:
279+
self.menu.remove(item)
280+
281+
if " " not in self.search_phrase:
282+
filtered_items_list = [item for item in all_items_list if
283+
self.search_phrase.upper() in item.get_label().upper()]
284+
else:
285+
# if the string ends with space, search exact 1st word
286+
first = self.search_phrase.split()[0].upper()
287+
filtered_items_list = [item for item in all_items_list if first == item.get_label().upper()]
300288

301289
for item in filtered_items_list:
302290
self.menu.append(item)
@@ -319,13 +307,15 @@ def search_items(self, menu, event):
319307
# restore original menu
320308
for item in menu_items_list:
321309
self.menu.append(item)
322-
# better to have it insensitive when possible
323-
self.search_item.set_sensitive(False)
324-
self.menu.reposition()
325310

326311
if len(self.search_phrase) == 0:
327312
self.search_box.set_text('Type to search')
328313

314+
# If our search result is a single, programmatically selected item, we may want to activate it
315+
# with the Enter key, but it does not work in GTK3. Here is a workaround:
316+
if event.keyval == 65293 and len(filtered_items_list) == 1:
317+
filtered_items_list[0].activate()
318+
329319
# key-release-event callback must return a boolean
330320
return True
331321

@@ -383,7 +373,6 @@ def list_commands():
383373
def build_menu(commands):
384374
icon_theme = Gtk.IconTheme.get_default()
385375
menu = Gtk.Menu()
386-
387376
win.search_item = Gtk.MenuItem()
388377
win.search_item.add(win.search_box)
389378
win.search_item.set_sensitive(False)
@@ -395,8 +384,8 @@ def build_menu(commands):
395384
item.set_property("name", "item-dmenu")
396385
item.connect('activate', launch, command)
397386
all_items_list.append(item)
398-
all_copies_list.append(item)
399387

388+
# At the beginning we'll only show args.t items. Nobody's gonna scroll through thousands of them.
400389
for item in all_items_list[:args.t]:
401390
menu.append(item)
402391

@@ -436,7 +425,7 @@ def build_menu(commands):
436425
item = Gtk.MenuItem()
437426
item.set_property("name", "item")
438427
item.add(hbox)
439-
item.connect('activate', launch, exec, True) # do not cache!
428+
item.connect('activate', launch, exec) # do not cache!
440429
menu.append(item)
441430

442431
menu.connect("hide", win.die)

0 commit comments

Comments
 (0)