Show the window much sooner after creating it
Do not make any OpenGL calls between creation and showing of the window. Hopefully, that will make the fussy wlroots happy.
This commit is contained in:
parent
1ba76508de
commit
3b04776956
@ -12,7 +12,8 @@ from weakref import WeakValueDictionary
|
||||
|
||||
from .cli import create_opts, parse_args
|
||||
from .config import (
|
||||
MINIMUM_FONT_SIZE, initial_window_size_func, prepare_config_file_for_editing
|
||||
MINIMUM_FONT_SIZE, initial_window_size_func,
|
||||
prepare_config_file_for_editing
|
||||
)
|
||||
from .config_utils import to_cmdline
|
||||
from .constants import (
|
||||
@ -23,7 +24,7 @@ from .fast_data_types import (
|
||||
create_os_window, current_os_window, destroy_global_data,
|
||||
get_clipboard_string, glfw_post_empty_event, global_font_size,
|
||||
mark_os_window_for_close, os_window_font_size, set_clipboard_string,
|
||||
set_in_sequence_mode, show_window, toggle_fullscreen
|
||||
set_in_sequence_mode, toggle_fullscreen
|
||||
)
|
||||
from .keys import get_shortcut, shortcut_matches
|
||||
from .remote_control import handle_cmd
|
||||
@ -31,9 +32,9 @@ from .rgb import Color, color_from_int
|
||||
from .session import create_session
|
||||
from .tabs import SpecialWindow, SpecialWindowInstance, TabManager
|
||||
from .utils import (
|
||||
end_startup_notification, get_primary_selection, init_startup_notification,
|
||||
log_error, open_url, parse_address_spec, remove_socket_file, safe_print,
|
||||
set_primary_selection, single_instance
|
||||
get_primary_selection, log_error, open_url, parse_address_spec,
|
||||
remove_socket_file, safe_print, set_primary_selection, single_instance,
|
||||
startup_notification_handler
|
||||
)
|
||||
|
||||
|
||||
@ -103,12 +104,11 @@ class Boss:
|
||||
if os_window_id is None:
|
||||
opts_for_size = opts_for_size or self.opts
|
||||
cls = wclass or self.args.cls or appname
|
||||
os_window_id = create_os_window(initial_window_size_func(opts_for_size, self.cached_values), appname, wname or self.args.name or cls, cls)
|
||||
if startup_id:
|
||||
ctx = init_startup_notification(os_window_id, startup_id)
|
||||
show_window(os_window_id)
|
||||
if startup_id:
|
||||
end_startup_notification(ctx)
|
||||
with startup_notification_handler(do_notify=startup_id is not None, startup_id=startup_id) as pre_show_callback:
|
||||
os_window_id = create_os_window(
|
||||
initial_window_size_func(opts_for_size, self.cached_values),
|
||||
pre_show_callback,
|
||||
appname, wname or self.args.name or cls, cls)
|
||||
tm = TabManager(os_window_id, self.opts, self.args, startup_session)
|
||||
self.os_window_map[os_window_id] = tm
|
||||
return os_window_id
|
||||
|
||||
40
kitty/glfw.c
40
kitty/glfw.c
@ -342,12 +342,22 @@ set_titlebar_color(OSWindow *w, color_type color) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline PyObject*
|
||||
native_window_handle(GLFWwindow *w) {
|
||||
#ifdef __APPLE__
|
||||
void *ans = glfwGetCocoaWindow(w);
|
||||
return PyLong_FromVoidPtr(ans);
|
||||
#endif
|
||||
if (glfwGetX11Window) return PyLong_FromLong((long)glfwGetX11Window(w));
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
int x = -1, y = -1;
|
||||
char *title, *wm_class_class, *wm_class_name;
|
||||
PyObject *load_programs = NULL, *get_window_size;
|
||||
if (!PyArg_ParseTuple(args, "Osss|Oii", &get_window_size, &title, &wm_class_name, &wm_class_class, &load_programs, &x, &y)) return NULL;
|
||||
PyObject *load_programs = NULL, *get_window_size, *pre_show_callback;
|
||||
if (!PyArg_ParseTuple(args, "OOsss|Oii", &get_window_size, &pre_show_callback, &title, &wm_class_name, &wm_class_class, &load_programs, &x, &y)) return NULL;
|
||||
|
||||
static bool is_first_window = true;
|
||||
if (is_first_window) {
|
||||
@ -391,8 +401,12 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, temp_window);
|
||||
glfwDestroyWindow(temp_window); temp_window = NULL;
|
||||
if (glfw_window == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to create GLFWwindow"); return NULL; }
|
||||
PyObject *pret = PyObject_CallFunction(pre_show_callback, "N", native_window_handle(glfw_window));
|
||||
if (pret == NULL) return NULL;
|
||||
Py_DECREF(pret);
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
if (x != -1 && y != -1) glfwSetWindowPos(glfw_window, x, y);
|
||||
glfwShowWindow(glfw_window);
|
||||
if (is_first_window) {
|
||||
gl_init();
|
||||
PyObject *ret = PyObject_CallFunction(load_programs, "i", glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER));
|
||||
@ -421,6 +435,8 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
w->logical_dpi_x = dpi_x; w->logical_dpi_y = dpi_y;
|
||||
w->fonts_data = fonts_data;
|
||||
current_os_window_ctx = glfw_window;
|
||||
w->shown_once = true;
|
||||
push_focus_history(w);
|
||||
glfwSwapInterval(OPT(sync_to_monitor) ? 1 : 0);
|
||||
#ifdef __APPLE__
|
||||
if (OPT(macos_option_as_alt)) glfwSetCocoaTextInputFilter(glfw_window, filter_option);
|
||||
@ -459,25 +475,6 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
return PyLong_FromUnsignedLongLong(w->id);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
show_window(PyObject UNUSED *self, PyObject *args) {
|
||||
id_type os_window_id;
|
||||
int yes = 1;
|
||||
if (!PyArg_ParseTuple(args, "K|p", &os_window_id, &yes)) return NULL;
|
||||
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
||||
OSWindow *w = global_state.os_windows + i;
|
||||
if (w->id == os_window_id) {
|
||||
if (yes) {
|
||||
glfwShowWindow(w->handle);
|
||||
w->shown_once = true;
|
||||
push_focus_history(w);
|
||||
} else glfwHideWindow(w->handle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_os_window(OSWindow *w) {
|
||||
if (w->handle) {
|
||||
@ -804,7 +801,6 @@ static PyMethodDef module_methods[] = {
|
||||
METHODB(get_content_scale_for_window, METH_NOARGS),
|
||||
METHODB(set_clipboard_string, METH_VARARGS),
|
||||
METHODB(toggle_fullscreen, METH_NOARGS),
|
||||
METHODB(show_window, METH_VARARGS),
|
||||
METHODB(glfw_window_hint, METH_VARARGS),
|
||||
METHODB(os_window_should_close, METH_VARARGS),
|
||||
METHODB(os_window_swap_buffers, METH_VARARGS),
|
||||
|
||||
@ -16,13 +16,12 @@ from .constants import (
|
||||
)
|
||||
from .fast_data_types import (
|
||||
create_os_window, glfw_init, glfw_terminate, set_default_window_icon,
|
||||
set_options, show_window
|
||||
set_options
|
||||
)
|
||||
from .fonts.box_drawing import set_scale
|
||||
from .fonts.render import set_font_family
|
||||
from .utils import (
|
||||
detach, end_startup_notification, init_startup_notification, log_error,
|
||||
single_instance
|
||||
detach, log_error, single_instance, startup_notification_handler
|
||||
)
|
||||
from .window import load_shader_programs
|
||||
|
||||
@ -44,19 +43,17 @@ def run_app(opts, args):
|
||||
set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback)
|
||||
set_font_family(opts)
|
||||
with cached_values_for(run_app.cached_values_name) as cached_values:
|
||||
window_id = create_os_window(
|
||||
run_app.initial_window_size_func(opts, cached_values),
|
||||
appname, args.name or args.cls or appname,
|
||||
args.cls or appname, load_all_shaders)
|
||||
run_app.first_window_callback(opts, window_id)
|
||||
startup_ctx = init_startup_notification(window_id)
|
||||
show_window(window_id)
|
||||
with startup_notification_handler(extra_callback=run_app.first_window_callback) as pre_show_callback:
|
||||
window_id = create_os_window(
|
||||
run_app.initial_window_size_func(opts, cached_values),
|
||||
pre_show_callback,
|
||||
appname, args.name or args.cls or appname,
|
||||
args.cls or appname, load_all_shaders)
|
||||
if not is_wayland and not is_macos: # no window icons on wayland
|
||||
with open(logo_data_file, 'rb') as f:
|
||||
set_default_window_icon(f.read(), 256, 256)
|
||||
boss = Boss(window_id, opts, args, cached_values)
|
||||
boss.start()
|
||||
end_startup_notification(startup_ctx)
|
||||
try:
|
||||
boss.child_monitor.main_loop()
|
||||
finally:
|
||||
@ -64,7 +61,7 @@ def run_app(opts, args):
|
||||
|
||||
|
||||
run_app.cached_values_name = 'main'
|
||||
run_app.first_window_callback = lambda opts, window_id: None
|
||||
run_app.first_window_callback = lambda window_handle: None
|
||||
run_app.initial_window_size_func = initial_window_size_func
|
||||
|
||||
|
||||
|
||||
@ -17,8 +17,7 @@ from .constants import (
|
||||
appname, is_macos, is_wayland, supports_primary_selection
|
||||
)
|
||||
from .fast_data_types import (
|
||||
GLSL_VERSION, log_error_string, redirect_std_streams, x11_display,
|
||||
x11_window_id
|
||||
GLSL_VERSION, log_error_string, redirect_std_streams, x11_display
|
||||
)
|
||||
from .rgb import Color, to_color
|
||||
|
||||
@ -190,7 +189,7 @@ def adjust_line_height(cell_height, val):
|
||||
return int(cell_height * val)
|
||||
|
||||
|
||||
def init_startup_notification_x11(window_id, startup_id=None):
|
||||
def init_startup_notification_x11(window_handle, startup_id=None):
|
||||
# https://specifications.freedesktop.org/startup-notification-spec/startup-notification-latest.txt
|
||||
from kitty.fast_data_types import init_x11_startup_notification
|
||||
sid = startup_id or os.environ.pop('DESKTOP_STARTUP_ID', None) # ensure child processes dont get this env var
|
||||
@ -199,8 +198,7 @@ def init_startup_notification_x11(window_id, startup_id=None):
|
||||
display = x11_display()
|
||||
if not display:
|
||||
return
|
||||
window_id = x11_window_id(window_id)
|
||||
return init_x11_startup_notification(display, window_id, sid)
|
||||
return init_x11_startup_notification(display, window_handle, sid)
|
||||
|
||||
|
||||
def end_startup_notification_x11(ctx):
|
||||
@ -208,11 +206,14 @@ def end_startup_notification_x11(ctx):
|
||||
end_x11_startup_notification(ctx)
|
||||
|
||||
|
||||
def init_startup_notification(window, startup_id=None):
|
||||
def init_startup_notification(window_handle, startup_id=None):
|
||||
if is_macos or is_wayland:
|
||||
return
|
||||
if window_handle is None:
|
||||
log_error('Could not perform startup notification as window handle not present')
|
||||
return
|
||||
try:
|
||||
return init_startup_notification_x11(window, startup_id)
|
||||
return init_startup_notification_x11(window_handle, startup_id)
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
@ -230,6 +231,29 @@ def end_startup_notification(ctx):
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
class startup_notification_handler:
|
||||
|
||||
def __init__(self, do_notify=True, startup_id=None, extra_callback=None):
|
||||
self.do_notify = do_notify
|
||||
self.startup_id = startup_id
|
||||
self.extra_callback = extra_callback
|
||||
self.ctx = None
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
def pre_show_callback(window_handle):
|
||||
if self.extra_callback is not None:
|
||||
self.extra_callback(window_handle)
|
||||
if self.do_notify:
|
||||
self.ctx = init_startup_notification(window_handle, self.startup_id)
|
||||
|
||||
return pre_show_callback
|
||||
|
||||
def __exit__(self, *a):
|
||||
if self.ctx is not None:
|
||||
end_startup_notification(self.ctx)
|
||||
|
||||
|
||||
def remove_socket_file(s, path=None):
|
||||
try:
|
||||
s.close()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user