How to open app window on toolbar click in safari app extension? - swift

I'd like to open an application/extension Window when user clicks toolbar item in safari. This is not question about extension's Popover feature. The main reason is to close/hide the window on deactivation AND user action (both conditions are required to work).
Safari App Extension (meaning the new preferred/forced way to create extensions for safari by Apple) can open a Popover or call a Command when toolbar item is clicked. But it cannot be hidden programatically (https://forums.developer.apple.com/thread/105817). Per answer by bweinstein it's work in progress by apple devs.
My use case is about Window containing WKWebView with loaded webpage. When user clicks anything in there I want to open a page in Safari's new tab (this part already works for me in Popover mode) and close the window immediately (this doesn't work for me yet)
So my thinking here was to avoid integrated Popover feature. I'd like to show Window instead when Command (override func toolbarItemClicked(in window: SFSafariWindow) {}) is called.
I know this is somehow doable as e.g. agilebits' 1Password extension is doing exactly this: when you click a toolbar item, window is displayed having no close/minimize buttons, no menu etc. It works exactly as I need, but I don't know how to achieve that.
I don't know whether to define the view as part of Safari extension or as part of Storyboard of containing app and how to access it programatically and show it on screen when user clicks the toolbar item.
As I am new to macos development I don't really have a code to share. Important part from my POV:
- Info.plist's NSExtension->SFSafariToolbarItem->Action is set to Command
As pointed above, feature I need to achieve is to open and close a Window programatically when user clicks toolbar item.
Thanks in advance

Could you not call SFSafarWindow.openTab("httxxx://mysite.com", true, ...) in your toolbarItemClicked
You could also call SFSafariApplication.openWindow API and close SFSafariWindow (by calling windowObject.close() ) -

Related

NSWindow appears inactive but still accepts keyevents

I'm building a status bar app (windowless) on OSX and having trouble with a pesky little UI bug.
The application opens up a preferences window from the status bar menu when a certain menu item is clicked. The bug presents after the following scenario:
A user opens the preference window from the status bar menu
App resigns the active status when the user opens a browser or another app
User clicks the status bar item (to look at some info in the menu) but doesnt click the menuitem to show the preferenceswindow
User closes the other application and clicks on the already opened preferences window again
After this sequence the NSWindow representing the preferences window appears inactive while still accepting key events. By inactive I mean that the close button for the preferences NSWindow is gray unless hovered over, all the textfields don't get a blue focus ring when clicked and buttons with keyEquivalent = "\r" are not blue. The status bar item will also not highlight. It's like some other hidden window is hijacking the visuals of an active window.
This is what the preferences window looks like normally:
This is what it looks like after the scenario I just described:
How do I make it so that when the preferences NSWindow looks active when clicked even if the user has used other apps and clicked the status bar item in the meantime? Note that the window accepts keyevents normally, and the application is active. Even just a step further in how to debug this would be helpful. Ive logged the main/key window and the apps active status in multiple places and everything looks right.
I think I figured it out. Apparently the NSMenu pop up from the statusbar blocks the execution of the application code. Somehow the NSMenu was retaining the focus even if the menu had been closed if the application wasn't active.
Solution was to activate the app if windows are open when clicking on the NSMenu before popUpMenu is called. Note that the popUpMenu must be done slightly later to not block the activation of the app. Something like:
let noWindowsOpen = extraVisibleWindows.count == 0
if (!noWindowsOpen) {
NSApp.activate(ignoringOtherApps: true)
}
Timer.scheduledTimer(withTimeInterval: 0.04, repeats: false) { _ in
self.statusItem.popUp(self.menu)
}
I found the solution on Github for another app that was dealing with similar problems.

Make application not take over menu bar but still have dock icon?

I'm making an application that I want to function like a status bar app, where it doesn't control the menu bar (so if it's open over, say, Firefox, the menu is still the one for Firefox), but I also want people to be able to cmd-tab to it for keyboard navigation purposes. I know about Application is Agent, but that only flips both those things at once. Is there some more granular control elsewhere that allows me to change these aspects individually?

popover view for a status item not responsive to mouse movements

I have been struggling with this and could not find a solution.
I am creating a statusitem app for mac osx using swift. When the item is clicked a popover with a custom view that has a webview in it appears. everything works fine except that after clicking outside and the popover is closed and clicking again on statusitem to show popover this time the view (webview) is not responsive to mouse movement events like mouse hover a link etc.. unless I click inside the popover to activate it. I found a solution by calling NSApp.activateIgnoringOtherApps(true) but this greys out other opened applications like chrome.
Now my question is that, can I make the app active without greying out other apps? dropbox mac app is an example, clicking the item in status bar, opens the popover of dropbox and its responsive to mouse events but other opened apps in the background are not greyed out and they are responsive to mouse movement events, even after clicking inside it doesn't grey out other apps unless a window appear e.g. preferences window or login window. How to achieve this behaviour?
this image shows how webview is not interactive with mouse
the second image show how it is interactive with mouse hover effect on "Advertising Programs" but chrome app is greyed out

iPhone and iPad wordpress menu BAD behavior

On this site : mecanomedic.com, the menu template work fine in "normal" desktop browser, but dont slide down on ipad-iphone device. What can be the problem ?
Some tell me it's a css problem, but HOW safari desktop work ?
The problem is that the menu expansion relies on the user hovering with a mouse. On touch devices like iPads & iPhones, the hovering gesture can't be replicated because there's only one input- touch. If I were you, I'd take a look at Twitter's Bootstrap menu setup and perhaps use media queries to serve up a different menu on smaller screen sizes.
Here's an example of a Bootstrap navigation bar in action (you'll have to inspect the code to see how it works).
Add a href to the top-level <a>'s so that they can be focusable:
Produits
Elements that are focusable receive mouse events and hover styles when the user taps on them.
As #Matt stated, the problem is that your menu relies on a hover event and unfortunately that event is unavailable on touch screen devices.
One way to fix this would be to:
Check if the current user's device is an iOS device
If the device is an iOS device, use javascript to trigger a menu item's "show event" when the menu button is CLICKED instead of ROLLED OVER / HOVERED.
This would result in the menu being shown when the user taps a menu button.

Open "Modal" Widow and close in TabGroup Based Application

Should Also have specified, I am developing this using Titanium Mobile.
I have a tabbed application. I have the need to open a "modal" like window for the purpose of allowing the user to enter some settings.
For example, you click the 3rd tab in the tabGroup. Some logic runs to see if a setting is set before continuing to create the view. The setting is not in place, so a new window animates in asking you to create this setting. After you create the setting, it closes and the view continues to render, or refreshes.
I cannot for the life of me figure this out. I have created the window, animated it into the current tab, and I have even successfully closed it. Getting the view to refresh or re-load is what is difficult. Also, the navigation bar offers the user the ability to navigate back to the window to change the setting, which I also do not want.
Any way to accomplish this?
I have the same need for logging the user into the application.
Use this code:
windowbject.open({modal:true});
This will only works in iOS.
And you want to refresh view which is behind this modal window then you have to add "focus" eventlistener to the window and write code in it.This code will execute when ever window got focus.
So when you close "modal" view then window behind it will get focus.
I hope this will help you.