qdot / systray-rs

Allows rust applications to show a platform specific system tray icon and menu.
BSD 3-Clause "New" or "Revised" License
170 stars 66 forks source link

Add macOS support #4

Open qdot opened 7 years ago

qdot commented 7 years ago

Got permission from @jmquigs months ago to adapt code from rs-barfly (https://github.com/jmquigs/rs-barfly) to systray, meaning less porting weirdness from go's systray library. Just need to get around to actually doing this.

daniel-abramov commented 7 years ago

As for the mac implementation, just a heads up... I've got core API changes coming into the linux-core branch that moves the callback/menu idx/etc management up to the top level of the library (see #7), so platform code should be much simpler. It wasn't supposed to be that way in the first place, I just got interrupted in the middle of development which is why the API used direct window access up until now. It's pretty much done, just finishing the linux core now then will fix up the windows code. Other than that, not sure if you saw in #4, but we've got permission to port rs-barfly, so there's starter code there if you're interested.

Yes, I saw that. Although rs-barfly contains some useful hints on how to implement callbacks, some code is not even compilable. I implemented some basic things for the tray icon (the tray icon itself) for Mac (see comments from 1st of March https://github.com/snapview/systray-rs/commits/master), but I did not use the code from rs-barfly to implement additional items inside the tray icon menu. The code from rs-barfly works after fixing small compile time errors, but it seems more like a hack to me, I think that I have to invest some time in a research in order to figure out how to do it properly on Mac (we somehow have to pass the ownership of callback structure to the obj-c runtime, without memory leaks, crashes etc and to ensure that it will run as expected).

qdot commented 7 years ago

Ok, cool. Hadn't really taken much of a look at the barfly stuff myself, just knew it was there and possibly working. I'll keep an eye on your fork, great to see icons are at least up and running! We'll probably need to sync up at some point about how threading is going to work between all these platforms too.

zaaack commented 7 years ago

Any update on macos?

daniel-abramov commented 7 years ago

From my side I can only tell that I was able to create a tray icon (back then) and display it, but unfortunately I did not have time to add an additional functionality.

Perhaps it would make sense to merge my fork into master branch (at least it allows you to show a working tray icon in Mac, but it does not allow you to specify your own callbacks).

daniel-abramov commented 7 years ago

Oh, also I was not able to create a tray icon from an arbitrary thread, it seems that there are some limitations in Mac OS for such things. I had to start the tray icon in a main thread, otherwise the application crashed; not sure how to overcome this limitation (it could be that it is not possible).

zaaack commented 7 years ago

Anyway to add callback? I tried barfly, but it cannot modify the tray menu in the callback...

qdot commented 7 years ago

AFAIK, we have to keep everything GUI wise on the same thread at the loop running the GUI. If someone has pull requests for me, that'd be awesome, happy to take them. I /am/ hoping to get back to this project at some point, just busy on some other releases for at least the next few weeks.

daniel-abramov commented 7 years ago

Anyway to add callback? I tried barfly, but it cannot modify the tray menu in the callback...

Once I added some sort of a callback and it worked out for me after spending some time on writing "hacks" (which were required to make it work), but I did not push these changes to any of the repositories as they were mostly supposed to be for local tests and the code was not clean enough. I have not tried to modify the tray menu from the callback though.

zaaack commented 7 years ago

@application-developer-DA Can you push to a temporary branch? Although I'm a rust new bee and might not help much. A cross-platform tray library is really meaningful since most GUI library doesn't provide one, hope you can figure out a macOS solution.

daniel-abramov commented 7 years ago

I'm not sure if I still have these callback-related changes, but I'll take a look, maybe they're still staging in some of the local repositories.

Other changes (which were more or less stable and used by me in some software products) are accessible from a fork repository at https://github.com/snapview/systray-rs (but they do not support callbacks though).

I've noticed that my fork is now behind the current master branch, so I'll try to rebase it and create a pull request if I find some time this week.

zaaack commented 7 years ago

@application-developer-DA Thanks! These will help a lot.

daniel-abramov commented 7 years ago

Ok, I rebased the current state from my fork and created a pull request. Check it out.

Unfortunately I did not have time to test it (i'm a bit busy at the moment), but as I know that some people may need this Mac implementation, I decided to merge it and just to run an example in Windows and to compile on other operating system to ensure that it compiles, but I'll try to do more tests in a near future (as one of the projects I'm working on is using systray-rs, but it relies on an old version from my fork, not on upstream changes).

zaaack commented 7 years ago

@application-developer-DA It's very kind of you! Although I still have no idea how to make callback with mutable borrowed application working in macos, at least here is making some progress!

daniel-abramov commented 7 years ago

I tried barfly, but it cannot modify the tray menu in the callback...

@zaaack I've recently work on some objc-runtime things which had similar issues and I think that it might be possible to implement something similar in systray-rs (I'll try to do that when I have some free time for that). In order to do that, you have to create a custom NSMenuItem based on your own objc::runtime::Object (and class declared by means of objc::decl::ClassDecl), this object must have an ivar which should be able to store a reference as *mut c_void which poitns to an object which has an access to the tray menu.

frewsxcv commented 7 years ago

hey all, i looked for a rust sysbar library a few months ago and (at the time) was only aware of barfly and knew it wasn't too active, so i started a new project: https://github.com/rust-sysbar/rust-sysbar.

once i added the initial (minimal) macOS implementation, i announced it on reddit. someone in the comments pointed me at this crate (systray-rs) which i hadn't seen until then. and now that i've seen this one, it seems redundant for me to continue working on a different, less-mature crate with goals similar to this one, so i'll probably stop working on that one.

the primary issue i'm writing in this particular comment thread is that @mrmekon (sorry for the ping) reached out to me on reddit informing me they have their own project called connectr which has its own mac (and cross-platform) implementation of sysbar support and that implementation looks pretty solid. even though the licenses differ (Apache 2.0 vs. MIT) mrmekon told me over reddit "Feel free to take anything useful out of Connectr" so I'm going to guess they're pretty lax about licensing.

anyways, just thought i'd share my thoughts and would love to have a common crate for doing sysbar things and systray-rs seems like a good candidate 👍

qdot commented 7 years ago

Cool, thanks for pointing that out! I'll try to take a look at connectr. Though, I keep saying I'm going to be back to this project and it keeps not happening, so I can't really give a good timeframe. If someone is feeling motivated enough to take over maintainership I'd be happy to discuss that, otherwise I'll hopefully start wandering back this direction soon.

jonhoo commented 7 years ago

It'd be awesome to get macOS support, because that would immediately make buzz be cross-platform too! :D No immediate rush though -- take your time.

qdot commented 4 years ago

Working with @application-developer-DA's patches from snapview/systray-rs now. Things compile, but crash on the example.

alexandrvicente commented 4 years ago

Implemented on #40, still didn't have time to test on other platforms to be sure that nothing stopped working with the changes I made to src/lib.rs though.

andrewdavidmackenzie commented 4 years ago

Any thoughts on merging efforts with https://github.com/rust-sysbar/rust-sysbar that would like to add linux and window support?

I was looking to this project for clues and code to contribute that to rust-sysbar, but maybe best the maintainers consider a merge?

qdot commented 4 years ago

Any thoughts on merging efforts with https://github.com/rust-sysbar/rust-sysbar that would like to add linux and window support?

I was looking to this project for clues and code to contribute that to rust-sysbar, but maybe best the maintainers consider a merge?

Not sure how much I'd trust this project for clues, heh. I wrote most of this in mid-2016, it was one of my first rust projects, and it hasn't really been updated since. It really needs a complete overhaul.

I've been saying I'd get back to this at some point but that's looking less and less likely. My expertise is in device interfaces, not windowing systems, so this tends to stay on the back burner. For instance, we've had OS X patches in PR for a while, but they crash on windows and I don't have time to figure that out.

I'm not sure how you'd merge with systray either, as the idioms it uses aren't really great for what it needs to do. Also, there's @ciantic's Trayicon (https://github.com/Ciantic/trayicon-rs/) which is also coming up.

That said, I'm definitely not trying to be the only player in town or anything, I think I just established first and got name recognition, hence the stars. I'm happy to add alternative library choices like yours and trayicon to the README here, and honestly I may end up officially abandoning this library in the near future.

andrewdavidmackenzie commented 4 years ago

OK, I understand- Time is a precious resource hard to come by.

trayicon-rs is windows only I think, and the priority order I was looking for was macos, linux, windows..... and I currently dont have a windows machine to develop on, just mac and linux.... so Ill leave it for now.

We need to merge all three projects (or the dependencies and how to use them) to get a true cross-platform approach

qdot commented 4 years ago

In my experience, if you aren't designing for all the systems you want to support at once, you're going to have a Bad Time when you claim your library is cross platform. I see this a lot in Rust, with projects dropping windows to the lowest support priority, and then wondering why the community has traction problems outside of network services and posix utility replacements.

For a project to be cross platform in a way that works fairly, it needs to map out the capabilities it wants up front, then figure out how all 3 platforms are going to fit into that framework. Otherwise it'll be shoehorning everything into whatever the first model made was. This is one of the issues blocking systray-rs at the moment, I need to do this analysis for Win/Mac/Linux before embarking on an API update, and why I'm not sure I agree with your priority order. I see this step would be the "dependencies and how to use them" portion of your comment.

Also, missing a platform for development is gonna be a big hit to a cross platform project, and is super frustrating to those of us that NEED to work on all 3 platforms at once when one platform feels like a half-built afterthought. VMs exist, and are pretty easy to set up.

tanekere commented 4 years ago

so any progress on this?

qdot commented 4 years ago

Nope.

becerratops commented 4 years ago

@jeffrey-p-mcateer take a look at this plz

bedax commented 4 years ago

You may have seen it already, but here's a good reference: https://github.com/zserge/tray