Ein Grid Select Menu für den Awesome Windowmanager

Update 09.10.2022: fixed fehlende Farbe beim letzten Knopf wenn die Anzahl der Anwendungen, die Anzahl der hinterlegten Farben übersteigt

Nach dem Umstieg auf den awesome Windowmanager, bin ich echt begeistert, nur eins fehlte mir, ein Grid Select Menu, wie ich es von xmonad kannte. Ein Grid Select Menu zeigt mir als Overlay eine tabellarische Anordnung von Menüeinträgen / Anwendungsnamen aus denen ich dann auswählen kann und durch Klick oder Enter auf dem jeweiligen Eintrag die Anwendung starten kann.

Der awesome Windowmanager läßt sich in der Programmiersprache Lua erweitern und so habe ich eine kleine Routine geschrieben, mit der man awesome um ein Grid Select erweitern kann.

Dieses awesome widget kann bis zu 50 Menueinträge anzeigen und wird direkt über die rc.lua (Konfigurationsdatei von awesome und normalerweise im Verzeichnis ~/.config/awesome abgelegt).

Zuerst definiert man sich die gewünschten Menüeinträge und zugehörige Programme. Dabei ist der erste String der Text, der im Menü angezeigt wird und der zweite Stringe das Kommando, das bei Auswahl des Menüeintrages ausgeführt wird.

Das sieht dann z.B. so aus:

local my_appgrid = { {"Chromium", "chromium"}, {"Thunderbird", "thunderbird"} , {"Firefox", "firefox"}, {"Urxvt", "urxvt"} , {"LibreOffice Calc", "localc"}, {"LibreOffice Writer", "lowriter"} , {"PCManFM", "pcmanfm"} }
Code-Sprache: JavaScript (javascript)

Um das Menü auch aufrufen zu können verknüpft man es dann mit einer Tastenkombination. Im folgenden Beispiel ist das <Mod4> + g.

awful.key({ modkey }, "g", function() grid_select.launch({appgrid = my_appgrid}) end, {description = "Show grid selection menu", group = "custom"} )
Code-Sprache: JavaScript (javascript)

Dies Verknüpfung mit der Tastenkombination wird in rc.lua im Abschnitt globalkeys = mytable.join( … ) eingebaut.

Wer möchte kann sich auch eine andere Menge an Farben definieren. Dazu definiert man sich eine Tabelle von Farben und gibt diese als Parameter an das Widget mit.

local myColors = { „#9BB7D4“, „#C74375“, „#BF1932“, „#7BC4C4“, „#E2583E“, „#53B0AE“ }

Die Verknüpfung mit der Tastenkombination sieht dann so aus:

awful.key({ modkey }, "g", function() grid_select.launch({appgrid = my_appgrid, colors = myColors}) end, {description = "Show grid selection menu", group = "custom"} )
Code-Sprache: JavaScript (javascript)

Das Widget wird wie folgt in rc.lua eingebunden:

local grid_select = require("grid-select-widget.grid-select")
Code-Sprache: JavaScript (javascript)

Zum Abschluss der Sourcecode des Widgets, den man z.B. im Verzeichnis ~/.config/awesoem/grid-select/grid-select.lua ablegt.

------------------------------------------------- – Grid select widget for Awesome Window Manager – @author tuxlogger – @copyright 2022 Tuxlogger ------------------------------------------------- -- – To use this grid select widget, edit rc.luadefine your own commands in a table --[[[ local HOME_DIR = os.getenv("HOME") local my_appgrid = { {"Chromium", "chromium"} , {"Thunderbird", "thunderbird"} , {"Firefox", "firefox"} , {"Urxvt", "urxvt"} , {"LibreOffice Calc", "localc"} , {"LibreOffice Writer", "lowriter"} , {"PCManFM", "pcmanfm"} } and add a keybinding awful.key({ modkey }, "g", function() grid_select.launch({appgrid = my_appgrid}) end, {description = "Show grid selection menu", group = "custom"}) somewhere in the globalkeys = mytable.join( ... ) section in rc.lua You can also change the colors defining your own color table local myColors = { "#9BB7D4", "#C74375", "#BF1932", "#7BC4C4", "#E2583E", "#53B0AE" } and change the keybinding accordingly to awful.key({ modkey }, "g", function() grid_select.launch({appgrid = my_appgrid, colors = myColors}) end, {description = "Show grid selection menu", group = "custom"}) You can either define the selected entry by setting default_app to the number of the entry in my_appgrid, counting start at 1 local my_appgrid_default = 9 and change the keybindings according to awful.key({ modkey }, "g", function() grid_select.launch({appgrid = my_appgrid, colors = myColors, default_app = my_appgrid_default}) end, {description = "Show grid selection menu", group = "custom"}) --]] local awful = require("awful") local capi = {keygrabber = keygrabber } local wibox = require("wibox") local gears = require("gears") local HOME_DIR = os.getenv("HOME") – default appgrid entries to have something to start with local myAppGrid = { {"Chromium", "chromium"} , {"Thunderbird", "thunderbird"} , {"Firefox", "firefox"} , {"Urxvt", "urxvt"} , {"LibreOffice Calc", "localc"} , {"LibreOffice Writer", "lowriter"} , {"PCManFM", "pcmanfm"} } – default color palette from the pantene colors of the year local myColors = { "#9BB7D4", "#C74375", "#BF1932", "#7BC4C4", "#E2583E", "#53B0AE", "#9B1B30", "#5A5B9F", "#F0C05A", "#45B5AA", "#D94F70", "#DD4124", "#009473", "#B163A3", "#955251", "#92A8D1", "#88B04B", "#5F4B8B", "#FF6F61", "#0F4C81" } – create overlay parent widget - default local w = wibox {} – create button widget with text label, connected to command with background color bg_color local function create_button(label, command, bg_color) – create button local but = wibox.widget{ { { markup = '<span size="14000" >' .. label ..'</span>', – font size 14 align = 'center', valign = 'center', widget = wibox.widget.textbox }, top = 8, bottom = 8, left = 8, right = 8, widget = wibox.container.margin }, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 4) end, widget = wibox.container.background } – set colors of button but:set_bg(bg_color) but:set_fg("#222222") – change button layout on enter and leave mouse focus but:connect_signal("mouse::enter", function(c) c:set_fg("#ffffff") but:set_shape( function(cr, width, height) gears.shape.hexagon(cr, width, height) end) end) but:connect_signal("mouse::leave", function(c) c:set_fg("#222222") but:set_shape( function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 4) end) end) but:connect_signal("button::press", function() awful.spawn(command) w.visible = false capi.keygrabber.stop() end) return but endcalculate the distriution of the entries to the columnscurrently this works with a max of 50 entries local function calc_entry_distribution( count ) local ca= {} – pattern of the grid select layout, giving the max entries for eacht col local col_patterns = { { 1 } ,{ 2 } ,{ 1, 3, 1 } ,{ 2, 4, 2 } ,{ 1, 3, 5, 3, 1 } ,{ 2, 4, 6, 4, 2 } ,{ 1, 3, 5, 7, 5, 3, 1 } ,{ 2, 4, 6, 8, 6, 4, 2 } ,{ 1, 3, 5, 7, 9, 7, 5, 3, 1 } ,{ 2, 4, 6, 8, 10, 8, 6, 4, 2 } } – max number of entries for the patterns defined in col_patterns local max_entries = { 1, 2, 5, 8, 13, 18, 25, 32, 41, 50 } – get the index of col_patterns for the given number of entries in count local i = 1 while(max_entries[i] < count) do i = i + 1 endreturn the selected pattern return col_patterns[i] endlaunch grid select menu local function launch(args) args = args or {} local bg_color = args.bg_color or "#333333" local appgrid = args.appgrid or myAppGrid local colors = args.colors or myColors local default_app = args.default_app or nilmaximum elements in the middle stack of the gridselect, dirty have to fix it local maxstack = math.floor( math.log(#appgrid/2) / math.log(2) ) – update overlay parent widget, doing this here because we have to change the size w = wibox { --opacity = 0.8, max_widget_size = 1000, ontop = true, width = 130 * math.pow(maxstack,2), height = 100 * maxstack, shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 8) end } w:set_bg(bg_color) – build button widget array local button_array = {} for i = 1, #appgrid do table.insert( button_array, create_button(appgrid[i][1], appgrid[i][2], colors[ (i % #colors) + 1]) ) endcreate container widget local l = wibox.widget { homogeneous = true, spacing = 15, min_cols_size = 10, min_rows_size = 10, expand = true, layout = wibox.layout.grid, } – get entry distribution local cols = calc_entry_distribution(#appgrid) – add buttons to the container widget using the given pattern local cc = 1 local offset = 0 local defx = 0 local defy = 0 for i = 1, #cols doloop for columns offset = math.floor( ( math.max(table.unpack(cols)) - cols[i]) /2) for j = 1, cols[i] doloop for rows if (button_array[cc] ~= nil) then l:add_widget_at(button_array[cc], j + offset, i) if (cc == default_app) then defx = j + offset defy = i end end cc = cc + 1 end endshow it w:set_widget(l) w.screen = mouse.screen w.visible = true awful.placement.centered(w) – focus on middle button if (default_app == nil) then x = math.ceil(#cols / 2) y = math.floor(cols[x] / 2) else x = defx y = defy end curr_button = l:get_widgets_at(x,y) curr_button[1]:emit_signal('mouse::enter') – connect to every button but default button to reformat default button on enter for i = 1, #button_array do if (i ~= default_app) then button_array[i]:connect_signal("mouse::enter", function(c) c:set_fg("#222222") button_array[default_app]:set_shape( function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 4) end) end) end endadd keyboard grabber capi.keygrabber.run(function(_, key, event) if event == "release" then return end if key then if key == 'Escape' then capi.keygrabber.stop() w.visible = false elseif key == 'Return' then curr_button[1]:emit_signal( 'button::press' ) elseif key == 'Up' then local new_x = x - 1 if new_x < 1 then new_x = 1 end local new_curr_button = l:get_widgets_at(new_x,y) if new_curr_button and new_curr_button[1] then curr_button[1]:emit_signal('mouse::leave') new_curr_button[1]:emit_signal('mouse::enter') curr_button = new_curr_button x = new_x end elseif key == 'Down' then local cmax = math.max(table.unpack(cols)) local new_x = x + 1 if new_x > cmax then new_x = cmax end local new_curr_button = l:get_widgets_at(new_x,y) if new_curr_button and new_curr_button[1] then curr_button[1]:emit_signal('mouse::leave') new_curr_button[1]:emit_signal('mouse::enter') curr_button = new_curr_button x = new_x end elseif key == 'Left' then local new_y = y - 1 if new_y < 1 then new_y = 1 end local new_curr_button = l:get_widgets_at(x,new_y) if new_curr_button and new_curr_button[1] then curr_button[1]:emit_signal('mouse::leave') new_curr_button[1]:emit_signal('mouse::enter') curr_button = new_curr_button y = new_y end elseif key == 'Right' then local new_y = y + 1 if new_y > #cols then new_y = #cols end local new_curr_button = l:get_widgets_at(x,new_y) if new_curr_button and new_curr_button[1] then curr_button[1]:emit_signal('mouse::leave') new_curr_button[1]:emit_signal('mouse::enter') curr_button = new_curr_button y = new_y end end if key == 'Escape' or string.match("Return", key) then capi.keygrabber.stop() w.visible = false end end end) endstart it return { launch = launch }
Code-Sprache: PHP (php)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

:bye: 
:good: 
:negative:  
:scratch: 
:wacko:  
:yahoo: 
B-) 
mehr...
 


   Mit der Nutzung dieses Formulars erklärst Du Dich mit der Speicherung und Verarbeitung Deiner Daten durch diese Website einverstanden. Mehr Informationen dazu findest Du in der Datenschutzerklärung.

Jooble.de ALL-INKL.COM - Webhosting Server Hosting Domain Provider TinyURL.com - Free URL Shortener

Powered by WordPress und SoftPress-Theme by MyThemeShop.

Diese Seite verwendet Cookies. Mit der Nutzung von tuxlog erklärst Du Dich mit der Verwendung von Cookies einverstanden. Detaillierte Informationen über die Verwendung von Cookies auf dieser Website findest Du in der Datenschutzerklärung.