Code Monkey home page Code Monkey logo

chamferwm's Introduction

chamferwm

A tiling window manager with Vulkan based compositor. Vulkan compositor for external X11 window managers. Documentation

Note Support for DMA-buf import has been added, and has been made default. This can be disabled with --memory-import-mode=1, which will revert to host pointer import method.

Note Initial support for standalone compositor feature has been merged. The program can now be configured to run the Vulkan compositor on external X11 window managers. See below for instructions.

Preview

Features

Window manager:

  • Dynamic horizontal and vertical tiling with gaps and stacking
  • Specify container size restrictions, overlap when necessary
  • Resize and translate individual containers in their place while keeping the surrounding layout
  • Floating containers and automatic dialog, dock, widget etc. handling
  • Multiple named workspaces
  • Yank and paste containers to move them within the tree hierarchy along with typical move operations
  • Configuration with python, scriptable behaviour with client and container specific callbacks
  • Fully keyboard controllable

Compositor:

  • Vulkan renderer
  • Arbitrary window decorations and borders with user supplied shaders
  • Per-client materials
  • Automatically disable for fullscreen applications
  • Optional, alternatively use any other external compositor
  • Standalone compositor mode (beta) to be used in combination with any other window manager

Installing

Prerequisites
  • XCB libraries
  • Vulkan SDK
  • glm
  • Python 3.6+ and boost modules
  • python-xlib
  • shaderc Shader compiler
  • FreeType2
  • HarfBuzz
  • fontconfig
General setup

Currently a PKGBUILD is available for testing purposes. Install from AUR, or run meson to build manually. The package from AUR will install a default configuration and the precompiled shaders to /usr/share/chamfer/. Copy the configuration to another location to make modifications. Put the following line to your .xinitrc:

exec chamfer --config=/usr/share/chamfer/config/config.py --shader-path=/usr/share/chamfer/shaders/

When multiple rendering devices are available, make the choice with --device-index=n, where n is the zero-based index of the device (default = 0). The ordering follows the list reported by vulkaninfo utility. Launch Xorg with startx.

  • To automatically let fullscreen applications bypass the compositor, use --unredir-on-fullscreen. A dedicated workspace with the compositor always disabled is provided, and by default bound to Meta+0.
  • NVIDIA users may have to add Option "AllowSHMPixmaps" "1" to their Xorg configuration, if shared memory import is used (--memory-import-mode=1).
  • For compositor compatibility mode if encountering any issues, use --memory-import-mode=1 or 2 and/or --no-scissoring.

To run the WM without the integrated compositor, use

exec chamfer --config=/usr/share/chamfer/config/config.py -n

In this case, any other external compositor may be used.

Compositor mode for other WMs

The Vulkan compositor can be used together with external X11 window managers. To launch the program in this mode, run

chamfer -C --config=/usr/share/chamfer/config/config.py --shader-path=/usr/share/chamfer/shaders/
Style and decorations

The default "demo" style draws rounded borders around the windows, as well as shadows. The style can be changed by editing the shaders section of the config. Changing the style attributes (color, borders etc.) of the stock shaders is at the moment only possible by editing the values in the fragment shader itself, and then rebuilding. For a complete custom look, the shaders can be replaced entirely. Shaders can be specified on per-window basis, enabling some interesting looks for your desktop.

chamferwm's People

Contributors

jaelpark avatar jbeich 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

chamferwm's Issues

Switching ttys crashes chamfer

Switching back and forth between chamfer and my current wm (which I need to do to properly configure it from a familiar environment) seems to crash chamfer.

To reproduce:

  1. Start chamfer in tty2
  2. chvt 1
  3. chvt 2, then chamfer crashes with:
focus a000e AIGLX: Suspending AIGLX clients for VT switch 
[chamfer]: Error: failed to acquire a swap chain image

Create a more basic shader/aestethic settings in config file

The plan is probably to make the window look, feel and behavior configurable from the python config. For this purpose, it would probably be a good idea to create a shader look that is in between the current frame shader and the shader called default (the frame shader is pretty opinionated for a default look imo). A window border is pretty much a necessity, but shadows, rounderd corners, and dashed border lines aren't. The ability to set the frame border color is pretty much standard for a wm, however, especially for differentiating between focused and unfocused windows (this is something e.g. i3 and bspwm allow/do by default). It would also be nice to disable some animations by default. In other words, a more basic shader, that people can build upon to their liking, is probably a good idea.

I tried to combine the default and frame shader into one myself, but this proved a little too difficult for someone unfamiliar with shaders and vulkan. I haven't tried super hard, but currently it's difficult to see where the code for a basic window border starts, and what is relevant to eyecandy as rounded corners and dashed lines.

Crash on launch

I tried launching chamferwm from exec chamfer --config=/usr/share/chamfer/config/config.py --shader-path=/usr/share/chamfer/shaders/, but it just disconnects me from tty. I tried redirecting stdout to a file to see what happens, but there is only [chamferwm 2020-01-15 19:34:43] Loading config /usr/share/chamfer/config/config.py... No pulsectl module.
Also there is nothing in /var/log/Xorg.0.log
Launching without the compositor does the same.
Launching without exec gives Error: failed to connect to X server (I don't know if this is expected).
I installed on arch with the AUR package, I'm using prime offloading with nvidia and intel proprietary drivers.

If you need any more info just ask.

Multi-monitor Set-up?

Does chamferWM support multi monitor? And if so, what variable would I use for my monitor config?

Thank you.

Entry echo one character behind

At some point after starting chamferwm, the character echoed in the terminal starts to lag one character behind what has been entered.

For example, if I enter "ab", only "a" is echoed until I enter "c" at which point I can see "ab". I then have to enter "space" before I can see "abc".

Installation steps with AUR

Hello, I'm trying to install chamfer from aur, but the installation fails on shaderc-git which throws error without message, just a failure occured in prepare(), nothing more.
Can you help me with installation? I can try to compile from meson, but how about deps for running after that?
Thanks for help.

Immediate crash with xf86-intel-video and xorg-server-git

If I launch chamferwm (with instructions from the README), for a few seconds I see a black screen and a mouse pointer that I can move around, and then it crashes me back to the tty. It doesn't seem like it will let me start any programs.
I can't see any errors in ~/.local/share/xorg/Xorg.0.log. Is there another place where errors are logged?

I installed chamerfwm from the AUR. Other specifics are that I'm running xf86-intel-video-git, xorg-server-git, and a vanilla, fully updated Arch.

It's probably a misconfiguration on my side, so my main question is where to look for errors.

Cannot change window border width

Assuming the window border is controlled by:

self.borderWidth = (0.005,0.005);

..changing the number does not change the width of the border, which obscures the window controls (maximise, minimise, exit).

VK_EXT_image_drm_format_modifier

Hello,

Do you have any information on implementation of VK_EXT_image_drm_format_modifier
we use nvidia on linux width proprietary drivers.

thanks

wbar dock has border

I've just built chamferfm and have it working - couple of questions:

config.py mentions "Panels, docks etc. should be rendered with no decorations.", but a wbar dock I'm using has a 5mm thick black/yellow border all the way around it - should this happen? Is there a way to stop it?

I see that config.py look for psutil and pulsectl and that there is some code about battery percentage, etc, but nothing is displayed?

Is there a man page/wiki somewhere that explains the keybindings (how to launch apps, quit chamferfm, etc)?

Possible to Launch with Light DM?

I have managed to launch chamferWM with light DM, rather inconsistently, is there an available script to write to make the launch successful every time that you may know of?

[idea/request] Standalone compositor

It would be great to use just the vulkan compositor with other WMs, like people use compton in plasma or xfce. Compton itself was considering a vulkan backend but it still didnt fly. What you think, @jaelpark ?

Keystroke to start browser does not work

Assuming the keystroke combo to start a browser is "alt 1", it does not work for me.

The other keystroke combo's I've tried do work - allowing for "alt shift e" not making it to the tty.

Compilation on debian 10

Hi
I try to compile the project on debian 10 and i have lot of error. do you have any idea ?

    ^~~~~

../src/CompositorResource.cpp:776:1: error: could not convert ‘{{"POSITION", VK_FORMAT_R32G32_SFLOAT, 8}, {"POSITION", VK_FORMAT_R32G32_UINT, 8}, {"TEXCOORD", VK_FORMAT_R32G32_SFLOAT, 8}, {"TEXCOORD", VK_FORMAT_R32G32_UINT, 8}}’ from ‘’ to ‘const std::vector<std::tuple<const char*, VkFormat, unsigned int> >’
};
^
../src/CompositorResource.cpp:789:1: error: could not convert ‘{{"xy0", 8}, {"xy1", 8}, {"transform", 16}, {"screen", 8}, {"margin", 8}, {"titlePad", 8}, {"titleSpan", 8}, {"stackIndex", 4}, {"flags", 4}, {"time", 4}}’ from ‘’ to ‘const std::vector<std::tuple<const char*, unsigned int> >’
};
^
../src/CompositorResource.cpp: In constructor ‘Compositor::Pipeline::Pipeline(Compositor::ShaderModule*, Compositor::ShaderModule*, Compositor::ShaderModule*, const std::vector<std::pair<Compositor::ShaderModule::INPUT, unsigned int> >, const VkPipelineInputAssemblyStateCreateInfo, const VkPipelineRasterizationStateCreateInfo*, const VkPipelineDepthStencilStateCreateInfo*, const VkPipelineColorBlendStateCreateInfo*, const VkPipelineDynamicStateCreateInfo*, const Compositor::CompositorInterface*)’:
../src/CompositorResource.cpp:801:186: error: no matching function for call to ‘get<0>(const value_type&)’
DebugPrintf(stdout,"warning: semantic %s in %s at location %u not supported by the input buffer.\n",std::get<0>(ShaderModule::semanticMap[_pvertexShader->inputs[i].semanticMapIndex]),_pvertexShader->pname,_pvertexShader->inputs[i].location);
^
In file included from /usr/include/c++/8/bits/stl_uninitialized.h:60,
from /usr/include/c++/8/vector:63,
from ../src/main.h:9,
from ../src/CompositorResource.cpp:1:
/usr/include/c++/8/utility:216:5: note: candidate: ‘template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)’
get(std::pair<_Tp1, _Tp2>& __in) noexcept
^~~
/usr/include/c++/8/utility:216:5: note: template argument deduction/substitution failed:
../src/CompositorResource.cpp:801:186: note: types ‘std::pair<_Tp1, _Tp2>’ and ‘const value_type’ {aka ‘const std::tuple<const char*, VkFormat, unsigned int>’} have incompatible cv-qualifiers
DebugPrintf(stdout,"warning: semantic %s in %s at location %u not supported by the input buffer.\n",std::get<0>(ShaderModule::semanticMap[_pvertexShader->inputs[i].semanticMapIndex]),_pvertexShader->pname,_pvertexShader->inputs[i].location);
^
In file included from /usr/include/c++/8/bits/stl_uninitialized.h:60,
from /usr/include/c++/8/vector:63,
from ../src/main.h:9,
from ../src/CompositorResource.cpp:1:
/usr/include/c++/8/utility:221:5: note: candidate: ‘template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)’
get(std::pair<_Tp1, _Tp2>&& __in) noexcept
^~~
Thanks

VK_KHR_incremental_present (VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME) does not seem to be available with NVIDIA

As titled. I got the exception thrown at line 492 in compositor.cpp while trying to start it up. It looks like it detected all the extensions except for VK_KHR_incremental_present.

(Also, as a suggestion, it is possible to also list which extensions chamfer is looking for before the listing of detected ones? Just so I don't need to go back to the code to figure out what was missing)


By "detected all the extensions" I mean, everything here except VK_KHR_incremental_present from line 467.

		VK_KHR_SWAPCHAIN_EXTENSION_NAME,
		VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
		VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
		VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME,
		VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
		VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME

Crash on startup with default config

Regressed by f43f8a5.

$ c++ --version
FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)
Target: x86_64-unknown-freebsd12.1
Thread model: posix
InstalledDir: /usr/bin

$ chamfer
[chamferwm 2020-05-21 01:05:25] Found config /usr/local/share/chamfer/config/config.py
No pulsectl module.
Process 99226 stopped
* thread #1, name = 'chamfer', stop reason = signal SIGSEGV: invalid address (fault address: 0xfffffffffffffffc)
    frame #0: 0x0000000000331b7f chamfer`Backend::X11Container::Name1(this=0x00000008013ae280) at backend.cpp:395:75
   392                          p += strlen(m->pname)+1;
   393                  }else *p++ = 0;
   394
-> 395          xcb_change_property(pbackend->pcon,XCB_PROP_MODE_REPLACE,pbackend->pscr->root,pbackend->ewmh._NET_DESKTOP_NAMES,XCB_ATOM_STRING,8,desktopNamesLen,pdesktopNames);
                                                                                         ^
   396
   397          delete []pdesktopNames;
   398  }
(lldb) bt
* thread #1, name = 'chamfer', stop reason = signal SIGSEGV: invalid address (fault address: 0xfffffffffffffffc)
  * frame #0: 0x0000000000331b7f chamfer`Backend::X11Container::Name1(this=0x00000008013ae280) at backend.cpp:395:75
    frame #1: 0x000000000033083d chamfer`Backend::X11Container::X11Container(this=0x00000008013ae280, _pbackend=0x0000000801cacd00) at backend.cpp:277:2
    frame #2: 0x00000000002df6af chamfer`Config::X11ContainerConfig::X11ContainerConfig(this=0x00000008013ae280, _pbackend=0x0000000801cacd00) at config.cpp:393:74
    frame #3: 0x000000000029a59d chamfer`DefaultBackend::DefaultBackend(this=0x0000000801cacd00, _pbackendInt=0x0000000801ab4ca0) at main.cpp:328:85
    frame #4: 0x000000000029817d chamfer`main(argc=1, pargv=0x00007fffffffeb88) at main.cpp:868:23
    frame #5: 0x000000000029510f chamfer`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1.c:76:7
(lldb) p *pbackend
(const Backend::X11Backend) $0 = {
  pcon = 0x0000000000000000
  pscr = 0xfffffffffffffffc
  psymbols = 0x0000000000000000
  window = 0
  lastTime = 0
  eventTimer = (tv_sec = 52474, tv_nsec = 361141766)
  pollTimer = (tv_sec = 0, tv_nsec = 0)
  keycodes = {
    std::__1::__vector_base<Backend::X11Backend::KeyBinding, std::__1::allocator<Backend::X11Backend::KeyBinding> > = {
      __begin_ = 0x0000000000000000
      __end_ = 0x0000000000000000
      __end_cap_ = {
        std::__1::__compressed_pair_elem<Backend::X11Backend::KeyBinding *, 0, false> = {
          __value_ = 0x0000000000000000
        }
      }
    }
  }
  ewmh = {
    connection = 0x0000000801cace88
    screens = 0x0000000000000000
    nb_screens = 0
    _NET_WM_CM_Sn = 0x0000000000000001
    _NET_SUPPORTED = 0
    _NET_CLIENT_LIST = 0
    _NET_CLIENT_LIST_STACKING = 22
    _NET_NUMBER_OF_DESKTOPS = 22
    _NET_DESKTOP_GEOMETRY = 0
    _NET_DESKTOP_VIEWPORT = 0
    _NET_CURRENT_DESKTOP = 120
    _NET_DESKTOP_NAMES = 230
    _NET_ACTIVE_WINDOW = 0
    _NET_WORKAREA = 121
    _NET_SUPPORTING_WM_CHECK = 160
    _NET_VIRTUAL_ROOTS = 1
    _NET_DESKTOP_LAYOUT = 0
    _NET_SHOWING_DESKTOP = 0
    _NET_CLOSE_WINDOW = 0
    _NET_MOVERESIZE_WINDOW = 0
    _NET_WM_MOVERESIZE = 0
    _NET_RESTACK_WINDOW = 0
    _NET_REQUEST_FRAME_EXTENTS = 0
    _NET_WM_NAME = 0
    _NET_WM_VISIBLE_NAME = 0
    _NET_WM_ICON_NAME = 0
    _NET_WM_VISIBLE_ICON_NAME = 0
    _NET_WM_DESKTOP = 0
    _NET_WM_WINDOW_TYPE = 0
    _NET_WM_STATE = 0
    _NET_WM_ALLOWED_ACTIONS = 0
    _NET_WM_STRUT = 0
    _NET_WM_STRUT_PARTIAL = 0
    _NET_WM_ICON_GEOMETRY = 0
    _NET_WM_ICON = 0
    _NET_WM_PID = 0
    _NET_WM_HANDLED_ICONS = 0
    _NET_WM_USER_TIME = 0
    _NET_WM_USER_TIME_WINDOW = 0
    _NET_FRAME_EXTENTS = 0
    _NET_WM_PING = 0
    _NET_WM_SYNC_REQUEST = 0
    _NET_WM_SYNC_REQUEST_COUNTER = 0
    _NET_WM_FULLSCREEN_MONITORS = 0
    _NET_WM_FULL_PLACEMENT = 0
    UTF8_STRING = 0
    WM_PROTOCOLS = 0
    MANAGER = 0
    _NET_WM_WINDOW_TYPE_DESKTOP = 0
    _NET_WM_WINDOW_TYPE_DOCK = 0
    _NET_WM_WINDOW_TYPE_TOOLBAR = 0
    _NET_WM_WINDOW_TYPE_MENU = 0
    _NET_WM_WINDOW_TYPE_UTILITY = 0
    _NET_WM_WINDOW_TYPE_SPLASH = 0
    _NET_WM_WINDOW_TYPE_DIALOG = 0
    _NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0
    _NET_WM_WINDOW_TYPE_POPUP_MENU = 0
    _NET_WM_WINDOW_TYPE_TOOLTIP = 0
    _NET_WM_WINDOW_TYPE_NOTIFICATION = 0
    _NET_WM_WINDOW_TYPE_COMBO = 0
    _NET_WM_WINDOW_TYPE_DND = 0
    _NET_WM_WINDOW_TYPE_NORMAL = 0
    _NET_WM_STATE_MODAL = 0
    _NET_WM_STATE_STICKY = 0
    _NET_WM_STATE_MAXIMIZED_VERT = 0
    _NET_WM_STATE_MAXIMIZED_HORZ = 0
    _NET_WM_STATE_SHADED = 0
    _NET_WM_STATE_SKIP_TASKBAR = 0
    _NET_WM_STATE_SKIP_PAGER = 0
    _NET_WM_STATE_HIDDEN = 0
    _NET_WM_STATE_FULLSCREEN = 3988824
    _NET_WM_STATE_ABOVE = 0
    _NET_WM_STATE_BELOW = 8202400
    _NET_WM_STATE_DEMANDS_ATTENTION = 8
    _NET_WM_ACTION_MOVE = 0
    _NET_WM_ACTION_RESIZE = 0
    _NET_WM_ACTION_MINIMIZE = 0
    _NET_WM_ACTION_SHADE = 0
    _NET_WM_ACTION_STICK = 0
    _NET_WM_ACTION_MAXIMIZE_HORZ = 0
    _NET_WM_ACTION_MAXIMIZE_VERT = 0
    _NET_WM_ACTION_FULLSCREEN = 0
    _NET_WM_ACTION_CHANGE_DESKTOP = 0
    _NET_WM_ACTION_CLOSE = 0
    _NET_WM_ACTION_ABOVE = 0
    _NET_WM_ACTION_BELOW = 0
  }
  ewmh_window = 31387920
  appendixQueue = {
    std::__1::__deque_base<std::__1::pair<const WManager::Client *, WManager::Client *>, std::__1::allocator<std::__1::pair<const WManager::Client *, WManager::Client *> > > = {
      __map_ = {
        __first_ = 0x0000000000000000
        __begin_ = 0x0000000000000000
        __end_ = 0x0000000000000000
        __end_cap_ = {
          std::__1::__compressed_pair_elem<std::__1::pair<const WManager::Client *, WManager::Client *> **, 0, false> = {
            __value_ = 0x0000000000000000
          }
        }
      }
      __start_ = 0
      __size_ = {
        std::__1::__compressed_pair_elem<unsigned long, 0, false> = (__value_ = 0)
      }
    }
  }
  atoms = ([0] = 0, [1] = 0, [2] = 0, [3] = 0)
  pcursorctx = 0x0000000000000000
  cursors = ([0] = 0)
}

White screen

I installed chamferWM via AUR.
When using the following command in xinit.rc:

exec chamfer --config=/usr/share/chamfer/config/config.py --shader-path=/usr/share/chamfer/shaders/

I only get a blank white screen.

I also tried:
exec stdbuf -oL chamfer --shader-path=/usr/share/chamfer/shaders/ > /tmp/log
but the log does not contain any errors

Error: SHM extension unavailable.

libxcb is installed of course... :(

System:
Host: jfpc Kernel: 5.2.9-22-tkg-pds x86_64 bits: 64 Desktop: Xfce 4.14.1
Distro: Arch Linux
Graphics:
Device-1: NVIDIA GM204 [GeForce GTX 970] driver: nvidia v: 430.40
Display: x11 server: X.Org 1.20.5 driver: nvidia
resolution: 1920x1080~60Hz
OpenGL: renderer: GeForce GTX 970/PCIe/SSE2 v: 4.6.0 NVIDIA 430.40

Cursor does not show when chamferwm first started

When chamferwm is first started the cursor does not show.

I am obliged to move the mouse blind until it rolls over the wbar dock and the cursor appears, so I can launch an app.

If the app launches full screen, then the cursor remains for the rest of the session. If the app launches part screen, then the cursor is not visible over the background.

Can't focus java swing window

as title.

error log maybe relevant

[chamferwm 2022-05-25 16:54:46] Error: Failed to allocate transfer buffer memory.
[chamferwm 2022-05-25 16:54:46] Error: Failed to import host memory. Disabling feature.

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.