How to set focus on a client under mouse cursor when a tag is changed? - awesome-wm

When I switch to another tag, a new client gets selected, but it is sometimes not a client that I have my mouse cursor over. To get a client under my mouse pointer focused, I have to either click somewhere on it, or switch to it with Mod4+j / k, or move mouse cursor out and back on that client.
I want awesome to give focus to a client that is under the mouse cursor whenever a tag is changed. How do I do that?
I found a function mouse.object_under_pointer() that finds the client I need, but I don't know when to call that function. Should I connect a handler to some particular signal? I tried connecting to various signals from Signals page on the wiki and checking with naughty.notify() if that is the right signal, but none of them were triggered when I was switching between tags.

This code did the trick, however there should be a better way to do this than setting up a huge 200 ms timer (smaller timeouts didn't properly focus some clients for me, but you can try setting a smaller one).
tag.connect_signal(
"property::selected",
function (t)
local selected = tostring(t.selected) == "false"
if selected then
local focus_timer = timer({ timeout = 0.2 })
focus_timer:connect_signal("timeout", function()
local c = awful.mouse.client_under_pointer()
if not (c == nil) then
client.focus = c
c:raise()
end
focus_timer:stop()
end)
focus_timer:start()
end
end
)
tag is this global object, so you should just place this code anywhere in your rc.lua.

Two things should be done:
First, you should remove require("awful.autofocus") from your config, so that this module no longer tries to focus some client via the focus history when you switch tags.
Then, this code works for me:
do
local pending = false
local glib = require("lgi").GLib
tag.connect_signal("property::selected", function()
if not pending then
pending = true
glib.idle_add(glib.PRIORITY_DEFAULT_IDLE, function()
pending = false
local c = mouse.current_client
if c then
client.focus = c
end
return false
end)
end
end)
end
This uses GLib directly to get a callback for when no other events are pending. This should mean that "everything else" was handled.

I know this is pretty old, but it helped me to come up with this
function focus_client_under_mouse()
gears.timer( { timeout = 0.1,
autostart = true,
single_shot = true,
callback = function()
local n = mouse.object_under_pointer()
if n ~= nil and n ~= client.focus then
client.focus = n end
end
} )
end
screen.connect_signal( "tag::history::update", focus_client_under_mouse )

Related

ALT + TAB behaviour implementation

I'm trying to implement ALT + TAB behaviour.
I want to know when a user is holding the ALT key.
Why does this release function not work?
awful.key(
{},
'Alt_L',
function()
altHold = true
end,
function()
altHold = false
end
),
IMPRACTICAL SOLUTION:
awful.key(
{},
'Alt_L',
function()
altHold = true
end
),
awful.key(
{'Mod1'},
'Alt_L',
nil,
function()
altHold = false
end
)
This works, but any other hotkeys with ALT no longer work.
OTHER SOLUTION:
keygrabber.run(
function (mod, key, event)
-- Stop alt-tabbing when the alt-key is released
if gears.table.hasitem(mod, "Mod1") then
if (key == "Alt_L" or key == "Escape") and event == "release" then
-- Make it visible
if key == "Escape" then
-- Cancel client selection
end
else
-- Raise clients in order to restore history
-- raise chosen client on top of all
-- restore minimized clients
end
end
keygrabber.stop()
-- Pressed tab
elseif key == "Tab" and event == "press" then
if gears.table.hasitem(mod, "Shift") then
-- Move to previous client on Shift-Tab
cyclePreview(-1)
else
-- Move to next client on each Tab-press
cyclePreview( 1)
end
end
end
end
)
This is a slightly modified version from Troglobit:
https://github.com/troglobit/awesome-switcher/blob/master/init.lua#L470-L525\
This gets called when ALT + TAB is pressed.
While holding ALT, the next TAB press calls previewCycle() function.
If ALT is released it selects the chosen client.
ESCAPE cancels the selection.
Random guess: When the key is released, the "alt" modifier is active, so you need a keybinding with Mod1 as modifier (is Alt Mod1? I'm not entirely sure). But of course, that key binding would then not react to key presses, so you need two.

How to open the browser in collapsed form?

The code:
Local $iPID=ShellExecute("C:\Program Files\Mozilla Firefox\firefox.exe", "","","", #SW_MINIMIZE);
How to open the browser in collapsed form?
; Optional debugging feature.
Opt('TrayIconDebug', True)
; Run Firefox if not running.
If Not ProcessExists('firefox.exe') Then
ShellExecute('"C:\Program Files\Mozilla Firefox\firefox.exe"')
EndIf
; Wait for a window to match the class.
WinWait('[CLASS:MozillaWindowClass]')
$hFirefox = 0
$iAbort = 5
Do
Sleep(1000)
; Get all class windows into an array.
$aWList = WinList('[CLASS:MozillaWindowClass]')
For $i1 = 1 To UBound($aWList) -1
; Get the visible window from the window handle.
If BitAND(WinGetState($aWList[$i1][1]), 2) Then
$hFirefox = $aWList[$i1][1]
_WinState($aWList[$i1][1], $aWList[$i1][0], True)
ExitLoop 2
Else
_WinState($aWList[$i1][1], $aWList[$i1][0], False)
EndIf
Next
$iAbort -= 1
Until Not WinExists('[CLASS:MozillaWindowClass]') Or $iAbort = 0
; Minimize the visible window.
If WinSetState($hFirefox, '', #SW_MINIMIZE) Then
ConsoleWrite('A Firefox window has been minimized.' & #CRLF)
EndIf
Exit
Func _WinState($hWinHandle, $sWinTitle, $bWinVisible = False)
; Debug output for visible state of a window.
Local $sWinVisible = $bWinVisible ? 'True' : 'False'
ConsoleWrite(StringFormat('Handle: %s Visible: %-5s Title: %s', $hWinHandle, $sWinVisible, $sWinTitle) & #CRLF)
EndFunc
Even if you set a Firefox shortcut to minimize and use it
to start Firefox, Firefox may not minimize at startup.
This is why the show flag of #SW_MINIMIZE for the
ShellExecute function may not work.
A -tray argument exists though I cannot get it to work as
mentioned in Command Line Options.
To minimize at startup, the code provided may help.
It will find the 1st window that is visible of the class
MozillaWindowClass, and will attempt to minimize it.
The variable $hFirefox may contain the handle of the
visible Firefox window which can be used after the Do
loop has complete.
Some code is optional, i.e. _WinState() is used to output
debug information to console to know if the the window search
for the visible window is working OK.

Robot Framework: Timed out waiting for page load

We have run our Robot Framework environment nearly one year without any problems, but now we get the error message:
TimeoutException: Message: Timed out waiting for page load.
Stacktrace:
at Utils.initWebLoadingListener/< (file:///tmp/tmp77bOby/webdriver-py-profilecopy/extensions/fxdriver#googlecode.com/components/driver-component.js:9089)
at WebLoadingListener/e (file:///tmp/tmp77bOby/webdriver-py-profilecopy/extensions/fxdriver#googlecode.com/components/driver-component.js:5145)
at WebLoadingListener/< (file:///tmp/tmp77bOby/webdriver-py-profilecopy/extensions/fxdriver#googlecode.com/components/driver-component.js:5153)
at fxdriver.Timer.prototype.setTimeout/<.notify (file:///tmp/tmp77bOby/webdriver-py-profilecopy/extensions/fxdriver#googlecode.com/components/driver-component.js:625)
What could be problem? I checked the disk space and there are disk space left.
A timeout error can have a laundry list of possible issues. Loading a page after a year of smooth operation narrows it down a little, but there are still many possibilities. Connection speeds sometimes change, sometimes the page you're loading up has added features that cause it to take longer to load or was just written poorly so it loads slowly... you get the idea. Without the code of the page or your code to look at, I can only suggest two fixes.
First, in the code of Selenium2Library, there is a timeout variable somewhere that can be set with Set Selenium Timeout. The default is 5 seconds, but if your page is taking longer to load, then increasing it might solve your problem. This assumes that your page loads at a reasonable rate in manual testing and that opening it is the least of your concerns.
Second, it's possible that you're testing an AngularJS application, not a normal website. If that's true, then you're going to want to use ExtendedSelenium2Library, not Selenium2Library. ExtendedSelenium2Library is better-equipped to deal with AngularJS applications and includes code to wait for Angular applications to load.
The old webdriver.xpi is buggy about page load handling. Timers are not correctly canceled, resulting in random windows switches and memory leaks. I copy here some replacement code that may be useful to anybody.
var WebLoadingListener = function(a, b, c, d) {
if ("none" == Utils.getPageLoadStrategy()) {
b(!1, !0);
} else {
this.logger = fxdriver.logging.getLogger("fxdriver.WebLoadingListener");
this.loadingListenerTimer = new fxdriver.Timer;
this.browser = a;
var self = this;
var e = function(a, c) {
self.destroy ();
b(a, c);
};
this.handler = buildHandler(a, e, d);
a.addProgressListener(this.handler);
-1 == c && (c = 18E5);
this.loadingListenerTimer.setTimeout(function() {
e(!0);
}, c);
WebLoadingListener.listeners [this.handler] = this;
goog.log.warning(this.logger, "WebLoadingListener created [" + Object.keys (WebLoadingListener.listeners).length + "] " + d.document.location);
}
};
WebLoadingListener.listeners = {};
WebLoadingListener.removeListener = function(a, b) {
if (b.constructor !== WebLoadingListener) {
b = WebLoadingListener.listeners [b];
}
b.destroy ();
};
WebLoadingListener.prototype.destroy = function() {
if (this.browser) {
this.loadingListenerTimer.cancel();
this.browser.removeProgressListener && this.handler && this.browser.removeProgressListener(this.handler);
delete WebLoadingListener.listeners [this.handler]
this.loadingListenerTimer = undefined;
this.browser = undefined;
goog.log.warning(this.logger, "WebLoadingListener destroyed [" + Object.keys (WebLoadingListener.listeners).length + "]");
}
};
enter code here

Knowing button press in corona sdk

In my corona aplication, I've a widget button to move an image. I was able to find the onPress method, but failed to find a method to check whether the button is still pressed. So that user don't have to tap the same button over and over again for moving the image...
Code:
function move( event )
local phase = event.phase
if "began" == phase then
define_robo()
image.x=image.x+2;
end
end
local movebtn = widget.newButton
{
width = 50,
height = 50,
defaultFile = "left.png",
overFile = "left.png",
onPress = move,
}
Any help is appreciable...
If your question is that you would like to know when the user's finger is moved, or when he releases the button, you can add handlers for those events:
"moved" a finger moved on the screen.
"ended" a finger was lifted from the screen.
"began" only handles when he starts touching the screen.
So your move function would be like:
function move( event )
local phase = event.phase
if "began" == phase then
define_robo()
image.x=image.x+2;
elseif "moved" == phase then
-- your moved code
elseif "ended" == phase then
-- your ended code
end
end
-- Updated according to comment:
Use this, replacing nDelay by the delay between each move, and nTimes by the number of times you wanna do the move:
function move( event )
local phase = event.phase
if "began" == phase then
local nDelay = 1000
local nTimes = 3
define_robo()
timer.performWithDelay(nDelay, function() image.x=image.x+2 end, nTimes )
end
end
Try this:
local image = display.newRect(100,100,50,50) -- Your image
local timer_1 -- timer
local function move()
print("move...")
image.x=image.x+2;
timer_1 = timer.performWithDelay(10,move,1) -- you can set the time as per your need
end
local function stopMove()
print("stopMove...")
if(timer_1)then timer.cancel(timer_1) end
end
local movebtn = widget.newButton {
width = 50,
height = 50,
defaultFile = "obj1.png",
overFile = "obj1.png",
onPress = move, -- This will get called when you 'press' the button
onRelease = stopMove, -- This will get called when you 'release' the button
}
Keep coding................ :)

Awesome wm keyup and keydown events

I'm using Awesome Window Manager. I want to show my top bar by pressing mod4 and then hide it when I release. I tired passing "keyup Mod4" to awful.key but it does not work. How can I tell it that I want to trigger an event on keyup?
Try
`awful.key({ modkey }, "", nil, function () staff here end)`
3rd param is handler for "release" event when passed.
I wanted the same thing! After some research I came up with:
Use external program to execute echo 'mywibox[1].visible = true' | awesome-client when mod4 is pressed and echo 'mywibox[1].visible = false' | awesome-client when released.
Use other key, not modifier, like Menu (near right Ctrl), because for some reason you can't hook up press and release event to mod4 (or it just doesn't work).
Here is my solution (timer is required because pressed key sends events as long as it is pressed):
-- Put it somewhere at the beginning
presswait = { started = false }
-- Put it in key bindings section (globalkeys = within awful.table.join)
awful.key({ }, "Menu", function()
if presswait.started then
presswait:stop()
else
-- One second to tell if key is released
presswait = timer({ timeout = 1 })
presswait:connect_signal("timeout", function()
presswait:stop()
-- Key is released
for i = 1, screen.count() do
mywibox[i].visible = false
end
end)
-- Key is pressed
for i = 1, screen.count() do
mywibox[i].visible = true
end
end
presswait:start()
end)
You could connect a signal to the key object:
key.connect_signal("press", function(k)
-- Analyze k and act accordingly
end)
More about signals here:
http://awesome.naquadah.org/wiki/Signals
Using the first suggestion from https://stackoverflow.com/a/21837280/2656413
I wrote this python script: https://github.com/grandchild/autohidewibox
What it does is, it runs xinput in the background and parses its output. You could also parse /dev/input/event1 directly in python, but I was lazy.
It then pipes the following lua code to awesome every time the key is pressed or released:
echo 'for i, box in pairs(mywibox) do box.visible = true end' | awesome-client
and
echo 'for i, box in pairs(mywibox) do box.visible = false end' | awesome-client
respectively.
Update:
For awesome 4+ use:
echo "for s in screen do s.mywibox.visible = false end" | awesome-client
or true.

Resources