Remove the compositor timer signal

This commit is contained in:
Kevin Lange 2017-01-26 15:58:50 +09:00
parent 132b649fe6
commit 2ebde54671
6 changed files with 195 additions and 205 deletions

View File

@ -487,18 +487,6 @@ static void server_window_resize_finish(yutani_globals_t * yg, yutani_server_win
mark_window(yg, win);
}
void * timer_tick(void * _server) {
(void)_server;
//yutani_globals_t * yg = _server;
yutani_t * y = yutani_init();
yutani_msg_t * m = yutani_msg_build_timer_tick();
while (1) {
usleep(20000); /* XXX timer precision */
yutani_msg_send(y, m);
}
}
#define FONT_PATH "/usr/share/fonts/"
#define FONT(a,b) {a, FONT_PATH b}
@ -2082,17 +2070,14 @@ int main(int argc, char * argv[]) {
yg->mid_zs = list_create();
yg->window_subscribers = list_create();
yg->timer_subscribers = list_create();
yg->last_mouse_buttons = 0;
yutani_cairo_init(yg);
pthread_t render_thread;
pthread_t timer_thread;
pthread_create(&render_thread, NULL, redraw, yg);
pthread_create(&timer_thread, NULL, timer_tick, yg);
if (!fork()) {
if (argx < argc) {
@ -2523,56 +2508,6 @@ int main(int argc, char * argv[]) {
}
}
break;
case YUTANI_MSG_TIMER_REQUEST:
{
struct yutani_msg_timer_request * tr = (void *)m->data;
/* TODO: precision */
if (tr->flags & 1) {
/* Unsubscribe */
node_t * node = list_find(yg->timer_subscribers, (void*)p->source);
if (node) {
list_delete(yg->timer_subscribers, node);
}
} else {
/* Subscribe */
foreach(node, yg->timer_subscribers) {
if ((uint32_t)node->value == p->source) {
break;
}
}
list_insert(yg->timer_subscribers, (void*)p->source);
}
}
break;
case YUTANI_MSG_TIMER_TICK:
{
/* Send timer ticks to requesters */
yutani_msg_t * response = yutani_msg_build_timer_tick();
list_t * remove = NULL;
foreach(node, yg->timer_subscribers) {
uint32_t subscriber = (uint32_t)node->value;
if (!hashmap_has(yg->clients_to_windows, (void *)subscriber)) {
if (!remove) {
remove = list_create();
}
list_insert(remove, node);
} else {
pex_send(yg->server, subscriber, response->size, (char *)response);
}
}
if (remove) {
while (remove->length) {
node_t * n = list_pop(remove);
list_delete(yg->timer_subscribers, n->value);
free(n);
}
free(remove);
}
free(response);
}
break;
default:
{
TRACE("Unknown type: 0x%8x", m->type);

View File

@ -162,11 +162,9 @@ int main (int argc, char ** argv) {
time_t last_tick = 0;
yutani_timer_request(yctx, 0, 0);
while (!exit_app) {
int index = syscall_fswait(2,fds);
int index = syscall_fswait2(2,fds,1000);
if (index == 1) {
pex_packet_t * p = calloc(PACKET_SIZE, 1);
@ -190,35 +188,32 @@ int main (int argc, char ** argv) {
case YUTANI_MSG_SESSION_END:
exit_app = 1;
break;
case YUTANI_MSG_TIMER_TICK:
{
time_t now = time(NULL);
if (now == last_tick) break;
last_tick = now;
list_t * tmp = list_create();
foreach(node, notifications) {
notification_int_t * toast = node->value;
if (toast->window && toast->ttl <= now) {
yutani_close(yctx, toast->window);
free(toast->title);
free(toast->content);
list_insert(tmp, node);
}
}
foreach(node, tmp) {
list_delete(notifications, node->value);
}
list_free(tmp);
free(tmp);
}
break;
}
free(m);
}
} else if (index == 2) {
time_t now = time(NULL);
if (now == last_tick) continue;
last_tick = now;
list_t * tmp = list_create();
foreach(node, notifications) {
notification_int_t * toast = node->value;
if (toast->window && toast->ttl <= now) {
yutani_close(yctx, toast->window);
free(toast->title);
free(toast->content);
list_insert(tmp, node);
}
}
foreach(node, tmp) {
list_delete(notifications, node->value);
}
list_free(tmp);
free(tmp);
}
}

View File

@ -1349,16 +1349,6 @@ void * handle_incoming(void) {
}
}
break;
case YUTANI_MSG_TIMER_TICK:
{
uint64_t ticks = get_ticks();
if (ticks > mouse_ticks + 600000LL) {
mouse_ticks = ticks;
spin_lock(&display_lock);
flip_cursor();
spin_unlock(&display_lock);
}
}
default:
break;
}
@ -1545,14 +1535,12 @@ int main(int argc, char ** argv) {
child_pid = f;
yutani_timer_request(yctx, 0, 0);
int fds[2] = {fd_master, fileno(yctx->sock)};
unsigned char buf[1024];
while (!exit_application) {
int index = syscall_fswait(2,fds);
int index = syscall_fswait2(2,fds,200);
check_for_exit();
@ -1564,8 +1552,16 @@ int main(int argc, char ** argv) {
}
display_flip();
spin_unlock(&display_lock);
} else {
} else if (index == 1) {
handle_incoming();
} else if (index == 2) {
uint64_t ticks = get_ticks();
if (ticks > mouse_ticks + 600000LL) {
mouse_ticks = ticks;
spin_lock(&display_lock);
flip_cursor();
spin_unlock(&display_lock);
}
}
}

View File

@ -13,6 +13,8 @@ import text_region
import toaru_fonts
import fswait
from button import Button
import yutani_mainloop
def rounded_rectangle(ctx,x,y,w,h,r):
@ -45,10 +47,14 @@ def draw_input_box(ctx,x,y,w,h,focused):
class TextInputWindow(yutani.Window):
base_width = 350
base_height = 80
base_width = 500
base_height = 120
text_offset = 22
okay_label = "Okay"
cancel_label = "Cancel"
def __init__(self, decorator, title, icon, text="", text_changed=None, callback=None,window=None):
super(TextInputWindow, self).__init__(self.base_width + decorator.width(), self.base_height + decorator.height(), title=title, icon=icon, doublebuffer=True)
if window:
@ -63,8 +69,6 @@ class TextInputWindow(yutani.Window):
self.tr.set_one_line()
self.tr.break_all = True
self.tr.set_text(text)
self.progress = 0
self.total = 1
self.is_focused = False
self.cursor_index = len(self.tr.text)
self.cursor_x = self.tr.get_offset_at_index(self.cursor_index)[1][1]
@ -72,6 +76,23 @@ class TextInputWindow(yutani.Window):
self.callback = callback
self.ctrl_chars = [' ','/']
self.button_ok = Button(self.okay_label,self.ok_click)
self.button_cancel = Button(self.cancel_label,self.cancel_click)
self.buttons = [self.button_ok, self.button_cancel]
self.hover_widget = None
self.down_button = None
def cancel_click(self, button):
self.close()
if __name__ == '__main__':
sys.exit(0)
def ok_click(self, button):
if self.callback:
self.callback(self)
def draw(self):
surface = self.get_cairo_surface()
@ -85,7 +106,6 @@ class TextInputWindow(yutani.Window):
draw_input_box(ctx,10,20,WIDTH-20,20,self.is_focused)
percent = int(100 * self.progress / self.total)
self.tr.resize(WIDTH-30,HEIGHT-self.text_offset)
self.tr.move(self.decorator.left_width() + 15,self.decorator.top_height()+self.text_offset)
self.tr.draw(self)
@ -95,6 +115,9 @@ class TextInputWindow(yutani.Window):
ctx.set_source_rgb(0,0,0)
ctx.fill()
self.button_ok.draw(self,ctx,WIDTH-130,HEIGHT-60,100,30)
self.button_cancel.draw(self,ctx,WIDTH-240,HEIGHT-60,100,30)
self.decorator.render(self)
self.flip()
@ -110,19 +133,59 @@ class TextInputWindow(yutani.Window):
def mouse_event(self, msg):
if self.decorator.handle_event(msg) == yutani.Decor.EVENT_CLOSE:
self.close()
if __name__ == '__main__':
sys.exit(0)
self.cancel_click(None)
x,y = msg.new_x - self.decorator.left_width(), msg.new_y - self.decorator.top_height()
w,h = self.width - self.decorator.width(), self.height - self.decorator.height()
redraw = False
if self.down_button:
if msg.command == yutani.MouseEvent.RAISE or msg.command == yutani.MouseEvent.CLICK:
if not (msg.buttons & yutani.MouseButton.BUTTON_LEFT):
if x >= self.down_button.x and \
x < self.down_button.x + self.down_button.width and \
y >= self.down_button.y and \
y < self.down_button.y + self.down_button.height:
self.down_button.focus_enter()
if self.down_button.callback(self.down_button):
redraw = True
self.down_button = None
else:
self.down_button.focus_leave()
self.down_button = None
redraw = True
else:
button = None
for b in self.buttons:
if x >= b.x and x < b.x + b.width and y >= b.y and y < b.y + b.height:
button = b
break
if button != self.hover_widget:
if button:
button.focus_enter()
redraw = True
if self.hover_widget:
self.hover_widget.focus_leave()
redraw = True
self.hover_widget = button
if msg.command == yutani.MouseEvent.DOWN:
if button:
button.hilight = 2
self.down_button = button
redraw = True
if not button:
if self.hover_widget:
self.hover_widget.focus_leave()
redraw = True
self.hover_widget = None
if x >= 10 and x < 10 + w - 20 and y >= 20 and y < 20 + 20:
changed = not self.is_focused
self.is_focused = True
if msg.command == yutani.MouseEvent.CLICK:
u,l = self.tr.pick(msg.new_x,msg.new_y)
if u:
print(u,l)
changed = True
self.cursor_x = l[1]
self.cursor_index = l[3]
@ -130,7 +193,6 @@ class TextInputWindow(yutani.Window):
self.cursor_x += u.width
self.cursor_index += 1
elif l:
print(l)
changed = True
self.cursor_x = l[1]
self.cursor_index = l[3]
@ -138,7 +200,7 @@ class TextInputWindow(yutani.Window):
changed = self.is_focused
self.is_focused = False
if changed:
if changed or redraw:
self.draw()
def keyboard_event(self, msg):
@ -229,8 +291,7 @@ class TextInputWindow(yutani.Window):
self.text_changed(self)
self.draw()
elif msg.event.key == b'\n':
if self.callback:
self.callback(self)
self.ok_click()
elif msg.event.key != b'\x00':
text = self.tr.text
before = text[:self.cursor_index]
@ -249,7 +310,11 @@ if __name__ == '__main__':
title = "Input Box" if len(sys.argv) < 2 else sys.argv[1]
icon = "default" if len(sys.argv) < 3 else sys.argv[2]
window = TextInputWindow(d,title,icon)
def print_text(text_box):
print(text_box.tr.text)
sys.exit(0)
window = TextInputWindow(d,title,icon,callback=print_text)
window.draw()
yutani_mainloop.mainloop()

View File

@ -22,6 +22,7 @@ import cairo
import yutani
import text_region
import toaru_fonts
import fswait
from menu_bar import MenuEntryAction, MenuEntrySubmenu, MenuEntryDivider, MenuWindow
from icon_cache import get_icon
@ -1199,7 +1200,6 @@ if __name__ == '__main__':
alttab = None
new_focused = -1
yctx.timer_request(0,0)
yctx.subscribe()
set_binds()
@ -1228,21 +1228,11 @@ if __name__ == '__main__':
signal.signal(signal.SIGUSR2, reset_zorder)
fds = [yutani.yutani_ctx]
while 1:
# Poll for events.
msg = yutani.yutani_ctx.poll()
if msg.type == yutani.Message.MSG_SESSION_END:
# All applications should attempt to exit on SESSION_END.
panel.close()
wallpaper.close()
msg.free()
break
elif msg.type == yutani.Message.MSG_NOTIFY:
# Update the window list.
windows_zorder = [x for x in update_window_list()]
windows = sorted(windows_zorder, key=lambda window: window.wid)
panel.draw()
elif msg.type == yutani.Message.MSG_TIMER_TICK:
fd = fswait.fswait(fds,500 if not wallpaper.animations else 20)
if fd == 1:
tick = int(time.time())
if tick != current_time:
try:
@ -1253,68 +1243,81 @@ if __name__ == '__main__':
panel.draw()
if wallpaper.animations:
wallpaper.animate()
elif msg.type == yutani.Message.MSG_KEY_EVENT:
if app_runner and msg.wid == app_runner.wid:
app_runner.key_action(msg)
elif fd == 0:
msg = yutani.yutani_ctx.poll()
if msg.type == yutani.Message.MSG_SESSION_END:
# All applications should attempt to exit on SESSION_END.
panel.close()
wallpaper.close()
msg.free()
continue
if not app_runner and \
(msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == yutani.Keycode.F2) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
app_runner = ApplicationRunnerWindow()
app_runner.draw()
if not panel.menus and \
(msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == yutani.Keycode.F1) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
appmenu.activate()
# Ctrl-Alt-T: Open Terminal
if (msg.event.modifiers & yutani.Modifier.MOD_LEFT_CTRL) and \
(msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == ord('t')) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
launch_app('terminal')
# Ctrl-F11: Toggle visibility of panel
if (msg.event.modifiers & yutani.Modifier.MOD_LEFT_CTRL) and \
(msg.event.keycode == yutani.Keycode.F11) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
panel.toggle_visibility()
# Release alt while alt-tabbing
if tabbing and (msg.event.keycode == 0 or msg.event.keycode == yutani.Keycode.LEFT_ALT) and \
(msg.event.modifiers == 0) and (msg.event.action == yutani.KeyAction.ACTION_UP):
finish_alt_tab(msg)
# Alt-Tab and Alt-Shift-Tab: Switch window focus.
if (msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == ord("\t")) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
alt_tab(msg)
if msg.wid in panel.menus:
panel.menus[msg.wid].keyboard_event(msg)
elif msg.type == yutani.Message.MSG_WELCOME:
# Display size has changed.
panel.resize(msg.display_width, PANEL_HEIGHT)
wallpaper.resize(msg.display_width, msg.display_height)
elif msg.type == yutani.Message.MSG_RESIZE_OFFER:
# Resize the window.
if msg.wid == panel.wid:
panel.finish_resize(msg)
elif msg.wid == wallpaper.wid:
wallpaper.finish_resize(msg)
elif msg.type == yutani.Message.MSG_WINDOW_MOUSE_EVENT:
if msg.wid == panel.wid:
panel.mouse_action(msg)
elif msg.wid == wallpaper.wid:
wallpaper.mouse_action(msg)
if msg.wid in panel.menus:
m = panel.menus[msg.wid]
if msg.new_x >= 0 and msg.new_x < m.width and msg.new_y >= 0 and msg.new_y < m.height:
panel.hovered_menu = m
elif panel.hovered_menu == m:
panel.hovered_menu = None
m.mouse_action(msg)
elif msg.type == yutani.Message.MSG_WINDOW_FOCUS_CHANGE:
if msg.wid in panel.menus and msg.focused == 0:
panel.menus[msg.wid].leave_menu()
msg.free()
break
elif msg.type == yutani.Message.MSG_NOTIFY:
# Update the window list.
windows_zorder = [x for x in update_window_list()]
windows = sorted(windows_zorder, key=lambda window: window.wid)
panel.draw()
elif msg.type == yutani.Message.MSG_KEY_EVENT:
if app_runner and msg.wid == app_runner.wid:
app_runner.key_action(msg)
msg.free()
continue
if not app_runner and \
(msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == yutani.Keycode.F2) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
app_runner = ApplicationRunnerWindow()
app_runner.draw()
if not panel.menus and \
(msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == yutani.Keycode.F1) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
appmenu.activate()
# Ctrl-Alt-T: Open Terminal
if (msg.event.modifiers & yutani.Modifier.MOD_LEFT_CTRL) and \
(msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == ord('t')) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
launch_app('terminal')
# Ctrl-F11: Toggle visibility of panel
if (msg.event.modifiers & yutani.Modifier.MOD_LEFT_CTRL) and \
(msg.event.keycode == yutani.Keycode.F11) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
panel.toggle_visibility()
# Release alt while alt-tabbing
if tabbing and (msg.event.keycode == 0 or msg.event.keycode == yutani.Keycode.LEFT_ALT) and \
(msg.event.modifiers == 0) and (msg.event.action == yutani.KeyAction.ACTION_UP):
finish_alt_tab(msg)
# Alt-Tab and Alt-Shift-Tab: Switch window focus.
if (msg.event.modifiers & yutani.Modifier.MOD_LEFT_ALT) and \
(msg.event.keycode == ord("\t")) and \
(msg.event.action == yutani.KeyAction.ACTION_DOWN):
alt_tab(msg)
if msg.wid in panel.menus:
panel.menus[msg.wid].keyboard_event(msg)
elif msg.type == yutani.Message.MSG_WELCOME:
# Display size has changed.
panel.resize(msg.display_width, PANEL_HEIGHT)
wallpaper.resize(msg.display_width, msg.display_height)
elif msg.type == yutani.Message.MSG_RESIZE_OFFER:
# Resize the window.
if msg.wid == panel.wid:
panel.finish_resize(msg)
elif msg.wid == wallpaper.wid:
wallpaper.finish_resize(msg)
elif msg.type == yutani.Message.MSG_WINDOW_MOUSE_EVENT:
if msg.wid == panel.wid:
panel.mouse_action(msg)
elif msg.wid == wallpaper.wid:
wallpaper.mouse_action(msg)
if msg.wid in panel.menus:
m = panel.menus[msg.wid]
if msg.new_x >= 0 and msg.new_x < m.width and msg.new_y >= 0 and msg.new_y < m.height:
panel.hovered_menu = m
elif panel.hovered_menu == m:
panel.hovered_menu = None
m.mouse_action(msg)
elif msg.type == yutani.Message.MSG_WINDOW_FOCUS_CHANGE:
if msg.wid in panel.menus and msg.focused == 0:
panel.menus[msg.wid].leave_menu()
msg.free()

View File

@ -64,8 +64,8 @@ class Message(object):
MSG_KEY_BIND = 0x00000040
MSG_WINDOW_UPDATE_SHAPE = 0x00000050
MSG_GOODBYE = 0x000000F0
MSG_TIMER_REQUEST = 0x00000100
MSG_TIMER_TICK = 0x00000101
MSG_TIMER_REQUEST = 0x00000100 # XXX deprecated
MSG_TIMER_TICK = 0x00000101 # xxx deprecated
MSG_WELCOME = 0x00010001
MSG_WINDOW_INIT = 0x00010002
@ -366,10 +366,6 @@ class Yutani(object):
"""Request a window subsription list."""
yutani_lib.yutani_query_windows(self._ptr)
def timer_request(self, precision=0, flags=0):
"""Request timer tick messages."""
yutani_lib.yutani_timer_request(self._ptr, precision, flags)
def focus_window(self, wid):
"""Request that the server change the focused window to the window with the specified wid."""
yutani_lib.yutani_focus_window(self._ptr, wid)