Git Product home page Git Product logo

quark-shell-mac's Introduction

Quark Shell for Mac

Quark Shell helps you create cross-platform (currently Mac-only, Windows version coming soon) menubar/tray app using HTML and JavaScript without writing any native code. Quark Shell exposes a JavaScript object called quark to provide system functions. Quark Shell for Mac is based on WebKit.

Screenshot

Integrating Web App

app/index.html is the portal of your menubar app. app/preferences/[identifier].html are the preference pages (for example, app/preferences/general.html).

To build your app:

  1. Delete the current app folder
  2. Put your files into app folder
  3. Open quark-shell.xcworkspace in Xcode
  4. Change bundle name and bundle identifier (see Issue #50 for details)
  5. Build and have fun!

Remember that Quark Shell is still a WIP. When the project is stable enough, the build process will be simplified.

API

APIs may change rapidly before 1.0.

quark.platform // returns "mac" or "windows"

// App info (configurable in Xcode)
quark.appVersion
quark.appBundleVersion

// Enable/disable Web Inspector
quark.debug = true

// Manipulate the popup window
quark.openPopup()
quark.closePopup()
quark.togglePopup()
quark.resizePopup({width: 326, height: 623})

// Quit application
quark.quit()

// Open URL in default browser
quark.openURL("https://pomotodo.com/")

// Set menubar icon
quark.setMenubarIcon("data:image/png;base64,iVBORw...SuQmCC")
quark.setMenubarHighlightedIcon("data:image/png;base64,iVBORw...SuQmCC")
quark.resetMenubarIcon()

// Set menubar icon click action
quark.setClickAction(function () { console.log("Don’t click me!"); })
quark.setSecondaryClickAction(function () { console.log("What did I say?"); })

// Set menubar label
quark.setLabel("03:14 AM")

// Auto launch at login
// You also need to change bundle identifier "com.hackplan.quark-shell-helper" to a proper one in quark-shell-helper.xcodeproj and QSHWebViewDelegate.m
quark.setLaunchAtLogin(true)

// Send system notification
quark.notify({
  title: "Pomotodo",
  content: "Break is over!",
  time: "2038-01-19T03:14:07Z", // (optional) delivery date for scheduled notification, in ISO 8601
  popupOnClick: true // popup when clicking notification
})

// Remove all scheduled notifications
quark.removeAllScheduledNotifications()

// Remove all delivered notifications from notification center
quark.removeAllDeliveredNotifications()

// Open new window
// "url" is relative to "app" folder
// Notice: You can only open one window at the same time,
// or the later window will replace the former window.
quark.newWindow({
  url: "about.html",
  width: 600,
  height: 400,

  // optional options
  x: 100, y: 100, // x and y should both be provided, "center" is also a valid value
  border: true, // whether the window has a border, default is true
  shadow: true, // whether the window has a shadow, default is true
  alwaysOnTop: false, // whether the window should always on top, default is false
  alpha: 1.0 // the alpha value of the window, between 0 and 1, default is 1.0
})

// Close new window
quark.closeWindow()

// Pin/unpin pop-up window (won’t close when click outside the window)
quark.pin()
quark.unpin()

// Exchange messages between webviews
quark.emit("MessageName", "payload")
quark.on("MessageName", function(message) {
	console.log(message)
})

// Show a context menu
quark.showMenu({
  items: [
    {label: "Test", click: function() { console.log("I am completely operational") } },
    {type: "separator"},
    {label: "Exit", click: function() { console.log("LIFE FUNCTION TERMINATED") } }
  ],
  x: 100,
  y: 200
])

Global Shortcuts

// Set global keyboard shortcut
quark.addKeyboardShortcut({
  keycode: 0x7A, // F1 key
  modifierFlags: 0, // no modifier key
  callback: function suchCallback() {
    console.log("wow")
    quark.togglePopup()
  }
})

// Clear global keyboard shortcut
quark.clearKeyboardShortcut()

Please follow NSEvent Class Reference for documentation about modifier flags.

Also, Quark Shell for Mac allows you to record shortcuts via native components in Preferences window.

Preferences

quark.setupPreferences([
  {"label": "General",  "identifier": "general",  "icon": "NSPreferencesGeneral", "height": 192},
  {"label": "Account",  "identifier": "account",  "icon": "NSUserAccounts",       "height": 102},
  {"label": "Shortcut", "identifier": "shortcut", "icon": "NSAdvanced",           "height": 120}
])

// Must be called after quark.setupPreferences()
quark.openPreferences()
quark.closePreferences()

Quark Shell for Mac also provides some native components for preferences.

More detail: Preferences.md

Auto Updating

// Check for update
quark.checkUpdate("https://rawgit.com/HackPlan/quark-shell-mac/master/updater/SampleAppcast.xml")
quark.checkUpdateInBackground("https://rawgit.com/HackPlan/quark-shell-mac/master/updater/SampleAppcast.xml")

More detail: AutoUpdate.md

FAQ

  • Can I use local storage? Yes.
  • Can I use WebSQL? Yes.
  • Can I use IndexedDB? No, because we are using NSWebView. A future Yosemite-only version using WKWebView will support IndexedDB.
  • Is Quark Shell compatible with Mac App Store? Absolutely yes.

Story

Quark Shell was originally Menubar WebKit. It was created for Pomotodo for Mac. Later on, we decided to create a Windows version based on Atom Shell. The project was highly inspired by Atom Shell (now Electron), node-webkit (now nw.js), and MacGap. As a cross-platform project, Menubar WebKit is no longer an appropriate name, so we started to use Quark Shell.

Credits

Quark Shell for Mac was created by LIU Dongyuan (@xhacker) in the development of Pomotodo for Mac.

Some of the code are taken from:

Used third-party libraries:

Contribution

Pull requests are welcome! If you want to do something big, please open an issue first.

License

MIT

quark-shell-mac's People

Contributors

readmecritic avatar untsop avatar xhacker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quark-shell-mac's Issues

How to define notification icon?

I successfully set the application icons using an 'AppIcon' set in images.xcassets
The system notification doesn't use any icons though, just the default 'blank' icon.
How can I set it?
Thanks! I love this project.

Set a custom Preferences icon

Is it currently possible to set your own Preferences icon as opposed to the three default icons?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/27753276-set-a-custom-preferences-icon?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Tab-able apps?

Hi there, would it be possible to expose our quark applications to the 'active application' tab, so that users can CMD-tab to access the application?

Thank you very much for your ongoing support.

Resize Window

Is it possible to change the properties of a window (resize / reposition)? I want to do this programatically in response to some events inside the window.

Function to close window

Is it possible to add a function to close the Menubar window? Similar to the existing mw.closeWindow() function?

I would like to be able to close the window via Javascript after the user completes an action.

I add a new function and selector that I can call from javascript but I can't figure out how to close the window.

Executable does not execute from /Applications

Is there a panel within xcode to determine an applications permissions?
My compiled application works great, but does not start when it is inside /Applications.
It starts fine from documents,downloads, and user/Applications.
Thanks

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/29552902-executable-does-not-execute-from-applications?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Keep menubar icon highlighted when popup is visible

The highlight state should be kept after click on the icon.

Some clue: https://code.google.com/p/chromium/issues/detail?id=402787

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/5884163-keep-menubar-icon-highlighted-when-popup-is-visible?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Documentation using Slate

https://github.com/tripit/slate

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/7821464-documentation-using-slate?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Fill color of top arrow

Can the fill color of the top arrow be configurable outside of Xcode? I can change it in: LDYWindowBorderView.m but it would be nice if it could be configured from either the index.html file... maybe it grabs the body background color? Or some sort of config file?


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

window 'popup' dimensions

I appreciate that maybe this question is out of the scope of what you are offering, but thought I would ask anyway. Which variables should I change to modify the size of the main pop-up window? I was chasing after NSwindow, setFrame, NSWidth, but couldn't figure it out.

Thanks again for your help!

setupPreferences Label

It would be really nice to be able to set different Label vs Window name on Preferences

eg:
"label": "General" as set in setupPreferencesm but the window name would be taken from <title> tag

No Hover Styles and Requiring Double Click to Click

Sometimes when the app is opened the window doesn't seem to be acknowledging the focus. Hover styles are not shown for elements within the web view and two clicks are required to activate anything. The window also won't dismiss when clicking outside.

Feature Request: File Read/Write

It would be nice to be able to read/write files. The HTML5 File API works but as far as I know requires user interaction/selection of files. Is there a way to disable that security requirement or implement an Objective-C to JS function?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/7512386-feature-request-file-read-write?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

mw.emit() bug?

I was testing the mw.on() and mw.emit() functions. I wanted the new window to send a message back to the main menubar window and the main window to send a message back to the new window. I was going to use this to send data to the new window after it is opened.

The first message works good, just like your example. if I do this:

mw.on("TestMessage", function(message) {
        console.log(message)
        mw.emit("replymessage", "I can't Dave")
})

mw.emit("replymessage", "I can't Dave"); does not work unless I put it in a setTimeout of about half a second... Then it works.

But after that I ran into a problem. If I close the New Window and then reopen it and run everything a second time, I get an error in the main window when trying to call mw.emit("replymessage", "I can't Dave") a second time. I removed the setTimeout stuff and just manually ran mw.emit() in the console and it also gave the error so it seems to be that mw.emit() can't be called to send a message to the new window anytime AFTER the first time the window is opened and closed.

Error: TypeError: 'undefined' is not an object (evaluating 'func.apply')
xcode console error: 
2014-09-02 23:50:06.252 menubar-webkit[72917:303] JavaScript console: undefined:1: TypeError: 'undefined' is not an object (evaluating 'func.apply')
2014-09-02 23:50:06.253 menubar-webkit[72917:303] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x608000437ac0

Does that description make sense?

Backend Requests

I like the idea of building a single UI which (hopefully) can work across multiple operation systems. However, it is not very useful to me if I cannot interface with the operation system. In Cordova for example, I would create a plug-in with an implementation per supported OS. How would you do that here?

License?

Can you add a license for this project?

manifest.json

Format:

{
    "name": "Pomotodo",
    "localized_name": {
        "zh_CN": "番茄土豆"
    },
    "bundle_id": "com.pomotodo.Pomotodo"
    "version": "1.0.0",
    "popup_size": {
        "width": 400,
        "height": 300
    }
    "windows": {
        "publisher": "Pomotodo",
        "url": "https://pomotodo.com",
        "codename": "pomotodo",
        "uuid": "33E7B2D6-CAE5-4E54-8D2B-1FDBC7080052",
        "popup_size": {
            "width": 400,
            "height": 320
        }
    },
    "mac": {
        "bundle_id": "com.pomotodo.PomotodoMac",
    }
}

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/4259348-manifest-json?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Smoother hide/show

Current hide/show is a little bit unpleasing, compare to normal menubar apps.

n00b-issue

Hello! I love all your work, especially Pomotodo. I am trying to install quark, but when I run 'pod install' it fails with the following error. Is it a permissions problem or something? Thanks for the support.

/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/pathname.rb:422:in `open': No such file or directory - /Users/chris/.cocoapods/repos (Errno::ENOENT)
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/pathname.rb:422:in `foreach'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/pathname.rb:422:in `children'
from /Users/chris/.gem/ruby/2.0.0/gems/cocoapods-0.35.0/lib/cocoapods/sources_manager.rb:63:in `all'
from /Users/chris/.gem/ruby/2.0.0/gems/cocoapods-0.35.0/lib/cocoapods/user_interface/error_report.rb:130:in `repo_information'
from /Users/chris/.gem/ruby/2.0.0/gems/cocoapods-0.35.0/lib/cocoapods/user_interface/error_report.rb:34:in `report'
from /Users/chris/.gem/ruby/2.0.0/gems/cocoapods-0.35.0/lib/cocoapods/command.rb:58:in `report_error'
from /Library/Ruby/Gems/2.0.0/gems/claide-0.7.0/lib/claide/command.rb:300:in `handle_exception'
from /Library/Ruby/Gems/2.0.0/gems/claide-0.7.0/lib/claide/command.rb:274:in `rescue in run'
from /Library/Ruby/Gems/2.0.0/gems/claide-0.7.0/lib/claide/command.rb:264:in `run'
from /Users/chris/.gem/ruby/2.0.0/gems/cocoapods-0.35.0/lib/cocoapods/command.rb:45:in `run'
from /Users/chris/.gem/ruby/2.0.0/gems/cocoapods-0.35.0/bin/pod:43:in `<top (required)>'
from /usr/bin/pod:23:in `load'
from /usr/bin/pod:23:in `<main>'

Keycodes issue for Shortcuts

I'm trying to setup a default shortcut using Command+L and am running into a problem with the keycode. The keycode I need to pass into the addKeyboardShortcut function is 0x25.

In my javascript it works if I hard code it into the function, but I want to be able to store the value so that the user can change it. When I store the keycode as a string: "0x25" and pass the string into the function I get the following error in Xcode:
[NSTaggedPointerString unsignedIntegerValue]: unrecognized selector sent to instance 0x3532783045

I discovered this because my shortcuts were being stored as JSON data and the 0x25 was being parsed into the integer 37 when I wasn't explicitly making it a string.

Shouldn't addKeyboardShortcut take a javascript string for the keycode? I looked at the code a bit and it looks like it is a NSUInteger but I don't really understand all of that.

Window Position

Can the newWindow function be expanded to support passing x,y coordinates to control the position the window opens on screen?

Renaming app

I don't have a heavy OS X / Xcode background, so I've found that renaming the app from "quark-shell" has proven difficult. Typically changing all identifiers and files from "quark" to my app's name has displayed several build errors.

Do you have any suggestions for renaming an app?

file:// instead of http://

a lot of JS scripts use something like: script.src = '//cdn.syndication.twimg.com/widgets/timelines/'

which becomes 'file://cdn.syndication.twimg.com/widgets/timelines/'

would there be a way to fix this, except hardcoding it to http or https?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/10634688-file-instead-of-http?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Bug: single-click interactions require double-click

Hi there,

Great project. Really appreciate the opportunity to use web standard technology to make native Mac apps. :)

To reproduce the bug:

  1. Click the "Play" button in Xcode. Xcode builds Quark Shell and automatically gives it focus.
  2. Click on a different app (e.g., Xcode, Chrome) to give that app focus.
  3. Click the Quark Shell app icon in the status bar again. Now it takes a double-click to interact with buttons instead of the expected single click. For example, I don't see a notification appear on my screen unless I double click the "Notification" button.

This problem doesn't arise if you click the Quark Shell app icon immediately after clicking the play button. This makes me think the bug appears when you click the Quark Shell app icon while another app has focus.

If you have any trouble reproducing the bug, let me know. I'd be happy to make a screencast or something.

Build error when folder has spaces, solution included

I can now build it, with SDK 10.10 but I had a build error due to spaces in my folder name.

Your custom scrip that cleans out the 'app' folder did not account for spaces in the build tree structure.
Solution add quotes in the proper place to the "Run Script" for the "Build Phases"

Change it to:

echo "rm -rf "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Resources/app""
rm -rf "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Resources/app"

echo "cp -RL "${SRCROOT}/app" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Resources/app""
cp -RL "${SRCROOT}/app" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Resources/app"

Debug option

Enable / disable WebKit inspector.

Can’t change it on the fly, maybe this should be in manifest.

No banner for notifications

When I click on the "notify" button in the sample app, there is no banner, the notification
is only visible in the notification center.

OS X 10.9.4

Support multiple new windows

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/4206266-support-multiple-new-windows?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Open a specific Preference tab

Perhaps you can pass in the tab identifier on quark.openPreferences() to open a specific tab?

Example: quark.openPreferences('account') would open the tab where "identifier": "account".

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/27753325-open-a-specific-preference-tab?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

可以将html文件等放到.app外部吗?

比如在首次运行的时候,会在磁盘创建一个文件夹,将html复制到硬盘里,以后的每次操作都从硬盘读取。

这样做的目的是,我希望我开发的app可以管理和加载包,将package放到硬盘某个位置,每次运行前加载所有包。

与此同时,需要一个IO操作,删除和创建文件,读取文本文件这些简单的操作。

希望能够加上,谢谢

Remove mw.on() subscriber when new window is closed

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/4139022-remove-mw-on-subscriber-when-new-window-is-closed?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Clipboard API

Could you add a simple copy to clipboard api? Since all of the content is in a web view I can't find a way to use Javascript to copy text/etc to the clipboard.

Node Webkit has a clipboard api that seems to work well:
https://github.com/rogerwang/node-webkit/wiki/Clipboard

https://github.com/rogerwang/node-webkit/tree/897288eac99ca9895bf209367a9526be67579f1f/src/api/clipboard

Thanks

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/3435202-clipboard-api?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F899498&utm_medium=issues&utm_source=github).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.