Skip to content
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

[GUI] [linux] Support creating fullscreen window by "ti.GUI(fullscreen=True)" #1921

Merged
merged 8 commits into from
Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/gui.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ Create a window
---------------


.. function:: ti.GUI(title = 'Taichi', res = (512, 512), background_color = 0x000000, show_gui = True)
.. function:: ti.GUI(title = 'Taichi', res = (512, 512), background_color = 0x000000, show_gui = True, fullscreen = False)

:parameter title: (optional, string) the window title
:parameter res: (optional, scalar or tuple) resolution / size of the window
:parameter background_color: (optional, RGB hex) background color of the window
:parameter show_gui: (optional, bool) see the note below
:parameter fullscreen: (optional, bool) ``True`` for fullscreen window
:return: (GUI) an object represents the window

Create a window.
Expand Down
22 changes: 22 additions & 0 deletions misc/demo_fullscreen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import taichi as ti
import numpy as np

ti.init()

res = (1920, 1080)
pixels = ti.Vector.field(3, dtype=float, shape=res)


@ti.kernel
def paint():
for i, j in pixels:
u = i / res[0]
v = j / res[1]
pixels[i, j] = [u, v, 0]


gui = ti.GUI('UV', res, fullscreen=True)
while not gui.get_event(ti.GUI.ESCAPE):
paint()
gui.set_image(pixels)
gui.show()
11 changes: 9 additions & 2 deletions python/taichi/misc/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import numpy as np
from taichi.core import ti_core
from .util import deprecated, core_veci
import os


class GUI:
Expand Down Expand Up @@ -38,14 +39,20 @@ def __init__(self,
name='Taichi',
res=512,
background_color=0x0,
show_gui=True):
show_gui=True,
fullscreen=False):
if 'TI_GUI_SHOW' in os.environ:
show_gui = bool(int(os.environ['TI_GUI_SHOW']))
if 'TI_GUI_FULLSCREEN' in os.environ:
fullscreen = bool(int(os.environ['TI_GUI_FULLSCREEN']))

self.name = name
if isinstance(res, numbers.Number):
res = (res, res)
self.res = res
# The GUI canvas uses RGBA for storage, therefore we need NxMx4 for an image.
self.img = np.ascontiguousarray(np.zeros(self.res + (4, ), np.float32))
self.core = ti_core.GUI(name, core_veci(*res), show_gui)
self.core = ti_core.GUI(name, core_veci(*res), show_gui, fullscreen)
self.canvas = self.core.get_canvas()
self.background_color = background_color
self.key_pressed = set()
Expand Down
3 changes: 3 additions & 0 deletions taichi/gui/cocoa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ void GUI::create_window() {
call(window, "becomeFirstResponder");
call(window, "setAcceptsMouseMovedEvents:", YES);
call(window, "makeKeyAndOrderFront:", window);
if (fullscreen) {
call(window, "toggleFullScreen:");
}
}

void GUI::process_event() {
Expand Down
13 changes: 11 additions & 2 deletions taichi/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ class GUI : public GUIBase {
int widget_height;
std::vector<std::unique_ptr<float>> widget_values;
bool show_gui;
bool fullscreen;

void set_mouse_pos(int x, int y) {
cursor_pos = Vector2i(x, y);
Expand Down Expand Up @@ -761,12 +762,14 @@ class GUI : public GUIBase {
int width = 800,
int height = 800,
bool show_gui = true,
bool fullscreen = true,
bool normalized_coord = true)
: window_name(window_name),
width(width),
height(height),
key_pressed(false),
show_gui(show_gui) {
show_gui(show_gui),
fullscreen(fullscreen) {
memset(button_status, 0, sizeof(button_status));
start_time = taichi::Time::get_time();
buffer.initialize(Vector2i(width, height));
Expand All @@ -784,8 +787,14 @@ class GUI : public GUIBase {
explicit GUI(const std::string &window_name,
Vector2i res,
bool show_gui,
bool fullscreen = true,
bool normalized_coord = true)
: GUI(window_name, res[0], res[1], show_gui, normalized_coord) {
: GUI(window_name,
res[0],
res[1],
show_gui,
fullscreen,
normalized_coord) {
}

void create_window();
Expand Down
11 changes: 8 additions & 3 deletions taichi/gui/win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,16 @@ void GUI::create_window() {
GetModuleHandle(0), // Instance handle
NULL // Additional application data
);

TI_ERROR_IF(hwnd == NULL, "Window creation failed");
gui_from_hwnd[hwnd] = this;

if (hwnd == NULL) {
TI_ERROR("Window creation failed");
if (fullscreen) {
// https://www.cnblogs.com/lidabo/archive/2012/07/17/2595452.html
LONG style = GetWindowLong(hwnd, GWL_STYLE);
style &= ~WS_CAPTION & ~WS_SIZEBOX;
SetWindowLong(hwnd, GWL_STYLE, style);
SetWindowPos(hwnd, NULL, 0, 0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN), SWP_NOZORDER);
}

ShowWindow(hwnd, SW_SHOWDEFAULT);
Expand Down
11 changes: 11 additions & 0 deletions taichi/gui/x11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#if defined(TI_GUI_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <cstdlib>

Expand Down Expand Up @@ -143,6 +144,16 @@ void GUI::create_window() {
XCreateSimpleWindow((Display *)display, RootWindow((Display *)display, 0),
0, 0, width, height, 1, 0, 0);
TI_ASSERT_INFO(window, "failed to create X window");

if (fullscreen) {
// https://stackoverflow.com/questions/9083273/x11-fullscreen-window-opengl
Atom atoms[2] = {
XInternAtom((Display *)display, "_NET_WM_STATE_FULLSCREEN", False), 0};
Atom wmstate = XInternAtom((Display *)display, "_NET_WM_STATE", False);
XChangeProperty((Display *)display, window, wmstate, XA_ATOM, 32,
PropModeReplace, (unsigned char *)atoms, 1);
}

XSelectInput((Display *)display, window,
ButtonPressMask | ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPress | ButtonReleaseMask | EnterWindowMask |
Expand Down
2 changes: 1 addition & 1 deletion taichi/python/export_visual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void export_visual(py::module &m) {
.value("Press", Type::press)
.value("Release", Type::release);
py::class_<GUI>(m, "GUI")
.def(py::init<std::string, Vector2i, bool>())
.def(py::init<std::string, Vector2i, bool, bool>())
.def_readwrite("frame_delta_limit", &GUI::frame_delta_limit)
.def_readwrite("should_close", &GUI::should_close)
.def("get_canvas", &GUI::get_canvas, py::return_value_policy::reference)
Expand Down