Giter Club home page Giter Club logo

aw-qt's Introduction

aw-qt

GitHub Actions badge Code style: black Typechecking: Mypy

A service manager and tray icon managing aw-server and watchers, built with Qt.

For instructions how to build, see Makefile.

aw-qt's People

Contributors

drarig29 avatar erikbjare avatar exoji2e avatar huantianad avatar infokiller avatar johan-bjareholt avatar lgtm-com[bot] avatar maciekstosio avatar victorwinberg avatar wolfercz avatar xylix 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

aw-qt's Issues

Deciding on a framework

We need a tray icon, and I currently have four options where I need to choose one, a critical decision.

Options:

  • Written in Python
    • With GTK
    • With QT
  • Written in JavaScript/Node.js
    • With Electron
    • With NW.js (formerly node-webkit)

Unable to build a wheel

pip install wheel
fixed the issue, should probably be done by build script
(also upgraded pip, but not sure that was needed)

"Open Dashboard/API Browser" not working when packaged with PyInstaller

When running aw-qt, the "Open Dashboard" and "Open API Browser" buttons fail to open the browser. When running aw-qt from source on the latest master it works fine though.

This part seems to be the cause

/usr/lib/firefox/firefox: /home/johan/Downloads/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)

Here are the full logs

Opening dashboard
/usr/lib/firefox/firefox: /home/johan/Downloads/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/bin/xdg-open: line 854: x-www-browser: command not found
/usr/lib/firefox/firefox: /home/johan/Downloads/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/bin/xdg-open: line 854: iceweasel: command not found
/usr/bin/xdg-open: line 854: seamonkey: command not found
/usr/bin/xdg-open: line 854: mozilla: command not found
/usr/bin/xdg-open: line 854: epiphany: command not found
/usr/bin/xdg-open: line 854: konqueror: command not found
/usr/bin/xdg-open: line 854: chromium: command not found
/usr/bin/xdg-open: line 854: chromium-browser: command not found
/usr/bin/xdg-open: line 854: google-chrome: command not found
/usr/bin/xdg-open: line 854: www-browser: command not found
/usr/bin/xdg-open: line 854: links2: command not found
/usr/bin/xdg-open: line 854: elinks: command not found
/usr/bin/xdg-open: line 854: links: command not found
/usr/bin/xdg-open: line 854: lynx: command not found
/usr/bin/xdg-open: line 854: w3m: command not found
xdg-open: no method available for opening 'http://localhost:5600'
Opening api browser
/usr/lib/firefox/firefox: /home/johan/Downloads/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/bin/xdg-open: line 854: x-www-browser: command not found
/usr/lib/firefox/firefox: /home/johan/Downloads/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/bin/xdg-open: line 854: iceweasel: command not found
/usr/bin/xdg-open: line 854: seamonkey: command not found
/usr/bin/xdg-open: line 854: mozilla: command not found
/usr/bin/xdg-open: line 854: epiphany: command not found
/usr/bin/xdg-open: line 854: konqueror: command not found
/usr/bin/xdg-open: line 854: chromium: command not found
/usr/bin/xdg-open: line 854: chromium-browser: command not found
/usr/bin/xdg-open: line 854: google-chrome: command not found
/usr/bin/xdg-open: line 854: www-browser: command not found
/usr/bin/xdg-open: line 854: links2: command not found
/usr/bin/xdg-open: line 854: elinks: command not found
/usr/bin/xdg-open: line 854: links: command not found
/usr/bin/xdg-open: line 854: lynx: command not found
/usr/bin/xdg-open: line 854: w3m: command not found
xdg-open: no method available for opening 'http://localhost:5600/api'

Crashes when pressing "Open Log Folder"

Traceback (most recent call last):
  File "/home/johan/Programming/activitywatch/aw-qt/aw_qt/trayicon.py", line 78, in <lambda>
    menu.addAction("Open log folder", lambda: open_dir(aw_core.dirs.get_log_dir()))
  File "/home/johan/Programming/activitywatch/aw-core/aw_core/dirs.py", line 10, in wrapper
    path = f(*args, **kwargs)
TypeError: get_log_dir() missing 1 required positional argument: 'module_name'
zsh: abort (core dumped)  aw-qt

PyInstaller builds crashes on start in Windows

Traceback (most recent call last):
  File "site-packages\PyInstaller\loader\rthooks\pyi_rth_qt5plugins.py", line 46, in <module>
  File "c:\python35\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 573, in load_module
ImportError: DLL load failed: Det går inte att hitta den angivna proceduren.
Failed to execute script pyi_rth_qt5plugins

Seems related to this: pyinstaller/pyinstaller#2152

Attempting a fix in: 597fdf1

Edit: Also related to [these pyinstaller warnings]

7562 WARNING: lib not found: Qt5Svg.dll dependency of C:\python35\lib\site-packages\PyQt5\Qt\plugins\imageformats\qsvg.dll
7999 WARNING: lib not found: Qt5Svg.dll dependency of C:\python35\lib\site-packages\PyQt5\Qt\plugins\iconengines\qsvgicon.dll
8437 WARNING: lib not found: Qt5PrintSupport.dll dependency of C:\python35\lib\site-packages\PyQt5\Qt\plugins\printsupport\windowsprintersupport.dll
8921 WARNING: lib not found: Qt5PrintSupport.dll dependency of c:\python35\lib\site-packages\PyQt5\QtPrintSupport.pyd

Separate the manager from the UI

I'm using ChromeOS and to track its Linux activity I had to start each component manually and it's not really working. Events aren't being logged from the chrome extension even though the extension says it's connected to the server (might just be in testing mode).

Anyway if the management part was separate it'd also make #32 easier.

Refresh module feature

  1. being able to refresh module without having to restart the app would be nice
  2. in windows some system modules are installed deep inside system PATH, opening the module location by right-clicking would also be nice (or at least have some way to know where the module is installed)

Use port from config

Port 5600 is hardcoded, but should be read from the server config file:

self.root_url = "http://localhost:{port}".format(port=5666 if self.testing else 5600)

Usecase:

My brother & I both use activitywatch on our common PC. His aw-server process runs on port 5600, while mine runs on port 5700. When launching the dashboard from trayicon, it always opens up port 5600!

aw-qt is not very good at managing modules

In my short ActivityWatch experience, I've had some issues with aw-qt. First of all, should a module crash, aw-qt does not restart it. In particular, aw-watcher-window crashes a lot on macOS for me due to a certain application that is seemingly missing the localizedName attribute (which macos.swift unwraps, crashing the application. I will look into contributing a fix). I've resorted to having a shell script manage aw-watcher-window. Second, aw-qt randomly stopped aw-server-rust and started aw-server. This caused my data to go into the wrong database for around a day until I found out.

I suggest that aw-qt restarts a module if it crashes. I am unsure what caused the server switch, but perhaps the selected server should be a separate, more persistent configuration option.

Cannot start on macOS Catalina

When i want to run aw-qt, macOS stop the app and if we force macOS to launch aw-qt in settings the same message appears for another python library and so on it does not end any more.

Capture d’écran 2019-11-26 à 22 11 01

Spec infos:

  • MacOS 10.15

If you need more details tell me :)

Install fails on older Ubuntu/Mint due to PyQt6

Since on the binary release I got

[21440] Error loading Python lib '/[redacted]/activitywatch-v0.12.0/libpython3.8.so.1.0': dlopen: /[redacted]/libpython3.8.so.1.0: cannot open shared object file: No such file or directory

I'm compiling from scratch. This worked on Linux Mint 19.3 for v0.12.0 but failed for v0.12.1 with the following issue:

https://stackoverflow.com/questions/72275959/pip-install-pyqt6-fails-module-sipbuild-api-has-no-attribute-prepare-metadat

The only way I could currently make it work was downgrade the aw-qt submodule to v0.12.0 version using

(cd aw-qt && git checkout 730575bc16223a9c030bced07a7851299be33119) && make build

Build fails on Ubuntu 20.04

Build fails on Ubuntu 20.04 with the error:
ERROR: Package 'aw-qt' requires a different Python: 3.8.2 not in '>=3.6,<3.8'

Seems to be caused by commit 91f250b

What was the reason for downgrading?

I've tried changing the .toml to include 3.8.2, but that results in:
ERROR: Could not find a version that satisfies the requirement sip<4.20,>=4.19.4 (from PyQt5==5.10.1->aw-qt==0.1.0) (from versions: 5.0.0, 5.0.1, 5.1.0, 5.1.1, 5.1.2, 5.2.0)
ERROR: No matching distribution found for sip<4.20,>=4.19.4 (from PyQt5==5.10.1->aw-qt==0.1.0)

tray-icon "Open Dashboard" uses the wrong browser on ubuntu 20.04

Using "Open Dashboard" defaults to Chrome even though the system default is Firefox.

I've tried having a look at the code that's launching it (here?) and what's strange that both xdg-open and webbrowser module in python on my system use the correct browser (Firefox), but AW tray-icon still launches in Chrome.

Both python3 -c "import webbrowser; webbrowser.open('bla')" and xdg-open "http://bla" open Firefox correctly.

Broken error handling when a module crashes

A bug where aw-qt crashes when trying to fetch and log stderr from a crashing module.

ActivityWatch/activitywatch#85

Reading active process stderr...
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/aw_qt-0.1-py3.6.egg/aw_qt/trayicon.py", line 110, in rebuild_modules_menu
show_module_failed_dialog(module)
  File "/usr/lib/python3.6/site-packages/aw_qt-0.1-py3.6.egg/aw_qt/trayicon.py", line 96, in show_module_failed_dialog
    box.setDetailedText(module.stderr())
  File "/usr/lib/python3.6/site-packages/aw_qt-0.1-py3.6.egg/aw_qt/manager.py", line 108, in stderr
    self._log += self._process.stderr.read()
AttributeError: 'NoneType' object has no attribute 'read'

Building with newest pyqt fails

After following official build info

(venv) chozabu@chozabu-32:~/devel/activitywatch$ pip freeze
...
PyQt5==5.11.2
...

versions: 5.6, 5.7, 5.7.1, 5.8, 5.8.1.1, 5.8.2, 5.9, 5.9.1, 5.9.2, 5.10, 5.10.1, 5.11.2)

(venv) chozabu@chozabu-32:~/devel/activitywatch$ pip install PyQT5==5.10.1

[build now works]

Open Dashboard opens in Chromium instead of my default browser Firefox

When clicking "Open Dashboard" it opens up in Chromium rather than my default browser Firefox (on Xubuntu 18.04). Chromium also seems to hang right away.

Following is what I assume is the relevant terminal output when clicking "Open Dashboard"

/usr/bin/exo-open: symbol lookup error: /usr/lib/x86_64-linux-gnu/libexo-2.so.0: undefined symbol: gdk_display_get_default_seat
/usr/bin/exo-open: symbol lookup error: /usr/lib/x86_64-linux-gnu/libexo-2.so.0: undefined symbol: gdk_display_get_default_seat
/usr/lib/firefox/firefox: /home/johannesg/bin/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/lib/firefox/firefox: /home/johannesg/bin/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: iceweasel: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: seamonkey: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: mozilla: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: epiphany: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: konqueror: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: chromium: not found
/usr/bin/exo-open: symbol lookup error: /usr/lib/x86_64-linux-gnu/libexo-2.so.0: undefined symbol: gdk_display_get_default_seat
/usr/bin/exo-open: symbol lookup error: /usr/lib/x86_64-linux-gnu/libexo-2.so.0: undefined symbol: gdk_display_get_default_seat
/usr/lib/firefox/firefox: /home/johannesg/bin/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/lib/firefox/firefox: /home/johannesg/bin/activitywatch/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/lib/firefox/firefox)
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: iceweasel: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: seamonkey: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: mozilla: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: epiphany: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: konqueror: not found
/usr/bin/xdg-open: 851: /usr/bin/xdg-open: chromium: not found

Running xdg-open http://localhost:5600 straight from the terminal runs firefox without problems.

Future of aw-qt

A while back, I was looking for a nice syncthing UI for Windows (starting a terminal and running it there everytime when needed wasn't enough anymore) and I found SyncTrayzor but never got around to installing it.

But today I did, and what surprised me was a full-blown WebView that shows the web UI. This is something I think we want for all our users by default. We would still be able to run the components separately and keep them modular (for those that prefer), but for the average user the only program they need to care about running should be aw-qt. It will handle the rest. Advanced users might want to run it "headless" so to speak (or on systems where we might not get much done in a while, such as on Android/iOS).

  • aw-qt should have a option to open a window with a webview containing the web UI.
  • aw-qt should ensure autostart on boot if it's such setting is set.
  • aw-qt should access the web UI with authentication so that it isn't exposed to the network.
    • There are many ways to do this: GET parameter (like git-annex-webapp), headers, etc.

Make aw-qt save logs instead of each module

Today we have an issue of not capturing stderr in the logs for the modules, essentially making the logs shown when the modules crash pointless.
It might be possible to work around it with something like the following, but it feels more like a hack https://stackoverflow.com/a/31688396/2127148

I think the proper way to do it would be to let aw-qt capture stdout and stderr instead of doing it in aw-core and then also make aw-qt responsible for saving the logs to disk.

@ErikBjare What do you think?

aw-qt long start/exit

When you start aw-qt it takes like 20 seconds to start up before it's usable.
Also after I press Quit ActivityWatch button in the right-click menu it takes like 20 seconds for the confirmation dialog to show up.

I think both of those are related to outdated fontconfig as I've seen similar reports for other programs (telegram, peek, chromium)

This #33 should probably solve it, but I think it's better for it to be saved here to make sure it's fixed later.

Arch linux, AW installed via AUR package, latest version.
Linux neko 4.17.2-1-ARCH #1 SMP PREEMPT Sat Jun 16 11:08:59 UTC 2018 x86_64 GNU/Linux

No tray icon on GNOME Wayland

I have the AppIndicator Support extension installed, and other tray icons are working fine. But when I launch aw-qt, the tray icon does not appear. If I run it from the terminal, I get an error:

(aw-qt:109375): GLib-GIO-ERROR **: 00:55:08.634: Settings schema 'org.gnome.settings-daemon.plugins.xsettings' does not contain a key named 'antialiasing'

Unable to find system modules on macOS

Versions:

# macOS 13.0.1
$ uname -a
Darwin macbook.local 22.1.0 Darwin Kernel Version 22.1.0

$ /Applications/ActivityWatch.app/Contents/MacOS/aw-server --version
v0.12.2b1

Problem:

Running aw-qt through Finder it's unable to find any system modules:

image

2023-01-30 11:29:45 [INFO ]: Started aw-qt...  (aw_qt.main:53)
2023-01-30 11:29:45 [INFO ]: Found 4 bundled modules  (aw_qt.manager:85)
2023-01-30 11:29:45 [INFO ]: Found 0 system modules  (aw_qt.manager:119)

However, running through the command line it is able to:

image

$ /Applications/ActivityWatch.app/Contents/MacOS/aw-qt
[...]
2023-01-30 11:32:29 [INFO ]: Started aw-qt...  (aw_qt.main:53)
2023-01-30 11:32:29 [INFO ]: Found 4 bundled modules  (aw_qt.manager:85)
2023-01-30 11:32:29 [INFO ]: Found 2 system modules  (aw_qt.manager:119)

Builds of aw-qt (with PyInstaller) don't appear to be portable

I'm getting crashes when trying to run aw-qt on various Linux machines.

For example, on my Ubuntu laptop:

↪ ➤➤➤ ~/Applications/activitywatch/aw-qt --testing
INFO:aw.qt.manager:Starting module aw-server
DEBUG:aw.qt.manager:Found executable for aw-server in: /home/erb/Applications/activitywatch/aw-server
DEBUG:aw.qt.manager:Running: ['/home/erb/Applications/activitywatch/aw-server', '--testing']
INFO:aw.qt.manager:Starting module aw-watcher-afk
DEBUG:aw.qt.manager:Found executable for aw-watcher-afk in: /home/erb/Applications/activitywatch/aw-watcher-afk
DEBUG:aw.qt.manager:Running: ['/home/erb/Applications/activitywatch/aw-watcher-afk', '--testing']
INFO:aw.qt.manager:Starting module aw-watcher-window
DEBUG:aw.qt.manager:Found executable for aw-watcher-window in: /home/erb/Applications/activitywatch/aw-watcher-window
DEBUG:aw.qt.manager:Running: ['/home/erb/Applications/activitywatch/aw-watcher-window', '--testing']
INFO:root:Creating trayicon...
Gtk-Message: Failed to load module "atk-bridge"
fish: “~/Applications/activitywatch/aw…” terminated by signal SIGSEGV (Address boundary error)

The error message Failed to load module "atk-bridge" has been seen in other places where is was solved by installing the packages libatk-adaptor, but that didn't solve it for me.

I've seen variations of the error on an arch machine (not yet tested on mine), can't remember but could have just been the addition of the libgail as referenced in the linked askubuntu link above.

Doesn't start with pyinstaller anymore

Ran GDB on windows from the build on my 0.8.0b8 branch and got this sefault
ActivityWatch/activitywatch#270

starting aw-server manually works fine

#0  0x74013397 in python35!PyDict_SetItem () from C:\Users\Johaj\Desktop\activitywatch-0.8.0b8-prerelease\python35.dll
#1  0x6eca5d14 in pythoncom35!?PyCom_IsGatewayRegistered@@YAHABU_GUID@@@Z ()
   from C:\Users\Johaj\Desktop\activitywatch-0.8.0b8-prerelease\pythoncom35.dll
#2  0x04ec4698 in ?? ()
#3  0x7421fb38 in python35!PyTupleIter_Type ()
   from C:\Users\Johaj\Desktop\activitywatch-0.8.0b8-prerelease\python35.dll
#4  0x00000000 in ?? ()

"Open log folder" opens a web browser

Clicking on the "Open log folder" opens up a Chrome window with my log directory, rather than a file browser. This is particularly strange since Chrome isn't my default web browser. Running xdg-open manually with either of these commands gives the intended behavior (opening with file browser):

  • xdg-open "file:///$HOME/.cache/activitywatch/log/"
  • xdg-open "$HOME/.cache/activitywatch/log/"

Opening the dashboard and API browser work correctly and use my default browser.

I'm on Ubuntu 18.04 using the v0.10.0 ActivityWatch distributable.

Rewrite in some other language

Since PyInstaller does not work reliably with QT and has created lots of issues for us we should probably consider writing it in a QT-native language so it can work cross-platform more reliably.

My first choice would be to write it in C++ with QT, but writing it in Rust with gtk-rs could also be an option if we feel like experimenting a bit.

Systray icon is missing on Fedora 35 KDE plasma 5.23

Executing aw-qt binary get these errors and system tray icon is not showing, while other processes run fine.

Got keys from plugin meta data ("xcb")
QFactoryLoader::QFactoryLoader() checking directory path "/home/me/opt/activitywatch/platforms" ...
Cannot load library /home/me/opt/activitywatch/PyQt5/Qt/plugins/platforms/libqxcb.so: (/lib64/libfreetype.so.6: undefined symbol: hb_ot_tags_from_script_and_language)
QLibraryPrivate::loadPlugin failed on "/home/me/opt/activitywatch/PyQt5/Qt/plugins/platforms/libqxcb.so" : "Cannot load library /home/me/opt/activitywatch/PyQt5/Qt/plugins/platforms/libqxcb.so: (/lib64/libfreetype.so.6: undefined symbol: hb_ot_tags_from_script_and_language)"
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

Configurable available and autostart modules

As a developer I would like to integrate my private watchers to the aw-qt without necessity to alter the aw-qt and maintain my own fork.

Currently aw-qt (v0.8.0b9) supports only few modules that are hard-coded in:

_possible_modules = [


Posible solutions:

Based on TODO in

# TODO: Fetch these from somewhere appropriate (auto detect or a config file)

aw_qt/manager.py:

# TODO: Fetch these from somewhere appropriate (auto detect or a config file)
#       Save to config wether they should autostart or not.
_possible_modules = [
    "aw-server",
    "aw-watcher-afk",
    "aw-watcher-window",
    # "aw-watcher-spotify",
    # "aw-watcher-network"
]
  1. Available modules and modules to be started automatically will be listed in new aw-qt configuration.
  2. Autodetect available modules. Modules to be started automatically will be listed in new aw-qt configuration.

NOTE: Available modules can be separated to independent issue/story (nice to have).

Application exits prematurely if QSystemTrayIcon.isSystemTrayAvailable() is false

On startup, aw-qt checks if QSystemTrayIcon.isSystemTrayAvailable() is false. If there isn't a system tray available, it simply exits since it cannot show an icon. This behavior makes sense most of the time.

However, on my system running KDE Plasma 5.27.3 (and I'd assume other Plasma systems), autostart programs are called before the panel containing a system tray is loaded. This causes aw-qt to crash on startup, as it tries to find a system tray, but Plasma has not yet loaded it.

This can simply be fixed by skipping or delaying the check to QSystemTrayIcon.isSystemTrayAvailable(). According to the QT docs, "If the system tray is currently unavailable but becomes available later, QSystemTrayIcon will automatically add an entry in the system tray if it is visible." Therefore, even if on startup QSystemTrayIcon.isSystemTrayAvailable() is false, QSystemTrayIcon will still properly display once the system tray is loaded.

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.