From 06d339c68dea140959f678022bab19baae175b96 Mon Sep 17 00:00:00 2001 From: streetturtle Date: Fri, 12 Mar 2021 22:43:13 -0500 Subject: [PATCH] update readme --- README.md | 84 +++++++++++++++++++++++++++++++++++- example.json | 31 +++++++++++++ init.lua | 67 ++++++++++++++-------------- scratch_27.json | 37 ---------------- screenshots/screenshot.png | Bin 0 -> 4897 bytes screenshots/screenshot2.png | Bin 0 -> 13233 bytes test.sh | 2 +- 7 files changed, 150 insertions(+), 71 deletions(-) create mode 100644 example.json delete mode 100644 scratch_27.json create mode 100644 screenshots/screenshot.png create mode 100644 screenshots/screenshot2.png diff --git a/README.md b/README.md index de878d4..d704802 100644 --- a/README.md +++ b/README.md @@ -1 +1,83 @@ -# noobie \ No newline at end of file +# noobie + +Create a wibar widget for Awesome WM with no lua code! + +This is widget-maker tool - it creates a widget based on a definition described in JSON format and returned by a script. + +For example, if your script returns a following JSON: + +```json +{ + "widget": { + "icon_path": "smile", + "text": "noobie", + "mouse_actions": { + "on_scroll_up": "echo 'scroll up'", + "on_scroll_down": "echo 'scroll down'", + "on_right_click": "echo 'right click'" + } + } +} +``` + +noobie will convert it to following widget: + +![screenshot](./screenshots/screenshot.png). + +You can also create widgets with menu: + +```json +{ + "widget": { + "icon_path": "smile", + "text": "noobie", + "mouse_actions": { + "on_scroll_up": "echo 'scroll up'", + "on_scroll_down": "echo 'scroll down'", + "on_right_click": "echo 'right click'" + } + }, + "menu": { + "items": [ + { + "icon": "bell", + "title": "Say hi!", + "onclick": "notify-send 'hi!'" + }, + { + "icon": "terminal", + "title": "Execute some script", + "onclick": "/tmp/somescript.sh" + }, + { + "icon": "slack", + "title": "OpenSlack", + "onclick": "xdg-open https://slack.com" + } + ] + } +} +``` + +gives: + +![](./screenshots/screenshot2.png) + +## Plugins + +You can create your own scripts in any language, the only rule is - it should return a proper JSON. +Or you can check existing plugins in this repo: https://github.com/streetturtle/noobie-plugins. + +## Installation + +1. Download the latest release under ~/.config/awesome/ folder +1. At the top of rc.lua add an import: + +```lua +local noobie_exmaple = require("noobie") +``` +1. Add a widget to wibox and provide a path to your script: + +```lua +noobie{ path = os.getenv("HOME") .. '/.config/awesome/noobie/test.sh' }, +``` diff --git a/example.json b/example.json new file mode 100644 index 0000000..c0bd4f4 --- /dev/null +++ b/example.json @@ -0,0 +1,31 @@ +{ + "widget": { + "icon_path": "smile", + "text": "noobie", + "mouse_actions": { + "on_scroll_up": "echo 'scroll up'", + "on_scroll_down": "echo 'scroll down'", + "on_right_click": "echo 'right click'" + } + }, + "menu": { + "items": [ + { + "icon": "bell", + "title": "Say hi!", + "onclick": "notify-send 'hi!'" + }, + { + "icon": "terminal", + "title": "Execute some script", + "onclick": "/tmp/somescript.sh" + }, + { + "icon": "slack", + "title": "OpenSlack", + "onclick": "xdg-open https://slack.com" + } + ] + } +} + diff --git a/init.lua b/init.lua index 47140fb..21138e9 100644 --- a/init.lua +++ b/init.lua @@ -5,7 +5,6 @@ local beautiful = require("beautiful") local gears = require("gears") local json = require("json") - local HOME_DIR = os.getenv("HOME") local WIDGET_DIR = HOME_DIR .. '/.config/awesome/noobie' local ICONS_DIR = WIDGET_DIR .. '/feather_icons/' @@ -13,19 +12,6 @@ local ICONS_DIR = WIDGET_DIR .. '/feather_icons/' local cur_stdout local noobie_widget = {} -local noobie_popup = awful.popup{ - ontop = true, - visible = false, - shape = function(cr, width, height) - gears.shape.rounded_rect(cr, width, height, 4) - end, - border_width = 1, - border_color = beautiful.bg_focus, - maximum_width = 400, - offset = { y = 5 }, - widget = {} -} - local function show_warning(message) naughty.notify{ preset = naughty.config.presets.critical, @@ -37,14 +23,28 @@ local function worker(user_args) local args = user_args or {} local refresh_rate = args.refresh_rate or 600 local path = args.path + local background = args.background or '#00000000' if path == nil then show_warning("Cannot create a widget, required parameter 'path' is not provided") return end - + local noobie_popup = awful.popup{ + ontop = true, + visible = false, + shape = function(cr, width, height) + gears.shape.rounded_rect(cr, width, height, 4) + end, + border_width = 1, + border_color = beautiful.bg_focus, + maximum_width = 400, + offset = { y = 5 }, + widget = {} + } local has_menu = false local has_mouse_actions = false + local menu_buttons = {} + local mouse_actions_buttons = {} noobie_widget = wibox.widget { { @@ -74,6 +74,7 @@ local function worker(user_args) shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 4) end, + bg = background, widget = wibox.container.background, set_text = function(self, new_text) if new_text == nil or new_text == '' then @@ -89,7 +90,12 @@ local function worker(user_args) } local update_widget = function(widget, stdout, stderr) + if stderr ~= '' then + show_warning(stderr) + return + end + --- do nothing if the output hasn't changed if (cur_stdout == stdout) then return else cur_stdout = stdout end @@ -101,10 +107,7 @@ local function worker(user_args) has_menu = result.menu ~= nil and result.menu.items ~= nil and #result.menu.items > 0 if has_menu then - local rows = { - { widget = wibox.widget.textbox }, - layout = wibox.layout.fixed.vertical, - } + local rows = { layout = wibox.layout.fixed.vertical } for i = 0, #rows do rows[i]=nil end for _, item in ipairs(result.menu.items) do @@ -148,9 +151,9 @@ local function worker(user_args) end end) - row:buttons(awful.util.table.join(awful.button({}, 1, function() + row:buttons(gears.table.join(awful.button({}, 1, function() awful.spawn.with_shell(item.onclick) - noobie_widget:set_bg('#00000000') + widget:set_bg(background) noobie_popup.visible = not noobie_popup.visible end))) @@ -159,19 +162,17 @@ local function worker(user_args) noobie_popup:setup(rows) - noobie_widget:buttons( - awful.util.table.join( + menu_buttons = gears.table.join( awful.button({}, 1, function() if noobie_popup.visible then - noobie_widget:set_bg('#00000000') + widget:set_bg(background) noobie_popup.visible = not noobie_popup.visible else - noobie_widget:set_bg(beautiful.bg_focus) + widget:set_bg(beautiful.bg_focus) noobie_popup:move_next_to(mouse.current_widget_geometry) end end) ) - ) end local actions = result.widget.mouse_actions @@ -179,13 +180,15 @@ local function worker(user_args) if has_mouse_actions then - widget:buttons(awful.util.table.join( - awful.button({}, 1, function() if actions.on_left_click ~= nill then awful.spawn.with_shell(actions.on_left_click) end end), - awful.button({}, 2, function() if actions.on_right_click ~= nill then awful.spawn.with_shell(actions.on_right_click) end end), - awful.button({}, 4, function() if actions.on_scroll_up ~= nill then awful.spawn.with_shell(actions.on_scroll_up) end end), - awful.button({}, 5, function() if actions.on_scroll_down ~= nill then awful.spawn.with_shell(actions.on_scroll_down) end end) - )) + mouse_actions_buttons = gears.table.join( + awful.button({}, 1, function() if actions.on_left_click ~= nil then awful.spawn.with_shell(actions.on_left_click) end end), + awful.button({}, 2, function() if actions.on_right_click ~= nil then awful.spawn.with_shell(actions.on_right_click) end end), + awful.button({}, 4, function() if actions.on_scroll_up ~= nil then awful.spawn.with_shell(actions.on_scroll_up) end end), + awful.button({}, 5, function() if actions.on_scroll_down ~= nil then awful.spawn.with_shell(actions.on_scroll_down) end end) + ) end + + widget:buttons(gears.table.join(mouse_actions_buttons, menu_buttons)) end watch(string.format([[sh -c "%s"]], path), refresh_rate, update_widget, noobie_widget) diff --git a/scratch_27.json b/scratch_27.json deleted file mode 100644 index 161e5ad..0000000 --- a/scratch_27.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "widget": { - "icon_path": "activity", - "text": "hello", - "mouse_actions": { - "on_scroll_up": "asd", - "on_scroll_down": "", - "on_left_click": "", - "on_right_click": "" - } - }, - "menu": { - "items": [ - { - "icon": "bell", - "title": "Some title" - }, - { - "icon": "check", - "title": "Some title" - }, - { - "icon": "box", - "title": "Some title" - }, - { - "icon": "slack", - "title": "Some title" - }, - { - "icon": "cloud", - "title": "Some title" - } - ] - } -} - diff --git a/screenshots/screenshot.png b/screenshots/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..128b8f529d6f2468ec84443cb47da43d5fcffbe5 GIT binary patch literal 4897 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 Ti6Zo-00000NkvXXu0mjfC>3>U literal 0 HcmV?d00001 diff --git a/screenshots/screenshot2.png b/screenshots/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb5f84613fb23b5bfb14d6a019f9d99734bbf4c GIT binary patch literal 13233 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