Track application focus state in global state

This commit is contained in:
Kovid Goyal 2017-09-13 08:26:16 +05:30
parent e6df82b255
commit 6e4b977128
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 38 additions and 35 deletions

View File

@ -93,7 +93,6 @@ extern int init_Line(PyObject *);
extern int init_ColorProfile(PyObject *);
extern int init_Screen(PyObject *);
extern int init_Face(PyObject *);
extern int init_Window(PyObject *);
extern bool init_freetype_library(PyObject*);
extern bool init_fontconfig_library(PyObject*);
extern bool init_glfw(PyObject *m);
@ -131,7 +130,6 @@ PyInit_fast_data_types(void) {
} else {
if (!init_shaders(m)) return NULL;
}
if (!init_Window(m)) return NULL;
#ifdef __APPLE__
if (!init_CoreText(m)) return NULL;
if (!init_cocoa(m)) return NULL;

View File

@ -4,7 +4,7 @@
* Distributed under terms of the GPL3 license.
*/
#include "data-types.h"
#include "state.h"
#include <structmember.h>
#include <GLFW/glfw3.h>
#if defined(__APPLE__)
@ -16,6 +16,7 @@
#error "glfw >= 3.2 required"
#endif
extern GlobalState global_state;
#define MAX_WINDOWS 256
#define CALLBACK(name, fmt, ...) \
@ -34,10 +35,10 @@ typedef struct {
GLFWwindow *window;
PyObject *framebuffer_size_callback, *char_mods_callback, *key_callback, *mouse_button_callback, *scroll_callback, *cursor_pos_callback, *window_focus_callback;
GLFWcursor *standard_cursor, *click_cursor;
} Window;
} WindowWrapper;
// callbacks {{{
static Window* the_window = NULL;
static WindowWrapper* the_window = NULL;
static void
framebuffer_size_callback(GLFWwindow UNUSED *w, int width, int height) {
@ -71,19 +72,20 @@ cursor_pos_callback(GLFWwindow UNUSED *w, double x, double y) {
static void
window_focus_callback(GLFWwindow UNUSED *w, int focused) {
global_state.application_focused = focused ? true : false;
WINDOW_CALLBACK(window_focus_callback, "O", focused ? Py_True : Py_False);
}
// }}}
static PyObject*
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
Window *self;
WindowWrapper *self;
char *title;
int width, height;
if (!PyArg_ParseTuple(args, "iis", &width, &height, &title)) return NULL;
if (the_window != NULL) { PyErr_SetString(PyExc_ValueError, "Only one glfw window is supported"); return NULL; }
self = (Window *)type->tp_alloc(type, 0);
self = (WindowWrapper *)type->tp_alloc(type, 0);
if (self != NULL) {
the_window = self;
self->window = glfwCreateWindow(width, height, title, NULL, NULL);
@ -207,7 +209,7 @@ glfw_init_hint_string(PyObject UNUSED *self, PyObject *args) {
// }}}
static void
dealloc(Window* self) {
dealloc(WindowWrapper* self) {
the_window = NULL;
Py_CLEAR(self->framebuffer_size_callback); Py_CLEAR(self->char_mods_callback); Py_CLEAR(self->key_callback); Py_CLEAR(self->mouse_button_callback); Py_CLEAR(self->scroll_callback); Py_CLEAR(self->cursor_pos_callback); Py_CLEAR(self->window_focus_callback);
if (self->window != NULL) glfwDestroyWindow(self->window);
@ -215,43 +217,43 @@ dealloc(Window* self) {
}
static PyObject*
swap_buffers(Window *self) {
swap_buffers(WindowWrapper *self) {
glfwSwapBuffers(self->window);
Py_RETURN_NONE;
}
static PyObject*
make_context_current(Window *self) {
make_context_current(WindowWrapper *self) {
glfwMakeContextCurrent(self->window);
Py_RETURN_NONE;
}
static PyObject*
window_id(Window *self) {
window_id(WindowWrapper *self) {
return PyLong_FromVoidPtr(self->window);
}
static PyObject*
should_close(Window *self) {
should_close(WindowWrapper *self) {
PyObject *ans = glfwWindowShouldClose(self->window) ? Py_True : Py_False;
Py_INCREF(ans);
return ans;
}
static PyObject*
get_clipboard_string(Window *self) {
get_clipboard_string(WindowWrapper *self) {
return Py_BuildValue("s", glfwGetClipboardString(self->window));
}
static PyObject*
get_cursor_pos(Window *self) {
get_cursor_pos(WindowWrapper *self) {
double x=0, y=0;
glfwGetCursorPos(self->window, &x, &y);
return Py_BuildValue("dd", x, y);
}
static PyObject*
set_should_close(Window *self, PyObject *args) {
set_should_close(WindowWrapper *self, PyObject *args) {
int c;
if (!PyArg_ParseTuple(args, "p", &c)) return NULL;
glfwSetWindowShouldClose(self->window, c);
@ -259,7 +261,7 @@ set_should_close(Window *self, PyObject *args) {
}
static PyObject*
set_input_mode(Window *self, PyObject *args) {
set_input_mode(WindowWrapper *self, PyObject *args) {
int which, value;
if (!PyArg_ParseTuple(args, "ii", &which, &value)) return NULL;
glfwSetInputMode(self->window, which, value);
@ -267,7 +269,7 @@ set_input_mode(Window *self, PyObject *args) {
}
static PyObject*
is_key_pressed(Window *self, PyObject *args) {
is_key_pressed(WindowWrapper *self, PyObject *args) {
int c;
if (!PyArg_ParseTuple(args, "i", &c)) return NULL;
PyObject *ans = glfwGetKey(self->window, c) == GLFW_PRESS ? Py_True : Py_False;
@ -276,7 +278,7 @@ is_key_pressed(Window *self, PyObject *args) {
}
static PyObject*
set_click_cursor(Window *self, PyObject *args) {
set_click_cursor(WindowWrapper *self, PyObject *args) {
int c;
if (!PyArg_ParseTuple(args, "p", &c)) return NULL;
glfwSetCursor(self->window, c ? self->click_cursor : self->standard_cursor);
@ -284,7 +286,7 @@ set_click_cursor(Window *self, PyObject *args) {
}
static PyObject*
set_clipboard_string(Window *self, PyObject *args) {
set_clipboard_string(WindowWrapper *self, PyObject *args) {
char *title;
if(!PyArg_ParseTuple(args, "s", &title)) return NULL;
glfwSetClipboardString(self->window, title);
@ -292,7 +294,7 @@ set_clipboard_string(Window *self, PyObject *args) {
}
static PyObject*
set_window_icon(Window *self, PyObject *args) {
set_window_icon(WindowWrapper *self, PyObject *args) {
GLFWimage logo;
Py_ssize_t sz;
if(!PyArg_ParseTuple(args, "s#ii", &(logo.pixels), &sz, &(logo.width), &(logo.height))) return NULL;
@ -302,7 +304,7 @@ set_window_icon(Window *self, PyObject *args) {
static PyObject*
_set_title(Window *self, PyObject *args) {
_set_title(WindowWrapper *self, PyObject *args) {
char *title;
if(!PyArg_ParseTuple(args, "s", &title)) return NULL;
glfwSetWindowTitle(self->window, title);
@ -311,14 +313,14 @@ _set_title(Window *self, PyObject *args) {
static PyObject*
get_framebuffer_size(Window *self) {
get_framebuffer_size(WindowWrapper *self) {
int w, h;
glfwGetFramebufferSize(self->window, &w, &h);
return Py_BuildValue("ii", w, h);
}
static PyObject*
get_window_size(Window *self) {
get_window_size(WindowWrapper *self) {
int w, h;
glfwGetWindowSize(self->window, &w, &h);
return Py_BuildValue("ii", w, h);
@ -360,7 +362,7 @@ current_monitor(GLFWwindow *window) {
}
static PyObject*
current_monitor_dpi(Window *self) {
current_monitor_dpi(WindowWrapper *self) {
GLFWmonitor *m = current_monitor(self->window);
if (m == NULL) return NULL;
return get_physical_dpi(m);
@ -368,7 +370,7 @@ current_monitor_dpi(Window *self) {
#ifdef glfwRequestWindowAttention
static PyObject*
request_window_attention(Window *self) {
request_window_attention(WindowWrapper *self) {
glfwRequestWindowAttention(self->window);
Py_RETURN_NONE;
}
@ -376,7 +378,7 @@ request_window_attention(Window *self) {
#ifdef __APPLE__
static PyObject*
cocoa_window_id(Window *self) {
cocoa_window_id(WindowWrapper *self) {
void *wid = glfwGetCocoaWindow(self->window);
if (wid == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to get native window handle"); return NULL; }
return PyLong_FromVoidPtr(wid);
@ -413,7 +415,7 @@ static PyMethodDef methods[] = {
};
static PyMemberDef members[] = {
#define CBE(name) {#name, T_OBJECT_EX, offsetof(Window, name), 0, #name}
#define CBE(name) {#name, T_OBJECT_EX, offsetof(WindowWrapper, name), 0, #name}
CBE(framebuffer_size_callback),
CBE(char_mods_callback),
CBE(key_callback),
@ -425,10 +427,10 @@ static PyMemberDef members[] = {
#undef CBE
};
PyTypeObject Window_Type = {
PyTypeObject WindowWrapper_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "fast_data_types.Window",
.tp_basicsize = sizeof(Window),
.tp_name = "fast_data_types.GLFWWindow",
.tp_basicsize = sizeof(WindowWrapper),
.tp_dealloc = (destructor)dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = "A GLFW window",
@ -437,8 +439,6 @@ PyTypeObject Window_Type = {
.tp_new = new,
};
INIT_TYPE(Window)
static PyMethodDef module_methods[] = {
{"glfw_set_error_callback", (PyCFunction)glfw_set_error_callback, METH_O, ""}, \
{"glfw_init", (PyCFunction)glfw_init, METH_NOARGS, ""}, \
@ -457,6 +457,9 @@ static PyMethodDef module_methods[] = {
bool
init_glfw(PyObject *m) {
if (PyModule_AddFunctions(m, module_methods) != 0) return false;
if (PyType_Ready(&WindowWrapper_Type) < 0) return false;
if (PyModule_AddObject(m, "GLFWWindow", (PyObject *)&WindowWrapper_Type) != 0) return 0;
Py_INCREF(&WindowWrapper_Type);
glfwSetErrorCallback(cb_error_callback);
#define ADDC(n) if(PyModule_AddIntConstant(m, #n, n) != 0) return false;
#ifdef GLFW_X11_WM_CLASS_NAME

View File

@ -20,7 +20,7 @@ from .fast_data_types import (
GL_VERSION_REQUIRED, GLFW_CONTEXT_VERSION_MAJOR,
GLFW_CONTEXT_VERSION_MINOR, GLFW_DECORATED, GLFW_OPENGL_CORE_PROFILE,
GLFW_OPENGL_FORWARD_COMPAT, GLFW_OPENGL_PROFILE, GLFW_SAMPLES,
GLFW_STENCIL_BITS, Window, change_wcwidth, check_for_extensions,
GLFW_STENCIL_BITS, GLFWWindow, change_wcwidth, check_for_extensions,
clear_buffers, glewInit, glfw_init, glfw_init_hint_string,
glfw_set_error_callback, glfw_swap_interval, glfw_terminate,
glfw_window_hint, set_options
@ -169,12 +169,12 @@ def run_app(opts, args):
viewport_size.width = opts.initial_window_width
viewport_size.height = opts.initial_window_height
try:
window = Window(viewport_size.width, viewport_size.height, args.cls)
window = GLFWWindow(viewport_size.width, viewport_size.height, args.cls)
except ValueError:
safe_print('Failed to create GLFW window with initial size:', viewport_size)
viewport_size.width = 640
viewport_size.height = 400
window = Window(viewport_size.width, viewport_size.height, args.cls)
window = GLFWWindow(viewport_size.width, viewport_size.height, args.cls)
window.set_title(appname)
window.make_context_current()
if isosx:

View File

@ -182,6 +182,7 @@ static PyMethodDef module_methods[] = {
bool
init_state(PyObject *module) {
global_state.application_focused = true;
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
return true;
}

View File

@ -35,6 +35,7 @@ typedef struct {
Tab tabs[MAX_CHILDREN];
unsigned int active_tab, num_tabs;
ScreenRenderData tab_bar_render_data;
bool application_focused;
} GlobalState;
typedef void (*draw_borders_func)();