-
-
Notifications
You must be signed in to change notification settings - Fork 195
feat(native): add initial tray-support for macOS #972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
8551994
8505c1e
4ca19bf
3479e14
6b192fe
5875b9d
5073247
9e0b01f
1b5553e
873b7b5
3834a89
465f015
1f53855
240e452
2f2c862
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| open Revery; | ||
| open Revery.UI; | ||
| open Revery.UI.Components; | ||
|
|
||
| let%component make = () => { | ||
| let%hook () = | ||
| Hooks.effect( | ||
| OnMount, | ||
| () => { | ||
| let trayImage = | ||
| Native.Tray.make( | ||
| ~imagePath=Environment.getAssetPath("outrun-logo.png"), | ||
| (), | ||
| ); | ||
|
|
||
| let trayText = | ||
| Native.Tray.make() |> Native.Tray.setTitle(~text="Hello Revery!"); | ||
|
|
||
| Some( | ||
| () => { | ||
| trayImage |> Native.Tray.remove; | ||
| trayText |> Native.Tray.remove; | ||
| }, | ||
| ); | ||
| }, | ||
| ); | ||
|
|
||
| <Center> | ||
| <Text | ||
| text="You should see two items in your tray-bar. One image and one with | ||
| the text \"Hello Revery!\"" | ||
| /> | ||
| </Center>; | ||
| }; | ||
|
|
||
| let render = () => make(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| %import | ||
| "config.h"; | ||
|
|
||
| type t; | ||
|
|
||
| open { | ||
| external c_make: (~imagePath: string=?, unit) => t = | ||
| "revery_makeTrayHandle"; | ||
| external c_setTitle: (t, ~text: string) => t = "revery_setTrayTitle"; | ||
| external c_remove: t => unit = "revery_removeTrayItem"; | ||
| }; | ||
|
|
||
| %if | ||
| defined(USE_COCOA); | ||
|
|
||
| let make = (~imagePath=?, ()) => { | ||
| let trayHandle = c_make(~imagePath?, ()); | ||
| Gc.finalise(NSObject.release, trayHandle); | ||
| trayHandle; | ||
| }; | ||
|
|
||
| [%%else]; | ||
|
|
||
| let make = c_make; | ||
|
|
||
| [%%endif]; | ||
|
|
||
| let setTitle = c_setTitle; | ||
| let remove = c_remove; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| type t; | ||
|
|
||
| /** | ||
| * make | ||
| * | ||
| * Takes an optional [imagePath] which is an absolute path to a in image-file. | ||
| * Returns a newly created Tray.t; | ||
| * | ||
| * Examples: | ||
| * Tray.make(~imagePath="/absolute/path/to/image.png", ()) |> ignore; | ||
| * Tray.make(~imagePath=Environment.getAssetPath("some_asset_image.png", ()) |> ignore; | ||
| * let tray = Tray.make(); | ||
| */ | ||
| let make: (~imagePath: string=?, unit) => t; | ||
|
|
||
| /** | ||
| * setTitle | ||
| * | ||
| * Takes a [title] of string and sets the tray's text to it. | ||
| * Returns the updated tray item. | ||
| * * | ||
| * Examples: | ||
| * tray |> Tray.setTitle(~text="Hello Revery!") |> ignore; | ||
| * let tray = Tray.make() |> Tray.setTitle(~text="Hello Revery!"); | ||
| * Tray.setTitle(tray, ~text="Hello World!") |> ignore; | ||
| */ | ||
| let setTitle: (t, ~text: string) => t; | ||
|
|
||
| /** | ||
| * remove | ||
| * | ||
| * Given a [t] removes the tray item from the tray. | ||
| * * | ||
| * Example: | ||
| * tray |> Tray.remove; | ||
| * Tray.remove(tray); | ||
| */ | ||
| let remove: t => unit; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #include "config.h" | ||
| #ifdef USE_COCOA | ||
| #include <stdio.h> | ||
|
|
||
| #import <Cocoa/Cocoa.h> | ||
|
|
||
| void *revery_makeImageFromAbsolutePath_cocoa(const char *imagePath) { | ||
| NSString *nsImagePath = | ||
| [NSString stringWithCString:imagePath encoding:NSUTF8StringEncoding]; | ||
|
|
||
| NSImage *nsImage = [[NSImage alloc]initWithContentsOfFile:nsImagePath]; | ||
|
|
||
| return nsImage; | ||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| #include <stdio.h> | ||
|
|
||
| #include <caml/alloc.h> | ||
| #include <caml/callback.h> | ||
| #include <caml/memory.h> | ||
| #include <caml/mlvalues.h> | ||
|
|
||
| #include "caml_values.h" | ||
|
|
||
| #include "config.h" | ||
| #ifdef USE_WIN32 | ||
| #include "ReveryWin32.h" | ||
| #elif USE_COCOA | ||
| #include "ReveryCocoa.h" | ||
| #import <Cocoa/Cocoa.h> | ||
| #elif USE_GTK | ||
| #include "ReveryGtk.h" | ||
| #endif | ||
|
|
||
| #include "utilities.h" | ||
|
|
||
| CAMLprim value revery_makeTrayHandle(value vImagePath) { | ||
| CAMLparam1(vImagePath); | ||
| CAMLlocal1(result); | ||
|
|
||
| #ifdef USE_COCOA | ||
| NSStatusItem *statusItem = [NSStatusBar.systemStatusBar statusItemWithLength:NSVariableStatusItemLength]; | ||
|
lessp marked this conversation as resolved.
|
||
| [(NSObject *)statusItem retain]; | ||
|
|
||
| if (vImagePath != Val_none) { | ||
| const char *imagePath = String_val(Some_val(vImagePath)); | ||
|
|
||
| NSImage *nsImage = revery_makeImageFromAbsolutePath_cocoa(imagePath); | ||
|
|
||
| statusItem.button.image = nsImage; | ||
|
|
||
| UNUSED(imagePath); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: is this still needed?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, actually, I don't know 🤔 Most likely I followed another example, but looking at the context, I was under the impression that it is, but this is your forte! |
||
| } | ||
|
|
||
| result = revery_wrapPointer(statusItem); | ||
|
lessp marked this conversation as resolved.
|
||
|
|
||
| CAMLreturn(result); | ||
| #elif USE_WIN32 | ||
| result = caml_alloc(sizeof(NULL), Abstract_tag); | ||
| #else | ||
| result = caml_alloc(sizeof(NULL), Abstract_tag); | ||
| #endif | ||
| CAMLreturn(result); | ||
| } | ||
|
|
||
| CAMLprim value revery_setTrayTitle(value vTrayHandle, value vTitle) { | ||
| CAMLparam2(vTrayHandle, vTitle); | ||
| CAMLlocal1(result); | ||
| #ifdef USE_COCOA | ||
| void* statusItem = revery_unwrapPointer(vTrayHandle); | ||
|
|
||
| const char *title = String_val(vTitle); | ||
|
|
||
| revery_setTrayTitle_cocoa(statusItem, title); | ||
|
|
||
| result = revery_wrapPointer(statusItem); | ||
|
|
||
| CAMLreturn(result); | ||
| #elif USE_WIN32 | ||
| result = caml_alloc(sizeof(NULL), Abstract_tag); | ||
| #else | ||
| result = caml_alloc(sizeof(NULL), Abstract_tag); | ||
| #endif | ||
| CAMLreturn(result); | ||
| } | ||
|
|
||
| void revery_removeTrayItem(value vTrayHandle) { | ||
| CAMLparam1(vTrayHandle); | ||
| #ifdef USE_COCOA | ||
| void* statusItem = revery_unwrapPointer(vTrayHandle); | ||
|
|
||
| revery_removeStatusItem_cocoa(statusItem); | ||
|
|
||
| CAMLreturn0; | ||
| #elif USE_WIN32 | ||
| CAMLreturn0; | ||
| #else | ||
| CAMLreturn0; | ||
| #endif | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #include "config.h" | ||
| #ifdef USE_COCOA | ||
| #include <stdio.h> | ||
|
|
||
| #import <Cocoa/Cocoa.h> | ||
|
|
||
| void *revery_setTrayTitle_cocoa(NSStatusItem* statusItem, const char *titleText) { | ||
| NSString *nsTitle = | ||
| [NSString stringWithCString:titleText encoding:NSUTF8StringEncoding]; | ||
|
|
||
| statusItem.button.image = NULL; | ||
| statusItem.button.title = nsTitle; | ||
|
|
||
| return statusItem; | ||
| } | ||
|
|
||
| void revery_removeStatusItem_cocoa(NSStatusItem* statusItem) { | ||
| [[NSStatusBar systemStatusBar] removeStatusItem: statusItem]; | ||
| } | ||
|
|
||
| #endif |
Uh oh!
There was an error while loading. Please reload this page.