mirror of
https://github.com/netbirdio/systray.git
synced 2026-05-22 17:08:41 -07:00
Added support for App Window
This commit is contained in:
+3
-3
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/getlantern/systray"
|
||||
"github.com/getlantern/systray/example/icon"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -22,6 +21,7 @@ func main() {
|
||||
}
|
||||
|
||||
func onReady() {
|
||||
systray.EnableAppWindow("Lantern", 1024, 768)
|
||||
systray.SetIcon(icon.Data)
|
||||
systray.SetTitle("Awesome App")
|
||||
systray.SetTooltip("Lantern")
|
||||
@@ -42,7 +42,7 @@ func onReady() {
|
||||
mChecked := systray.AddMenuItem("Unchecked", "Check Me")
|
||||
mEnabled := systray.AddMenuItem("Enabled", "Enabled")
|
||||
systray.AddMenuItem("Ignored", "Ignored")
|
||||
mUrl := systray.AddMenuItem("Open Lantern.org", "my home")
|
||||
mUrl := systray.AddMenuItem("Open UI", "my home")
|
||||
mQuit := systray.AddMenuItem("退出", "Quit the whole app")
|
||||
|
||||
// Sets the icon of a menu item. Only available on Mac.
|
||||
@@ -67,7 +67,7 @@ func onReady() {
|
||||
mEnabled.SetTitle("Disabled")
|
||||
mEnabled.Disable()
|
||||
case <-mUrl.ClickedCh:
|
||||
open.Run("https://www.getlantern.org")
|
||||
systray.ShowAppWindow("https://www.getlantern.org")
|
||||
case <-mToggle.ClickedCh:
|
||||
if shown {
|
||||
mQuitOrig.Hide()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
module github.com/getlantern/systray
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
|
||||
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So=
|
||||
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
|
||||
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk=
|
||||
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc=
|
||||
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
|
||||
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
|
||||
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
|
||||
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
|
||||
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
|
||||
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e h1:VAzdS5Nw68fbf5RZ8RDVlUvPXNU6Z3jtPCK/qvm4FoQ=
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@@ -7,6 +7,8 @@ void setIcon(const char* iconBytes, int length);
|
||||
void setMenuItemIcon(const char* iconBytes, int length, int menuId);
|
||||
void setTitle(char* title);
|
||||
void setTooltip(char* tooltip);
|
||||
void configureAppWindow(char* title, int width, int height);
|
||||
void showAppWindow(char* url);
|
||||
void add_or_update_menu_item(int menuId, char* title, char* tooltip, short disabled, short checked);
|
||||
void add_separator(int menuId);
|
||||
void hide_menu_item(int menuId);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
#include "systray.h"
|
||||
|
||||
NSWindowController *windowController = nil;
|
||||
WKWebView *webView = nil;
|
||||
|
||||
void doConfigureAppWindow(char* title, int width, int height)
|
||||
{
|
||||
if (windowController != nil) {
|
||||
// already configured, ignore
|
||||
return;
|
||||
}
|
||||
|
||||
NSRect frame = NSMakeRect(0, 0, width, height);
|
||||
int mask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable;
|
||||
id window =
|
||||
[[NSWindow alloc] initWithContentRect:frame
|
||||
styleMask:mask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
[window setTitle:[[NSString alloc] initWithUTF8String:title]];
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
[window center];
|
||||
|
||||
NSView *contentView = [window contentView];
|
||||
webView = [[WKWebView alloc] initWithFrame:[contentView bounds]];
|
||||
[webView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[contentView addSubview:webView];
|
||||
[contentView addConstraint:
|
||||
[NSLayoutConstraint constraintWithItem:webView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:contentView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
multiplier:1
|
||||
constant:0]];
|
||||
[contentView addConstraint:
|
||||
[NSLayoutConstraint constraintWithItem:webView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:contentView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
multiplier:1
|
||||
constant:0]];
|
||||
|
||||
// Window controller:
|
||||
windowController = [[NSWindowController alloc] initWithWindow:window];
|
||||
free(title);
|
||||
}
|
||||
|
||||
void configureAppWindow(char* title, int width, int height)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
doConfigureAppWindow(title, width, height);
|
||||
});
|
||||
}
|
||||
|
||||
void doShowAppWindow(char* url)
|
||||
{
|
||||
if (windowController == nil) {
|
||||
// no app window to open
|
||||
return;
|
||||
}
|
||||
id nsURL = [NSURL URLWithString:[[NSString alloc] initWithUTF8String:url]];
|
||||
id req = [[NSURLRequest alloc] initWithURL: nsURL
|
||||
cachePolicy: NSURLRequestUseProtocolCachePolicy
|
||||
timeoutInterval: 5];
|
||||
[webView loadRequest:req];
|
||||
[windowController.window orderFrontRegardless];
|
||||
free(url);
|
||||
}
|
||||
|
||||
void showAppWindow(char* url)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
doShowAppWindow(url);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <webkit2/webkit2.h>
|
||||
|
||||
static GtkWidget *web_window = NULL;
|
||||
static WebKitWebView *webView = NULL;
|
||||
|
||||
static gboolean closeWebViewCb(WebKitWebView* webView, GtkWidget* window);
|
||||
|
||||
void prepareBrowser()
|
||||
{
|
||||
// Create an 800x600 window that will contain the browser instance
|
||||
web_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size(GTK_WINDOW(web_window), 800, 600);
|
||||
|
||||
// Create a browser instance
|
||||
webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
||||
|
||||
// Put the browser area into the web window
|
||||
gtk_container_add(GTK_CONTAINER(web_window), GTK_WIDGET(webView));
|
||||
|
||||
g_signal_connect(webView, "close", G_CALLBACK(closeWebViewCb), web_window);
|
||||
|
||||
// Make sure that when the browser area becomes visible, it will get mouse
|
||||
// and keyboard events
|
||||
gtk_widget_grab_focus(GTK_WIDGET(webView));
|
||||
}
|
||||
|
||||
gboolean do_open_in_browser(gpointer data)
|
||||
{
|
||||
gtk_widget_show_all(web_window);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void openInBrowser(char* url)
|
||||
{
|
||||
// Load a web page into the browser instance
|
||||
webkit_web_view_load_uri(webView, url);
|
||||
|
||||
gdk_threads_add_idle(do_open_in_browser, url);
|
||||
}
|
||||
|
||||
static gboolean closeWebViewCb(WebKitWebView* webView, GtkWidget* window)
|
||||
{
|
||||
gtk_widget_destroy(window);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -70,6 +70,11 @@
|
||||
systray_ready();
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||
{
|
||||
systray_on_exit();
|
||||
|
||||
@@ -23,6 +23,8 @@ typedef struct {
|
||||
short checked;
|
||||
} MenuItemInfo;
|
||||
|
||||
void prepareBrowser();
|
||||
|
||||
int nativeLoop(void) {
|
||||
gtk_init(0, NULL);
|
||||
global_app_indicator = app_indicator_new("systray", "",
|
||||
@@ -31,6 +33,7 @@ int nativeLoop(void) {
|
||||
global_tray_menu = gtk_menu_new();
|
||||
app_indicator_set_menu(global_app_indicator, GTK_MENU(global_tray_menu));
|
||||
systray_ready();
|
||||
prepareBrowser();
|
||||
gtk_main();
|
||||
systray_on_exit();
|
||||
return 0;
|
||||
|
||||
+14
-2
@@ -3,9 +3,10 @@
|
||||
package systray
|
||||
|
||||
/*
|
||||
#cgo linux pkg-config: gtk+-3.0 appindicator3-0.1
|
||||
#cgo linux CFLAGS: -DWEBVIEW_GTK=1
|
||||
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 appindicator3-0.1
|
||||
#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc
|
||||
#cgo darwin LDFLAGS: -framework Cocoa
|
||||
#cgo darwin LDFLAGS: -framework Cocoa -framework WebKit
|
||||
|
||||
#include "systray.h"
|
||||
*/
|
||||
@@ -42,6 +43,17 @@ func SetTooltip(tooltip string) {
|
||||
C.setTooltip(C.CString(tooltip))
|
||||
}
|
||||
|
||||
// EnableAppWindow enables a single application window for this app.
|
||||
func EnableAppWindow(title string, width int, height int) {
|
||||
C.configureAppWindow(C.CString(title), C.int(width), C.int(height))
|
||||
}
|
||||
|
||||
// ShowAppWindow shows the given URL in the application window. Only works if
|
||||
// configureAppWindow has been called first.
|
||||
func ShowAppWindow(url string) {
|
||||
C.showAppWindow(C.CString(url))
|
||||
}
|
||||
|
||||
func addOrUpdateMenuItem(item *MenuItem) {
|
||||
var disabled C.short
|
||||
if item.disabled {
|
||||
|
||||
Reference in New Issue
Block a user