How to make Electron tray click events working reliably? - electron

In my OSX Electron app I have a tray icon that I would like to toggle between opening and closing the Electron app window. Similar to how clicking on the OSX Dropbox tray icon will open and close the Dropbox tray menu, no matter how fast you click the tray icon.
Here is the code I'm using:
tray.on('click', function(e){
if (mainWindow.isVisible()) {
mainWindow.hide()
} else {
mainWindow.show()
}
});
This works if you click slowly (wait a second between clicks) however if you click repeatedly, more than 1x in a second, the click fails and nothing happens. I couldn't find any type of delays in the docs. Any ideas on what's going on and how to make the click event work reliably?

The problem you're describing is easy to reproduce. The result you're getting is not a bug or a wrong implementation on your side but it's the expected result regarding the current way Electron is handling these click events on a tray element.
The class Tray exposes 3 events relative to click: click, double-click and right-click.
If you use the right-click event, you're not going to have this issue, you can click as fast as you want, you'll get your callback called every times.
The Electron code for macOS for example to handle this event is the following:
- (void)rightMouseUp:(NSEvent*)event {
trayIcon_->NotifyRightClicked(
[self getBoundsFromEvent:event],
ui::EventFlagsFromModifiers([event modifierFlags]));
}
For every right click, they're firing the right-click event and that's it.
Now if we take a look at how the left click are handled, the code is slightly different:
- (void)mouseUp:(NSEvent*)event {
// ...
// Truncated to only show the relevant part...
// ...
// Single click event.
if (event.clickCount == 1)
trayIcon_->NotifyClicked(
[self getBoundsFromEvent:event],
ui::EventFlagsFromModifiers([event modifierFlags]));
// Double click event.
if (event.clickCount == 2)
trayIcon_->NotifyDoubleClicked(
[self getBoundsFromEvent:event],
ui::EventFlagsFromModifiers([event modifierFlags]));
[self setNeedsDisplay:YES];
}
When the tray icon get clicked multiple times, the event.clickCount doesn't always return 1. Instead, it returns a value that counts the clicked times.
So when you're click the tray icon very fast, event.clickCount will have a value greater than 2 and they're only emitting an event when the value is 1 or 2 and if it's not the case, they don't have any fallback, they simply don't emit any event. That's the result you're seeing in your tests when clicking fast enough.
So without modifying the Electron implementation yourself, submitting an issue or a pull request, you can't at the moment avoid this behaviour.

Electron 3.0 introduced an API that prevents waiting for double-click.
// Ignore double click events for the tray icon
tray.setIgnoreDoubleClickEvents(true)
"Sets the option to ignore double click events. Ignoring these events allows you to detect every individual click of the tray icon. This value is set to false by default."
Related Docs | Release Notes for Electron 3.0

Related

click on svg element is not working in cypress

I am having a scenario to click on a svg element, tried the following code, it is not throwing any error. it is clicking but the element state is not changed. tried force click also.
cy.xpath("(//app-job[contains(#class,'selected')]//highcharts-chart[#id='GMF_K_CHART']//*[name()='svg']//*[name()='g' and #class='highcharts-series-group']//*[name()='g' and #clip-path='none' and not(#visibility)])[4]//*[name()='path'][4]")
.click()
Graph how displaying after clcik
But it should be if clicked properly
I tried multiple combination of clicks
`.click({force: true})
.click()
.trigger('change')
.trigger('focus')
.click()`
Please make sure that you're selecting the svg element and then, use trigger() to click on that element.
cy.get('<svg element>').trigger('click')
It seems that cypress expects that click is preceded by mouse hover. In that case, make sure that cypress hovers the mouse over the point (the tooltip must fire) and then let the cypress perform a click event on the point.
cy.get(".highcharts-container")
.get(".highcharts-point")
.eq(1)
.trigger("mousemove");
cy.wait(1000);
cy.get(".highcharts-container")
.get(".highcharts-point")
.eq(1)
.trigger("click");
If that didn't work, it would be possible that some cypress event is not correctly triggered; in that case try the following workaround:
cy.get(".highcharts-container")
.get(".highcharts-point")
.eq(1)
.trigger("mousemove").trigger("mousemove");
cy.wait(1000);
cy.get(".highcharts-container")
.get(".highcharts-point")
.eq(1)
.trigger("click").trigger("click");

Appium Touch Actions 'Press' and 'Move To' is not working in iOS chrome app

I am learning mobile automation and I came across a scenario some thing like this
Launch chrome app in iOS
Load https://www.google.com
Hold/Press and pull down banner web element on the web page which will display some overlay with three options 'New tab, Reload & Close tab' (note: overlay will lost on releasing the banner web element)
Tap on the new tab button
So far I have written below script in python
def Test(self, driver_provider):
single_tap = appium.webdriver.common.touch_action.TouchAction(driver_provider.driver)
element = driver_provider.driver.find_element_by_accessibility_id('NTPHomeFakeOmniboxAccessibilityID')
single_tap.tap(element=element).perform()
element.send_keys('https://www.google.com')
single_tap.tap(element=driver_provider.driver.find_element_by_accessibility_id('Go')).perform()
time.sleep(1)
#Press banner and pull down will display the over scroll actions
#Then move to left to tap on the add button
banner_element = driver_provider.driver.find_element_by_accessibility_id('banner')
screen_size = driver_provider.driver.get_window_size()
height = screen_size.get('height')
width = screen_size.get('width')
single_tap.press(banner_element, x=banner_element.size.get(
'width')/2, y=banner_element.size.get('height')/2).wait(1).move_to(banner_element,
x=width/2, y=height/2).wait(0.5).move_to(banner_element, x=0, y=height/2).release().perform()
for some reason press and move_to actions are not happening and there is no error returned as well, I am not clear what went wrong here. Please share your view on what went wrong thanks.
it's failing to perform press and move to because of wait value is very small. When I use the wait(500) then the press and move to is happening.
single_tap.press(banner_element, x=banner_element.size.get(
'width')/2, y=banner_element.size.get('height')/2).wait(500).move_to(banner_element,
x=width/2, y=height/2).wait(500).move_to(banner_element, x=0, y=height/2).wait(500).release().perform()

Showmodaldialog help button in title bar

I have an HTA which opens a showmodaldialog and this JavaScript code in the dialog page:
function helpButton(){
document.body.style.curosor = "help";
my_div.onclick = function(){alert("Help for the div is displayed here")}
}
I want a help button in the title bar of the showmodaldialog, like on the picture below:
(don't mind about the fact that the picture's in French, it's my computer's language)
When I push on that help button, I want it to execute the helpButton() function.
There was showModalDialog('path', 'arg', 'help:yes'); and you could attach an onhelp handler within the opened dialog's window. However, this dialog property is obsoleted - since IE9, if I'd recall correctly - and can't be returned by downgrading the app using X-UA when running a HTA with a newer IE.
You still can set onhelp, and call it by hitting F1:
window.onhelp = function () {
alert('Help is asked.');
};

iPhone Safari keyboard to say next vs go

I have a website that is optimized to work on iOS devices. But the problem is that the keyboard always says Go as user fills the form. How do I get the keyboard to say Next until the last entry on the form, where it should say Go? Or alternatively, how do I disable the Enter button entirely?
Again, this is a website. It works everywhere websites work: in browsers. Except I have having this particular problem in Safari on mobile devices.
while changing the input type gives you some control of the keyboard layout the return key label in IOS cannot be customized.
Other than changing it to say Search there are no customizations available. You can disable the functionality of the button using something like this injQuery:
$("#myForm input").live("keyup", function(evt) {
if (evt.keyCode === 13) {
$("#myForm").trigger("submit");
}
});

onMouseMove listener only starts receiving events after cursor leaves and re-enters the document

I have CanvasElement which requests pointer lock on click, and then repeatedly passes movementX and movementY to a function using an onMouseMove listener (I'm testing first person controls).
It works fine the first time (immediately after page load), but if I press escape and click the canvas again it successfully locks the cursor but doesn't generate a MouseEvent to pass to the onMouseMove listener.
If I press escape and move the mouse outside of the document (anywhere that's not governed by the markup), move it back into the document and click the canvas, everything works perfectly again.
Any ideas what's causing this odd behaviour?
_canvas.onMouseMove.listen((MouseEvent e) {
if (document.pointerLockElement == _canvas) {
print(e.movement); // debug print
orientateCamera(e.movement);
}
});
_canvas.onClick.listen((e) {
if (document.pointerLockElement == null) {
_canvas.requestPointerLock();
}
});
All the described behaviour is contained within these lines of code.
I have no idea what element.requestPointerLock() does but
MDN - Element.requestPointerLock states that you should listen to pointerlockchange and pointerlockerror to see if the request was successful. There is also a document.exitPointerLock() which you don't seem to use.
MDN Pointer Lock API seems to be a good introduction.

Resources