Open hmsjy2017 opened 3 years ago
I have used this in Linux.
More precisely, Argos is a GNOME Shell extension that turns executables' standard output into panel dropdown menus. It is inspired by, and fully compatible with, the BitBar app for macOS. Argos supports many BitBar plugins without modifications, giving you access to a large library of well-tested scripts in addition to being able to write your own.
This software is written in Go, so I think it will not be too difficult to support Windows and Linux.
That's a wrong assumption. The programming language itself is rarely the reason for something to work or not work on certain platforms as there is hardly any popular language that doesn't work on all major platforms.
The reason why GUI applications are harder to port to other platforms is usually because of their GUI toolkits, desktop environments, and often other intricacies of the underlying operating systems. And even though xbar is built using Wails which theoretically allows you to build cross-platform GUI applications that's usually only easy for quite simple windowed applications. As soon as you enter deeper territory of the desktop environment, like docks and menu bars, it becomes more difficult.
So, while adding support for more desktop environments directly to xbar could theoretically be possible it would also add a lot of maintenance overhead. Things would have to be tested and kept up-to-date with all target platforms which are evolving as well. That would take quite some bandwidth away from developling actual features.
That is why I personally would be a big fan of a different approach.
The thing that makes xbar (and BitBar before) so great is the simple protocol between plugins and xbar's UI. This should be somehow formalized and versioned, and maybe even extracted into some kind of library or CLI tool, so that a desktop environment specific UI can be built on top of it.
Argos (as mentioned by @xfangfang) kinda already does this but only loosely and I don't think that there's a formalized or even automatable way for it to ensure compatibility.
The Wails project (the tech that allows us to build the xbar UI and to control the menus) is indeed cross-platform, so when Wails v2 is released, we do expect to be able to build xbar for other operating systems. @dAnjou does raise some good points.
@dAnjou does raise good points and full compatibility cross platform is a lofty goal, however not unachievable. For instance, Linux is hard to support as gnome dropped support for system trays but you can hack around it using libappindicator, etc. I'm not even sure you can get text into a windows tray icon.
I think it might be possible to use OpenSwiftUI instead of SwiftUI on Windows and Linux platforms. https://github.com/Cosmo/OpenSwiftUI
@leaanthony One option is just to build a new UI that looks and works like menus for cases where traditional menu bars are unavailable. @hmsjy2017 we use Wails, not SwiftUI.
I'm not even sure you can get text into a windows tray icon.
On windows It should be possible to somehow create a "toolbar" to do this. Lenovo usually has something like this to show the battery percentage preinstalled on their laptops (for some reason). Here's a screenshot i found:
Unfortunately, after half an hour of googling about "windows taskbar toolbars" i was no closer to finding the underlying api which allows you to do this. But I am sure there are windows development wizards out there that could help if this turns into a serious effort 😄
@K1ngjulien pystray can do this on windows
https://github.com/moses-palmer/pystray/blob/master/lib/pystray/_win32.py
I'd really like to see this, it would be really useful to be able to share custom xbar plugins with non-Mac users. e.g. in my team we have all 3 of these OSes represented within the team.
I figure there's 2 parts to this:
For the most part the xbar code seems pretty cross-platform friendly. I managed to get it to compile & run on linux with just a little refactoring. But sadly, no system tray icon appeared, because ...
Wails itself (v2) doesn't currently support system tray (or much else) on linux or windows ... They have begun ports to windows and linux, but it looks like they're doing one after the other and progress is slow. It might take years to get systray parity with the mac support ... They mention their roadmaps here: https://github.com/wailsapp/wails/issues/661
I'm not sure if you're aware but https://github.com/getlantern/systray is a decent & workable system tray library in go. I've used it in Mac and Linux happily... There's one awkward limitation though, it only supports a single icon per process. Possibly because of some specific per-os limitations, I don't know the rationale.
I'm going to assume it would be really gross to try to crowbar this library it into xbar instead of wails. I mean, systray does integrate with a webview component but I just figure it'd be a big change for an app which is already working nicely for a lot of folks...
I'm tempted to build a compatible xbar clone with getlantern/systray (managing multiple processes to get multiple icons). If argos can do it in js then why not try it in another Go app ...
But really, it'd be nice not to fork/clone the app. It's preferable not to fragment an ecosystem, but I don't have the appetite to work on the C parts of Wails myself...
Any thoughts on how to go about this while playing nicely with the xbar community?
It would still be good for the plugin repo to be cross-platform, even while the xbar app isn't. By that I think I'm just talking about marking and filtering plugins by OS.
So, I figure it would be good to define some per-OS tagging support to the plugin system, and to have xbar's plugin browser respect those labels... xbar already defines plugin metadata fields ...
Probably this warrants its own ticket, but I'm just airing it here first...
Cheers
There are a number of technical reasons why this is hard, and you list some. The fact that there are libraries to do some of the work doesn't get around the fact that for a gui application, you have the problem of who owns the main event loop.
Despite these technical issues, the biggest issue with making xbar cross platform IMHO is that the concept of system trays on both Linux and Windows do not have parity with MacOS. The main difference being that they do not show text next to them. There doesn't seem to be any good solution to this other than to mimic the functionality with hacks that are a support concern, especially on Linux.
No matter what libraries you use, this disparity is still a core issue. Do you have any thoughts on a good solution?
Hi, fair point that Windows can't support text in the systray. The getlantern/systray docs confirm that 'set title' takes no effect in Windows, but it shows text just fine in Linux (it uses libappindicator; I've used it with gnome shell)
... For my use case this one thing isn't a deal breaker... I'm hoping that a first line of mytitle | icon=x.png
could hypothetically be used to indicate a systray icon?
... I'd be happy to use icons for the plugins I have in mind, and I think it's OK generally - assuming the possibility to mark some plugins as 'unsupported' on a per-OS basis, and then a plugin author would need some guidance in order to support multiple platforms ....
Are there any other platform-related obstacles you're aware of?
...
you have the problem of who owns the main event loop.
Sorry, I don't understand how this relates to the cross-platform thing.
The libraries you mentioned all have a Run function that owns the main event loop.
right, and xbar currently owns that loop? OK. Yeah my experiment with getlantern/systray lib is presenting each icon in a separate process and attempting some IPC (not very well as yet)... I don't know specifically why the library works this way but I'm just running with it.
You asked if I had any ideas for cross-platform support... Mainly I have just notes about obstacles and weird workarounds. Maybe some of these are helpful, maybe not ...
Icons vs text - as you say we'd need an alternative for platforms with icon-only tray items, and I haven't thought of anything amazing ...
|
and a property could be added to the text, but that wouldn't be consistent with xbar's current format ... not sure how bundling such icons might work. (bundled by plugin or by xbar? maybe a plugin comment-tag could indicate where to fetch them from?)Generally refreshing works fine in each platform, but with there's some challenges with the specific library I'm using ...
I feel like it would be really challenging for someone to write a plugin and feel confident it was ready for cross-platform use. Little differences would trip people up IMO... But also dependency management. It'd be hard for someone to say 'well if you're on windwos then you need to install bash, oh and on mac the grep binary needs to be from gnu... etc'
elvish
, it's kinda great to be honest, although it is a bit quirky. I'm beginning to eke out some helper functions for outputting submenus and OS-specific stuff like getting the home directory.open
/ xdg-open
/ explorer.exe on a directory. That seems straightforward.Wails 2.0 was released yesterday: https://wails.io/blog/wails-v2-released/
Wails 2.0 was released yesterday: https://wails.io/blog/wails-v2-released/
Last, but not least, a huge thank you to Mat Ryer who has provided advice and support during the development of v2. Writing xBar together using an early Alpha of v2 was helpful in shaping the direction of v2, as well as give me an understanding of some design flaws in the early releases. I'm happy to announce that as of today, we will start to port xBar to Wails v2, and it will become the flagship application for the project. Cheers Mat!
That's Awesome!
@matryer do you have an estimate when the ported xBar on Wails v2 could be released?
Is there anything for windows that exists that is at all similar to xbar?
The issue is that tray icons don't support text. Would you run it if it created a bar at the top of the screen permanently? Or maybe there's a better UI?
If it was auto-hide, maybe
On Tue Jan 24, 2023, 08:03 AM GMT, Lea Anthony @.***> wrote:
The issue is that tray icons don't support text. Would you run it if it created a bar at the top of the screen permanently? Or maybe there's a better UI? — Reply to this email directly, view it on GitHub https://github.com/matryer/xbar/issues/691#issuecomment-1401519378, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAYAUAII6TO5SMUS55QPLDWT6EEZANCNFSM42M6X5WA. You are receiving this because you commented.Message ID: @.***>
I am using this on all desktops
https://pkg.go.dev/fyne.io/systray
works well and designed for extensibility
—-
Good example that’s like xbar ?
Most plugins output text, and are updated multiple times a minute. Doesn't systray use bubble notifications on windows? So that would mean having a continuous stream of bubble notifications from all enabled plugins?
hey
screenshot:
(https://raw.githubusercontent.com/fyne-io/systray/master/example/screenshot.png)
i don’t have windows to test on though
Yeah Linux isn't a problem (apart from the shambles of whether the user will need to install a shared lib or not as it isn't standard)... It's Windows that has no concept of text next to the tray icon
Can someone run this on windows maybe. I would like to see what it looks like :) Sorry but just don’t have windows machine.
Yeah Linux isn't a problem (apart from the shambles of whether the user will need to install a shared lib or not as it isn't standard)... It's Windows that has no concept of text next to the tray icon
Fyne has installers and updaters. We can try them
line 7 and 8:
https://github.com/fynelabs/iot-blog-example/blob/main/go.mod
Hey. Is there any update in this case? It would be great to have xbar on Windows 🥰
We would love to do that but what would it look like? Tray menus on windows do not support text so it wouldn't be a 1:1 port. Would it be a bar at the top? Same for Linux.
We would love to do that but what would it look like? Tray menus on windows do not support text so it wouldn't be a 1:1 port. Would it be a bar at the top? Same for Linux.
As mentioned above, there is a systray package that allow to create an icon in the tray menu, but it doesn't support refreshing menu itself. I guess that it wouldn't be a 1:1 port because yesterday I studied the wails 2.7 package and there are a lot of differences, so probably it should be a new repository calls I don't know... wbar maybe...
Now I noticed that there is a v3-alpha version available of the Wails and there is a new systray package (https://v3alpha.wails.io/whats-new/#systrays) I will try to write something using v3-alpha version for fun :)
OK, I know that the code is not perfect and it should be refactored, but it is a prototype :) Because I used the xbar mostly for the Jira issues counter, inspired by the python Jira plugin, I've made a simple app with a dynamically generated icon tray icon and issue list.
package main
import (
"bytes"
_ "embed"
"fmt"
"image"
"image/png"
"log"
"strings"
"time"
jira "github.com/andygrunwald/go-jira"
"github.com/fogleman/gg"
"github.com/wailsapp/wails/v3/pkg/application"
)
type JIRAAuth struct {
juser string
jtoken string
jql string
uri string
}
func generateIcon(number int) []byte {
const size = 16
dc := gg.NewContext(size, size)
dc.SetRGB(0, 0, 0)
dc.Clear()
dc.SetRGB(1, 1, 1)
dc.DrawStringAnchored(fmt.Sprintf("%d", number), size/2, size/2, 0.5, 0.5)
var img image.Image = dc.Image()
result := new(bytes.Buffer)
png.Encode(result, img)
return result.Bytes()
}
func FetchJIRAIssues(JIRA JIRAAuth) *[]jira.Issue {
tp := jira.BasicAuthTransport{
Username: JIRA.juser,
Password: JIRA.jtoken,
}
jiraClient, err := jira.NewClient(tp.Client(), JIRA.uri)
opt := jira.SearchOptions{
MaxResults: 20,
Expand: "summary,issuetype,status,assignee,project",
}
issues, _, err := jiraClient.Issue.Search(JIRA.jql, &opt)
if err != nil {
log.Fatal(err)
}
return &issues
}
func GenerateMenu(app *application.App, systemTray *application.SystemTray, issueTypes []string, JIRA JIRAAuth) int {
myMenu := app.NewMenu()
issues := FetchJIRAIssues(JIRA)
var added bool
for _, issueType := range issueTypes {
added = false
for _, issue := range *issues {
if strings.ToUpper(issue.Fields.Status.Name) == strings.ToUpper(issueType) {
if added == false {
myMenu.Add(issueType).SetEnabled(false)
added = true
}
label := fmt.Sprintf("[%s] %s", issue.Key, issue.Fields.Summary)
myMenu.Add(label).
SetTooltip(issue.Key).
OnClick(func(ctx *application.Context) {
app.BrowserOpenURL(fmt.Sprintf("%s/browse/%s", JIRA.uri, ctx.ClickedMenuItem().Tooltip()))
})
}
}
}
myMenu.AddSeparator()
myMenu.Add("Go to JIRA Issues").OnClick(func(ctx *application.Context) {
app.BrowserOpenURL(fmt.Sprintf("%s/issues/?jql=%s", JIRA.uri, JIRA.jql))
})
myMenu.Add("Quit").OnClick(func(ctx *application.Context) {
app.Quit()
})
systemTray.SetMenu(myMenu)
return len(*issues)
}
func main() {
app := application.New(application.Options{
Name: "JIRA Issue Counter",
Description: "A demo of the Wails v3 API",
Assets: application.AlphaAssets,
Mac: application.MacOptions{
ActivationPolicy: application.ActivationPolicyAccessory,
},
})
JIRA := JIRAAuth{
juser: "username@mail.com",
jtoken: "jira_ptoken",
jql: "assignee = currentUser() ORDER BY created DESC",
uri: "https://yourcompany.atlassian.net",
}
systemTray := app.NewSystemTray()
var issueTypes []string
issueTypes = append(issueTypes, "New")
issueTypes = append(issueTypes, "In Progress")
// issueTypes = append(issueTypes, "Oczekuje na odpowiedź klienta")
// issueTypes = append(issueTypes, "Odpowiedź od klienta")
// issueTypes = append(issueTypes, "Wstrzymane")
go func() {
for {
cnt := GenerateMenu(app, systemTray, issueTypes, JIRA)
systemTray.SetDarkModeIcon(generateIcon(cnt))
time.Sleep(60 * time.Second)
}
}()
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
So yes, it is possible, the wbar will have few limitations, f.ex. it is not possible to put into Windows tray a long text, but it works :)
I'm not even sure you can get text into a windows tray icon.
On windows It should be possible to somehow create a "toolbar" to do this. Lenovo usually has something like this to show the battery percentage preinstalled on their laptops (for some reason). Here's a screenshot i found:
Unfortunately, after half an hour of googling about "windows taskbar toolbars" i was no closer to finding the underlying api which allows you to do this. But I am sure there are windows development wizards out there that could help if this turns into a serious effort 😄
There's a tool called Traffic Monitor can do this.
But its wrote with c, the method is a bit hack. It seems to create a transparent and borderless window as a child window of explorer.exe.
But its wrote with c, the method is a bit hack. It seems to create a transparent and borderless window as a child window of explorer.exe.
Oh wow. I wonder what it looks like if you fill the taskbar with icons or move it to be vertical 😬
xbar is a good software. I want to use it in other platforms. This software is written in Go, so I think it will not be too difficult to support Windows and Linux. Thank you.