Change awesomewm theme programmatically - awesome-wm

I have several wallpapers and a theme/colour palette for each one, I'm trying to find a way to assign a keyboard shortcut to change the theme from one to another.
I have no problems setting each individual theme, but cannot for the life of me figure out a way to set the theme once awesomewm has started running without killing the current instance and then making a new one.
I think once the theme has been assigned and awesomewm has been instansiated the values are fixed, if that's the case I don't think it will be possible to do.

I think one of possible ways is recreate all you widgets after theme changes. Not sure for whole code, but here is quick example how to rebuild panel by hotkey for awesome v4.0.
Some modifications for screen building functions first
local function build_panel(s)
-- destroy old panel
if s.mywibox then s.mywibox:remove() end
-- create a promptbox for given screen
s.mypromptbox = awful.widget.prompt()
-- create a layoutbox for given screen
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(awful.util.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end))
)
-- create a taglist widget
s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
-- create a tasklist widget
s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
-- create panel wibox
s.mywibox = awful.wibar({ position = "top", screen = s })
-- add widgets to the panel wibox
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ layout = wibox.layout.fixed.horizontal, mylauncher, s.mytaglist, s.mypromptbox },
s.mytasklist,
{ layout = wibox.layout.fixed.horizontal, mykeyboardlayout, wibox.widget.systray(), mytextclock, s.mylayoutbox },
}
end
awful.screen.connect_for_each_screen(function(s)
-- wallpaper
set_wallpaper(s)
-- tags
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
-- panel setup
build_panel(s)
end)
And add action to globalkeys
awful.key(
{ modkey }, "z",
function()
-- change theme settings
beautiful.bg_normal = "#ff2020"
beautiful.fg_normal = "#2020ff"
-- rebuild panel widgets
build_panel(mouse.screen)
end,
{description="theme colors change", group="awesome"}
),

I wanted the same and achieved that by writing a little script which is mapped to a shortcut. If you want to do it on your own, than you can follow these steps:
Create a folder which includes your themes.
Write a script (or use mine) which copys the files to your ~/.config/awesome folder.
Add a shortcut or something like that to execute the script.
The script should copy the files inside of your theme-folder to the config folder of awesome (~/.config/awesome).
After that you can see/use your theme after executing the script and restarting awesomewm (Default shortcut: modkey + shift + r
Your rc.lua file should only read files of your awesome-config-directory. You are just "overwriting" them by copying the files of your theme-folder. I hope the explanation is fine if not just comment on this answer.

Related

How to keep focusing on the client after it's moved to a new tag in Awesome WM?

How to make the Awesome's window(client) moving behavior the similar like DWM's ViewonTag patch
Follow a window to the tag it is being moved to.
Patch 20210312 prevents the window being followed if it is being moved
to the "all" tag.
What code should I write here?
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:move_to_tag(tag)
--- ???????? ---
--- How to follow the client window? ---
end
end
end,
{description = "move focused client to tag #"..i, group = "tag"}),
After many tries I solved this. But I don't know why it needs to declare the variables screen and tag2. Why can't use tag:view_only()
-- Move client to tag.
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then
client.focus:move_to_tag(tag)
local screen = awful.screen.focused()
local tag2 = screen.tags[i]
tag2:view_only()
end
end
end,
{ description = "move focused client to tag #"..i, group = "tag" }
),

Could someone explain how do buttons on widget work?

I'm extremely confused about how to do this. The documentation of Awesome is not clear to me at all, nor following stuff from the rc.lua helps. All I wanna do is to pop up the calendar upon clicking the textclock widget (with LMB), though I don't know how to start with it because the documentation has no examples (or at least I could not find it after spending 1 hour of googling), and the rc.lua has many different lines and arguments in each of them, making me unable to do anything.
My idea was
awful.button({}, 1, function() wibox.widget.calendar.year(os.date('*t')) end)
, but I have no clue how to attach this to the textclock widget. Also, I'm not quite sure if that is going to work anyway (that is, after I manage to attach it to the textclock). I'd wanna avoid adding too many widgets that I can interact with, and keep it simple, with as few as possible.
Thank you in advance, and I hope I didn't make anyone pull their hair out...
AwesomeWM concept of "buttons" can be split into 2 APIs. First of all, there is the button widget, which actually doesn't do much and is just a glorified wibox.widget.imagebox. This is the part not super relevant to your question.
The other part, which is relevant, is the event model. There are 2 ways to get something to happen when you click on a widget. The first one are the signals. Each widget has a button::press, button::release, mouse::enter and mouse::leave signals. You can attach a function to a signal this way:
mytextclock:connect_signal("button::press", function(self, lx, ly, button, mods, metadata)
wibox.widget.calendar.year(os.date('*t'))
end)
That API is more rich than a simple button. You get a lot of geometry and layout information you don't get from awful.button. However, it is overkill for simple buttons, thus awful.button.
Each widget has a :buttons() method in AwesomeWM < v4.4 or a .buttons object property in AwesomeWM >= v4.4. There are several examples in rc.lua of how to add some awful.buttons to these widget. Here are the snippets for the mylayoutbox widget:
For < v4.4:
s.mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc( 1) end),
awful.button({ }, 5, function () awful.layout.inc(-1) end)))
for >= v4.4:
s.mylayoutbox = awful.widget.layoutbox {
screen = s
}
s.mylayoutbox.buttons = {
awful.button({ }, 1, function () awful.layout.inc( 1) end),
awful.button({ }, 3, function () awful.layout.inc(-1) end),
awful.button({ }, 4, function () awful.layout.inc(-1) end),
awful.button({ }, 5, function () awful.layout.inc( 1) end),
}
-- That works too.
s.mylayoutbox:add_button(awful.button({ }, 1, function () awful.layout.inc( 1) end))
As for the lack of examples in the documentation. That's a fair point. I will add some.

Accessing object properties between classes in kivy

This bit of Code here creates a scrollview of buttons to allow me select from a list of different "tickets"
SearchResultButton(Button(text=str(Datarray2[i]),id=str(Datarray2[i]),on_press=self.Pressbtn ))
self.ids.SearchResult.add_widget(SearchResultButton)
From there it opens this function, which should set a variable (In this case "UpdateTicketNum") which will be used in another function to set the label text in another screen.
def Pressbtn(self, SearchResultButton):
global UpdateTicket
UpdateTicket = OPENTicket
woo = SearchResultButton.text
print(SearchResultButton.text)
wow = [blank.strip() for blank in woo.split(',')]
print("\n\n\n\n")
global UpdateTicketNum
UpdateTicketNum = (wow[0])
self.manager.get_screen('UpdateTicket').UpdateOpen()
At this point it opens up the sqlite DB and double checks that the TicketNumber is valid. The issue comes in when trying to access the label inside the kv build
def UpdateOpen(self):
print("TESTSETST")
conn = sqlite3.connect('TicketData.db', timeout=10)
UD = conn.cursor()
UD.execute('SELECT TicketNumber FROM TicketData WHERE TicketNumber = ?',(UpdateTicketNum,))
tips = UD.fetchone()
print(tips[0])
tipsy = tips[0]
UpdatedLabelTexT = tipsy
sm.current=('UpdateTicket')
UpdateTicket.ids.UpdateLabels['text']=(UpdatedLabelTexT)
The UpdateTicket.ids.UpdateLabels['text']=UpdatedLabelText] field always claims to be a property of the scrollview buttons even though I am initializing it inside another class, and with different parameters. apologies if this question is poorly formatted. but 3 days of dying trying to figure this out and I snapped.
Here is the bit in KV
<UpdateTicket>
name: 'UpdateTicket'
on_enter:
root.UpdateOpen()
orientation: "vertical"
FloatLayout:
canvas.before:
Color:
rgba: .0, .6, 1, 1
Rectangle:
pos: self.pos
size: self.size
source: "lights.jpg"
Label:
id: UpdateLabels
text: "filler"
multiline: False
size_hint: (None, None)
size: (root.width/5,root.height/20)
pos_hint:{'center_x': .5,'center_y': .5 }
and how I initialize the screen
sm.add_widget(UpdateTicket(name='UpdateTicket'))
I found the solution that worked for me. when first initializing the app
class SampleApp(App)
return sm(to build the application)
I needed to replace that return SM with
global root
return sm
root = ScreenManager()
return root
And that appeared to fix my issue. thanks for reading

testcomplete dealing with save file in wordpad

could anyone help how to deal with ribbon commnad bars in testcomplete
I'm trying to save a wordpad file
I'm writing the next code
function saveFile() {
TestedApps.wordpad.Run();
var pWordPad = Sys.Process("wordpad");
var wWordPad = pWordPad.Window("WordPadClass", "Документ - WordPad", 1).Window("RICHEDIT50W", "", 1);
wWordPad.Keys("smth");
var ribbon = pWordPad.Window("WordPadClass", "* - WordPad", 1).Window("UIRibbonCommandBarDock", "UIRibbonDockTop", 3).Window("UIRibbonCommandBar", "Ribbon", 1).Window("UIRibbonWorkPane", "Ribbon", 1).Window("NUIPane", "", 1).Window("NetUIHWND", "", 1);
}
Here I'm stack...I wonder how to open dialog save file?
I tried like this
ribbon.Click("File|Save as...");
however, it doen't work
Use keyboard shortcuts to work with Ribbon in WordPad.
function wordPadSaveAs()
{
var wordpad = Sys.Process("wordpad");
wndWordPadClass = wordpad.Window("WordPadClass", "*");
wndWordPadClass.Activate();
Sys.Keys("~fa");
}
You need to add the NetUIHWND class name to the MSAA or UI Automation list so that TestComplete could recognize different objects on a ribbon. After this, try recording the actions.

Setting windows layout for a specific application in awesome-wm

How to config awesome so it would start new application with two windows aligned like this:
----------------
|xxxxxxxxxx####|
|xxxxxxxxxx####|
|xxxxxxxxxx####|
|xxxxxxxxxx####|
----------------
where "x" is for example conversation window in pidgin and '#' is buddy list window.
In general I would like to specify width of right window and put it on the right side (maximized vertically) and the other window should take the remaining space.
I already have some almost-working code, but it behaves strangely (it setups everything correct for pidgin, but it doesn't for gimp and v_sim, and occasionally without any known to me reason it changes geometry of the left window. Or when I start application (v_sim) it isn't placed in correct positions and it isn't maximized vertically, but when I then restart awesome, it places it correctly. So I guess that this application changes something when it starts.
Here is code which I use now:
awful.rules.rules = {
...
{ rule = { class = "Pidgin", role = "buddy_list" },
properties = {
floating = true
},
callback = function( c )
local w_area = screen[ c.screen ].workarea
local winwidth = 340
c:struts( { right = winwidth } )
c:geometry( { x = w_area.width - winwidth, width = winwidth, y = w_area.y, height = w_area.height } )
end
},
{ rule = { class = "Pidgin", role = "conversation" },
properties = {
floating = true,
x = 0,
maximized_vertical = true,
maximized_horizontal = true
},
callback = awful.client.setslave
},
...
}
I had this exact same problem, but I wanted a large Firefox window on the left with a small terminal on the right. To get it to work I dedicated a tag for this purpose with a tile-left layout and adjusted the width factor (i.e. the operation normally performed by CTRL-L).
Add the following to the end of rc.lua where yourtag is the tag in which you would like to place these windows. The 0.15 value can be adjusted to your taste.
awful.tag.viewonly(yourtag)
awful.tag.incmwfact(0.15, yourtage)
Also, using the awful.client.setslave for the window that you want on the right ensures that they don't get switched.
{
rule = { class = "URxvt" },
callback = awful.client.setslave
},
You may also direct certain applications to a tag using the tag property.
{
rule = { class = "Firefox" },
properties = { tag = browse }
},
{
rule = { class = "URxvt", instance = "browse" },
properties = { tag = browse },
},
I then created a binding to open these applications as follows.
-- Custom programs
awful.key({ modkey, "Shift" }, "b", function()
awful.tag.viewonly(browse)
awful.util.spawn_with_shell("urxvt -name browse -e newsbeuter")
awful.util.spawn("firefox")
end)
This is the final result:
Alternatively, you can use a floating contact list window with struts.
This prevents the contact list window from being maximized when no message-window is present.
Also, it allows the CL-window to be placed next to arbitrary (tiling) windows.
Check out: http://www.bramschoenmakers.nl/en/node/738
Although his implementation is a bit buggy for my version of awesome.
The problem is that it does not adjust for struts that have already been set.
My implementation:
{ rule = { class = "Pidgin", role = "buddy_list" },
properties = {floating=true,
maximized_vertical=true, maximized_horizontal=false },
callback = function (c)
local cl_width = 250 -- width of buddy list window
local scr_area = screen[c.screen].workarea
local cl_strut = c:struts()
-- scr_area is affected by this client's struts, so we have to adjust for that
if c:isvisible() and cl_strut ~= nil and cl_strut.left > 0 then
c:geometry({x=scr_area.x-cl_strut.left, y=scr_area.y, width=cl_strut.left})
-- scr_area is unaffected, so we can use the naive coordinates
else
c:struts({left=cl_width, right=0})
c:geometry({x=scr_area.x, y=scr_area.y, width=cl_width})
end
end },
This puts the CL window on the left and allocating a fixed space for it.
(You don't need any rule for the conversation-window)

Resources