Awesome WM: Placing tiled clients in specific order on startup - lua

I've installed Awesome WM about a week ago. Since then I've been trying to place terminal clients (bare terminal and vim, vifm, htop) in a specific order on startup. Here is a visual representation of what I'm trying to achieve:
########################
# # htop #
# ###########
# vim # bare #
# ###########
# # vifm #
########################
I've managed to place vim in the right position, but other windows are placed in what seems to be an arbitrary order, which changes with every reboot. Here is the content of my autostart.lua config:
1 local awful = require("awful")
1
2 awful.spawn.single_instance(terminal.."-e xmodmap ~/.Xmodmap; exit")
3 awful.spawn.single_instance("brave-browser", {
4 fullscreen = true,
5 focus = true
6 })
7
8 awful.spawn(terminal.." -e vim", {
9 tag = "edit",
10 placement = awful.placement.left,
11 callback = function(c) awful.client.setmaster(c) end})
12 awful.spawn(terminal.." -e htop", {
13 tag = "edit",
14 height = 80,
15 placement = awful.placement.top_right})
16 awful.spawn(terminal, {
17 tag = "edit",
18 placement = awful.placement.right})
19 awful.spawn(terminal.." -e vifm", {
20 tag = "edit",
21 placement = awful.placement.bottom_right})
22
23 awful.spawn(terminal.." -e neomutt", {
24 tag = "communication",
25 fullscreen = true })
26
27 awful.spawn("Spotify", { tag = "read" })
The layout of the tag with which I have problem is "tile". I'm on Awesome v4.3. What client property should I add to get the desired behavior?

To get clients been spawned in the desired positions on startup callback option should be used. Here is a chunk of my autostart.lua file related to the issue:
1 local awful = require("awful")
1
2 local function spawn_vifm ()
3 awful.spawn(terminal.." -e vifm", {
4 tag = "edit",
5 placement = awful.placement.bottom_right
6 })
7 end
8
9 local function spawn_term ()
10 awful.spawn(terminal, {
11 tag = "edit",
12 placement = awful.placement.right,
13 callback = function(c) spawn_vifm() end
14 })
15 end
16
17 local function spawn_htop ()
18 awful.spawn(terminal.." -e htop", {
19 tag = "edit",
20 placement = awful.placement.top_right,
21 callback = function(c) spawn_term() end
22 })
23 end
.......
38 awful.spawn(terminal.." -e vim", {
39 tag = "edit",
40 placement = awful.placement.left,
41 callback = function(c)
42 awful.client.setmaster(c)
43 store_active_client(awful.tag.find_by_name(awful.screen.focused(), "edit"), c)
44 spawn_htop()
45 end
46 })
Spawning the next client in the callback function of the previous one ensures, that the placement property will be preserved for both of them.

I don't know what you mean by this: "The layout of the tag with which I have problem is tiled left." I assume you mean that your terminals aren't tiling properly? I've used AwesomeWM for about a week a few years ago, but realized quickly it needs a lot of tinkering to get exactly how you want it. What's happening to you is exactly what I was running into.
Found it easier just to use LXDE and Devilspie2. You can Lua script windows to undecorate & maximise, jump to other desktops or whatever you want, fairly easily. This might help get you where you're going, but it's hard to say, without clarification on your question.
local screenwidth = awful.screen.geometry.width
local screenheight = awful.screen.geometry.height
local halfwidth = math.floor( screenwidth /2 )
local thirdheight = math.floor( screenheight /3 )
awful .spawn( terminal .." -e vim", {
tag = "edit",
width = halfwidth,
height = screenheight,
placement = awful .placement .left,
callback = function(c) awful .client .setmaster(c) end } )
awful .spawn( terminal.." -e htop", {
tag = "edit",
width = halfwidth,
height = thirdheight,
placement = awful .placement .top_right } )
awful .spawn( terminal, { -- bare
tag = "edit",
width = halfwidth,
height = thirdheight,
placement = awful .placement .right } )
awful .spawn( terminal .." -e vifm", {
tag = "edit",
width = halfwidth,
height = thirdheight,
placement = awful .placement .bottom_right } )
Also, I'd point out that Conky might be a viable solution, if you're just looking to view terminal output on your desktop, while scripting in Lua.

Related

How to arrange picture in lua like a grid?

I'm learning lua and I want to arrange my bubble picture with some specific x and y coordinates, here's my code so far, the value of my j and i is only incrementing by 1 instead of the +29, I know I'm lacking some knowledge so any help will be appreciated
local background = display.newImageRect("blueBackground.png",642, 1040)
background.x = display.contentCenterX
background.y = display.contentCenterY
local x = 15
local y=15
for i=15,25 do
for j=15, 25 do
local bubble = display.newImageRect("bubble.png", 23,23)
bubble.x = i
bubble.y = j
j = j + 29
print("j",j)
end
i = i + 29
print("i",i)
end
This should helps you.
From Lua documentation
The for statement has two variants: the numeric for and the
generic for.
A numeric for has the following syntax:
for var=exp1,exp2,exp3 do
something
end
That loop will execute something for each value of var from exp1
to exp2, using exp3 as the step to increment var. This third
expression is optional; when absent, Lua assumes one as the step
value. As typical examples of such loops, we have
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end
Use
for i=15, 29*10+15, 29 do
for j=15, 29*10+15, 29 do
local bubble = display.newImageRect("bubble.png", 23,23)
bubble.x = i
bubble.y = j
print("j",j)
end
print("i",i)
end
or
for i=0, 10 do
for j=0, 10 do
local bubble = display.newImageRect("bubble.png", 23,23)
bubble.x = 15 + i * 29
bubble.y = 15 + j * 29
...

Framer Studio, iOS Messages "select text"

With Framer Studio, I'm trying to replicate the iOS Messages App's "select text" feature as seen below:
Particularly, I want the zoomed in bubble to show up on any location when I press and hold.
Here is an example Chris Aga posted in the Framer.js Facebook group: http://share.framerjs.com/78aqs01eogh9/
So what you want to do is, first check for longpress:
screen.on Events.TouchStart, (event) ->
isHeld = true
Utils.delay .25, () ->
if isHeld then triggerLongHold(event)
To normalize mouse and touch event coordinates we're using the Pointer Module. So you'll need to include the module in your project.
After that move the magnifying glass layer to wherever the long press is happening:
triggerLongHold = (event) ->
mask.opacity = 1
shadow.opacity = 1
pointerValues = Pointer.screen(event, screen)
mask.x = pointerValues.x - mask.width / 2
mask.y = pointerValues.y - mask.height
bgMagnified.x = -2 * pointerValues.x + 140
bgMagnified.y = -2 * pointerValues.y + 120
and update its position if the user moves the finger/mouse:
screen.on Events.TouchMove, (event) ->
if isHeld
pointerValues = Pointer.screen(event, screen)
mask.x = pointerValues.x - mask.width / 2
mask.y = pointerValues.y - mask.height
bgMagnified.x = -2 * pointerValues.x + 140
bgMagnified.y = -2 * pointerValues.y + 120
Hope this will get you started!

Corona SDK Lua: Moving items from one table to another

I'm new to corona and was trying to do some kind of object pooling on moving platforms. When they exit the screen theyre moved from visibleBlocks to blocks. When I log counts of both my tables the numbers dont match the way they should.. and there are long gaps in my blocks appearing on screen.
My blocks generation:
local color = 'red'
for i = 1, 10 do
local block = display.newRect( 0, 0, 60, 2 )
block.index = i
block.name = 'block'
block.isVisible = false
physics.addBody( block, 'static' )
blocks[i] = block
sceneGroup:insert( block )
block.color = color
color = switchColor(block)
end
code detecting when blocks left the screen
function update()
for k, block in pairs(visibleBlocks) do
block.y = block.y - 1
if block.y < 0 then
removeBlock(block)
end
end
removeblock code
function removeBlock(block)
block.isVisible = false
block.isBodyActive = false
blocks[block.index] = block
visibleBlocks[block.index] = nil
print (' ')
print( 'blocks: ' .. #blocks)
print( 'visible blocks: ' .. #visibleBlocks )
end
addblock which is executed on a timer
function addBlock()
local block = table.remove( blocks )
if block ~= nil then
block.isVisible = true
block.isBodyActive = true
visibleBlocks[block.index] = block
block.x = math.random(
block.contentWidth/2 + 20,
display.contentWidth - block.contentWidth/2 - 20
)
block.y = display.contentHeight
end
end
my console output looks like this:
Oct 23 08:50:16.281: blocks: 0
Oct 23 08:50:16.281: visible blocks: 9
Oct 23 08:50:17.289:
Oct 23 08:50:17.290: blocks: 0
Oct 23 08:50:17.290: visible blocks: 8
Oct 23 08:50:18.329:
Oct 23 08:50:18.329: blocks: 10
Oct 23 08:50:18.329: visible blocks: 7
Oct 23 08:50:19.353:
Oct 23 08:50:19.354: blocks: 9
Oct 23 08:50:19.354: visible blocks: 6
Oct 23 08:50:20.313:
Oct 23 08:50:20.314: blocks: 8
Oct 23 08:50:20.314: visible blocks: 5
Oct 23 08:50:21.339:
Oct 23 08:50:21.340: blocks: 0
Oct 23 08:50:21.340: visible blocks: 10
Oct 23 08:50:22.376:
Oct 23 08:50:22.376: blocks: 7
Oct 23 08:50:22.376: visible blocks: 10
Oct 23 08:50:23.390:
Oct 23 08:50:23.390: blocks: 6
Oct 23 08:50:23.390: visible blocks: 10
Oct 23 08:50:24.392:
Oct 23 08:50:24.393: blocks: 5
Oct 23 08:50:24.393: visible blocks: 10
Oct 23 08:50:25.457:
Oct 23 08:50:25.457: blocks: 4
Oct 23 08:50:25.458: visible blocks: 10
these numbers should always add up to 10 right? something isnt quite right here
By saying visibleBlocks[block.index] = nil in removeBlock, you are creating holes in your "array", which means what # does is no longer clearly defined. As an example,
function footest( t ) print( ("%d,%s"):format( #t, tostring( t[2] ) ) ) end
footest { 1, nil, 3 }
--> 3,nil
footest { 1, [3] = 3 }
--> 1,nil
t = { 1, 2, 3 } ; t[2] = nil ; footest( t )
--> 3,nil
u = { 1, 2, 3 } ; u[1] = nil ; footest( u )
--> 3,2
u[2] = nil ; footest( u )
--> 3,nil
u[3] = nil ; footest( u )
--> 0,nil
(at least this is what currently happens on my machine… While you could look at the source and find out what will happen in all of these cases for the particular version you're using, the reference manual just says that what happens is undefined.)
So how to fix this?
One way of going about this would be to use table.remove instead of nil-ing fields. (table.remove( t, n ) will shift all elements "right of" n in the "array" one to the left to close the gap, that is for
t = { [1] = 1, [2] = 2, [3] = 3 }
saying
table.remove( t, 1 )
results in
t = { [1] = 2, [2] = 3, [3] = nil }
and not leaving a gap inside the array.) This works well when you depend on the order of things in the table/"array" but not on their absolute position.
Unfortunately, it seems you're relying on fixed positions for all blocks (block.index) – if so, this won't work. (If this does work and I'm just mis-interpreting your code, it's probably the simplest way to fix this.)
So a better way might be to assign false instead of nil. You'll have to adjust update (and maybe other code that I didn't see), but the changes are minor:
Your
function update()
for k, block in pairs(visibleBlocks) do
block.y = block.y - 1
if block.y < 0 then
removeBlock(block)
end
end
end
turns into
function update()
for k, block in ipairs(visibleBlocks) do
if block then
block.y = block.y - 1
if block.y < 0 then
removeBlock(block)
end
end
end
end
The first change – replacing pairs with ipairs – is something that you should do anyway whenever you're using a table as an array. (ipairs will stop at the first gap, which means if you accidentally create a hole, a lot of stuff will be missing and you get a pretty obvious error that's easier to debug than those minor glitches. Also, if your array contains holes, pairs may not iterate over everything in ascending order – try it with t = { 1, 2, 3, [9] = 9, [12] = 12 }, iterating with pairs may produce the order 1, 2, 3, 12, 9!)
The only other change is checking if block then …, because some blocks may be absent, as represented by false, and will not silently be skipped like when using nil and pairs.
The result will be good if you depend on position (and, implicitly, order) of elements in the table/"array", and the "is this actually a block?"-check isn't too bad.
A third option – if you're relying neither on the order nor on the absolute position of elements – would be not trying to use the table as an array. Just use each block as a key and assign a dummy value (commonly true) to its entry. (As a bonus, you don't need to remember an extra block.index – the block is the index!)
To add a block, just say blocks[block] = true, to remove, just say blocks[block] = nil. To iterate over all blocks,
for block in pairs( blocks ) do
…
end
but if you need to count the blocks, you'll need a function like
function size( t )
local count = 0
for _ in pairs( t ) do count = count + 1 end
return count
end
This version will break horribly when you rely on the relative order as the drawing order or something like that: Whenever you insert an element, the order of all entries may change completely, which would result in blocks randomly popping above/below others. Compare:
t = { [5] = 1, [2] = 1, [8] = 1 }
for k in pairs( t ) do print( k ) end
--> 8, 5, 2
t[3] = 1
for k in pairs( t ) do print( k ) end
--> 8, 5, 2, 3
t[6] = 1
for k in pairs( t ) do print( k ) end
--> 2, 3, 5, 6, 8
(and you could get a completely different order if you run this.)
If this potential problem doesn't apply this may actually result in the simplest code overall (even though you'll probably have to restructure a bit more.)

Scintilla fold margin icons

The following code I use sets a Scintilla window for folding:
local SCI_STYLECLEARALL = 2050
local SCI_SETMARGINMASKN = 2244
local SCI_SETMARGINSENSITIVEN = 2246
local SCI_STYLESETFORE = 2051
local SCI_MARKERDEFINE = 2040
local SC_MARKNUM_FOLDEROPEN = 31
local SC_MARK_BOXMINUS = 14
local SC_MARKNUM_FOLDER = 30
local SC_MARK_BOXPLUS = 12
local SC_MARKNUM_FOLDERSUB = 29
local SC_MARK_VLINE = 9
local SC_MARKNUM_FOLDERTAIL = 28
local SC_MARK_LCORNERCURVE = 16
local SCI_MARKERSETFORE = 2041
local SCI_MARKERSETBACK = 2042
local SCI_SETFOLDMARGINCOLOUR = 2290
local SCI_USEPOPUP = 2371
local SCI_SETMARGINWIDTHN = 2242
local SCI_STYLESETSIZE = 2055
Scintilla.SendMessage(Ctrl,SCI_STYLECLEARALL,0,0)
Scintilla.SendMessage(Ctrl,SCI_SETMARGINWIDTHN,1,0)
Scintilla.SendMessage(Ctrl,SCI_SETMARGINSENSITIVEN,2,1)
Scintilla.SendMessage(Ctrl,SCI_SETMARGINMASKN,2,-33554432)
Scintilla.SendMessage(Ctrl,SCI_STYLESETFORE,32,12632256)
Scintilla.SendMessage(Ctrl,SCI_MARKERDEFINE,SC_MARKNUM_FOLDEROPEN,SC_MARK_BOXMINUS)
Scintilla.SendMessage(Ctrl,SCI_MARKERDEFINE,SC_MARKNUM_FOLDER,SC_MARK_BOXPLUS)
Scintilla.SendMessage(Ctrl,SCI_MARKERDEFINE,SC_MARKNUM_FOLDERSUB,SC_MARK_VLINE)
Scintilla.SendMessage(Ctrl,SCI_MARKERDEFINE,SC_MARKNUM_FOLDERTAIL,SC_MARK_LCORNERCURVE)
Scintilla.SendMessage(Ctrl,SCI_MARKERSETFORE,SC_MARKNUM_FOLDER,12632256)
Scintilla.SendMessage(Ctrl,SCI_MARKERSETBACK,SC_MARKNUM_FOLDER,16777215)
Scintilla.SendMessage(Ctrl,SCI_MARKERSETFORE,SC_MARKNUM_FOLDEROPEN,12632256)
Scintilla.SendMessage(Ctrl,SCI_MARKERSETBACK,SC_MARKNUM_FOLDEROPEN,16777215)
Scintilla.SendMessage(Ctrl,SCI_MARKERSETBACK,SC_MARKNUM_FOLDERSUB,12632256)
Scintilla.SendMessage(Ctrl,SCI_MARKERSETBACK,SC_MARKNUM_FOLDERTAIL,12632256)
Scintilla.SendMessage(Ctrl,SCI_SETMARGINWIDTHN,2,20)
Scintilla.SendMessage(Ctrl,SCI_USEPOPUP,0,0)
Scintilla.SendMessage(Ctrl,SCI_SETFOLDMARGINCOLOUR,1,16777215)
Scintilla.SendMessage(Ctrl,SCI_STYLESETSIZE,32,10)
but for whatever reason the default circle icon for the fold open/close does not get overwritten by the new value so the circle shows below the new selection:
have tried SCI_MARKERDELETEALL and SCI_MARKERDELETE to try to remove the default icon before applying the new one but it has no effect, how do I get rid of the offending circle?
The square is the default Scintilla image and according to the docs it should not look like that (Box +, Box -):
You need to set all folder markers for them to be drawn properly.

how to use table elements

I'm displaying titles of movies as letter images e.g. A separate image for each letter. Each letter can then be dragged in a space/container. this is my code for displaying the container
posX = {}
posY = 124
px = 10
containers = {}
for i = 1, #letters do
if(letters[i]==" ") then
px = px + 10
-- print(posX[i])
-- table.remove(posX, posX[i])
else
posX[i] = px
containers[i] = display.newImage( "Round1_blue_tileEnlarged 40x40.png", posX[i],posY )
px = px + 40
end
end
As you can see I am checking for a space e.g if batman begins was the title, I have no problems if the title is a single word, but adding the space is adding another element to my array that is causing an error when im placing an objecet in my containers. You can see in the 'if' im just adding a space but I dont want this to be an element of my table posX
I am not sure I understand your question well but if I do here is your problem: you are using i as the index in posX but i is incremented by the for loop even for spaces. That results in holes in the posX and containers tables.
You can fix that in several ways, here is a trivial one:
posX = {}
posY = 124
px = 10
containers = {}
local j = 1
for i = 1,#letters do
if(letters[i]==" ") then
px = px + 10
else
posX[j] = px
containers[j] = display.newImage( "Round1_blue_tileEnlarged 40x40.png", posX[j],posY )
px = px + 40
j = j + 1
end
end
You could also use #posX instead of j.

Resources