Move visual bell tracking into the Screen object
This commit is contained in:
parent
ca5eb4feb5
commit
ccf5391b45
@ -369,7 +369,7 @@ class Boss:
|
||||
self.tab_manager.render()
|
||||
for window in tab.visible_windows():
|
||||
if not window.needs_layout:
|
||||
window.render_cells()
|
||||
window.char_grid.render_cells()
|
||||
active = self.active_window
|
||||
if active is not None:
|
||||
draw_cursor = True
|
||||
|
||||
@ -42,8 +42,8 @@ def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell
|
||||
return ScreenGeometry(xstart, ystart, window_geometry.xnum, window_geometry.ynum, dx, dy)
|
||||
|
||||
|
||||
def render_cells(vao_id, sg, screen, invert_colors=False):
|
||||
draw_cells(vao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, invert_colors, screen)
|
||||
def render_cells(vao_id, sg, screen):
|
||||
draw_cells(vao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, screen)
|
||||
|
||||
|
||||
class CharGrid:
|
||||
@ -172,10 +172,8 @@ class CharGrid:
|
||||
def text_for_selection(self):
|
||||
return ''.join(self.screen.text_for_selection())
|
||||
|
||||
def render_cells(self, invert_colors=False):
|
||||
render_cells(
|
||||
self.vao_id, self.screen_geometry,
|
||||
self.screen, invert_colors=invert_colors)
|
||||
def render_cells(self):
|
||||
render_cells(self.vao_id, self.screen_geometry, self.screen)
|
||||
|
||||
def render_cursor(self, is_focused):
|
||||
if not self.screen.cursor_visible or self.screen.scrolled_by:
|
||||
|
||||
@ -247,6 +247,7 @@ typedef struct {
|
||||
bool *tabstops, *main_tabstops, *alt_tabstops;
|
||||
ScreenModes modes;
|
||||
ColorProfile *color_profile;
|
||||
double start_visual_bell_at;
|
||||
|
||||
uint32_t parser_buf[PARSER_BUF_SZ];
|
||||
unsigned int parser_state, parser_text_start, parser_buf_pos;
|
||||
@ -286,6 +287,19 @@ typedef struct {
|
||||
} ChildMonitor;
|
||||
PyTypeObject ChildMonitor_Type;
|
||||
|
||||
typedef struct {
|
||||
double visual_bell_duration;
|
||||
bool enable_audio_bell;
|
||||
} Options;
|
||||
|
||||
typedef struct {
|
||||
Options opts;
|
||||
} GlobalState;
|
||||
|
||||
#ifndef IS_STATE
|
||||
extern GlobalState global_state;
|
||||
#endif
|
||||
|
||||
#define clear_sprite_position(cell) (cell).sprite_x = 0; (cell).sprite_y = 0; (cell).sprite_z = 0;
|
||||
|
||||
#define left_shift_line(line, at, num) \
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
#include "screen.h"
|
||||
#include <structmember.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "unicode-data.h"
|
||||
#include "modes.h"
|
||||
#include "wcwidth9.h"
|
||||
@ -911,8 +914,34 @@ screen_use_latin1(Screen *self, bool on) {
|
||||
CALLBACK("use_utf8", "O", on ? Py_False : Py_True);
|
||||
}
|
||||
|
||||
bool
|
||||
screen_invert_colors(Screen *self) {
|
||||
bool inverted = false;
|
||||
if (self->start_visual_bell_at > 0) {
|
||||
if (monotonic() - self->start_visual_bell_at <= global_state.opts.visual_bell_duration) inverted = true;
|
||||
else self->start_visual_bell_at = 0;
|
||||
}
|
||||
if (self->modes.mDECSCNM) inverted = inverted ? false : true;
|
||||
return inverted;
|
||||
}
|
||||
|
||||
void
|
||||
screen_bell(Screen UNUSED *self) {
|
||||
if (global_state.opts.enable_audio_bell) {
|
||||
int fd = open("/dev/tty", O_WRONLY | O_CLOEXEC | O_NOCTTY);
|
||||
if (fd > 0) {
|
||||
static const char bell[2] = {7, 0};
|
||||
while(true) {
|
||||
if (write(fd, &bell, sizeof(bell)) == sizeof(bell)) break;
|
||||
if (errno == EINTR) continue;
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
if (global_state.opts.visual_bell_duration > 0) {
|
||||
self->start_visual_bell_at = monotonic();
|
||||
}
|
||||
CALLBACK("bell", NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -61,6 +61,7 @@ void report_device_status(Screen *self, unsigned int which, bool UNUSED);
|
||||
void report_mode_status(Screen *self, unsigned int which, bool);
|
||||
void screen_apply_selection(Screen *self, void *address, size_t size);
|
||||
bool screen_is_selection_dirty(Screen *self);
|
||||
bool screen_invert_colors(Screen *self);
|
||||
void screen_update_cell_data(Screen *self, void *address, size_t sz);
|
||||
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
|
||||
DECLARE_CH_SCREEN_HANDLER(bell)
|
||||
|
||||
@ -596,10 +596,10 @@ create_cell_vao() {
|
||||
}
|
||||
|
||||
static void
|
||||
draw_cells(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, bool inverted, Screen *screen) {
|
||||
draw_cells(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen) {
|
||||
size_t sz;
|
||||
void *address;
|
||||
if (screen->modes.mDECSCNM) inverted = inverted ? false : true;
|
||||
bool inverted = screen_invert_colors(screen);
|
||||
if (screen->scroll_changed || screen->is_dirty) {
|
||||
sz = sizeof(Cell) * screen->lines * screen->columns;
|
||||
address = map_vao_buffer(vao_idx, sz, 0, GL_STREAM_DRAW, GL_WRITE_ONLY);
|
||||
@ -839,11 +839,11 @@ NO_ARG(init_cell_program)
|
||||
NO_ARG_INT(create_cell_vao)
|
||||
PYWRAP1(draw_cells) {
|
||||
float xstart, ystart, dx, dy;
|
||||
int vao_idx, inverted;
|
||||
int vao_idx;
|
||||
Screen *screen;
|
||||
|
||||
PA("iffffpO", &vao_idx, &xstart, &ystart, &dx, &dy, &inverted, &screen);
|
||||
draw_cells(vao_idx, xstart, ystart, dx, dy, inverted & 1, screen);
|
||||
PA("iffffO", &vao_idx, &xstart, &ystart, &dx, &dy, &screen);
|
||||
draw_cells(vao_idx, xstart, ystart, dx, dy, screen);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
NO_ARG(destroy_sprite_map)
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#define IS_STATE
|
||||
#include "data-types.h"
|
||||
|
||||
#define PYWRAP0(name) static PyObject* py##name(PyObject UNUSED *self)
|
||||
@ -12,21 +13,14 @@
|
||||
#define PYWRAP2(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args, PyObject *kw)
|
||||
#define PA(fmt, ...) if(!PyArg_ParseTuple(args, fmt, __VA_ARGS__)) return NULL;
|
||||
|
||||
typedef struct {
|
||||
double visual_bell_duration;
|
||||
} Options;
|
||||
|
||||
typedef struct {
|
||||
Options opts;
|
||||
} GlobalState;
|
||||
|
||||
static GlobalState global_state = {{0}};
|
||||
GlobalState global_state = {{0}};
|
||||
|
||||
|
||||
// Python API {{{
|
||||
PYWRAP1(set_options) {
|
||||
#define S(name, convert) { PyObject *ret = PyObject_GetAttrString(args, #name); if (ret == NULL) return NULL; global_state.opts.name = convert(ret); Py_DECREF(ret); }
|
||||
S(visual_bell_duration, PyFloat_AsDouble);
|
||||
S(enable_audio_bell, PyObject_IsTrue);
|
||||
#undef S
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@ -117,14 +117,6 @@ class Window:
|
||||
print('Failed to write to child %d as it does not exist' % self.id, file=sys.stderr)
|
||||
|
||||
def bell(self):
|
||||
if self.opts.enable_audio_bell:
|
||||
try:
|
||||
with open('/dev/tty', 'wb') as f:
|
||||
f.write(b'\007')
|
||||
except EnvironmentError:
|
||||
pass # failure to beep is not critical
|
||||
if self.opts.visual_bell_duration > 0:
|
||||
self.start_visual_bell_at = monotonic()
|
||||
get_boss().request_attention()
|
||||
glfw_post_empty_event()
|
||||
|
||||
@ -281,14 +273,6 @@ class Window:
|
||||
def buf_toggled(self, is_main_linebuf):
|
||||
self.screen.scroll(SCROLL_FULL, False)
|
||||
|
||||
def render_cells(self):
|
||||
invert_colors = False
|
||||
if self.start_visual_bell_at is not None:
|
||||
invert_colors = monotonic() - self.start_visual_bell_at <= self.opts.visual_bell_duration
|
||||
if not invert_colors:
|
||||
self.start_visual_bell_at = None
|
||||
self.char_grid.render_cells(invert_colors)
|
||||
|
||||
# actions {{{
|
||||
|
||||
def show_scrollback(self):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user