Wayland: Use XDG_ACTIVATION_TOKEN when present at launch
This commit is contained in:
parent
b247759d30
commit
58a3baaf0f
@ -245,6 +245,7 @@ def generate_wrappers(glfw_header: str) -> None:
|
||||
const char* glfwGetPrimarySelectionString(GLFWwindow* window, void)
|
||||
int glfwGetNativeKeyForName(const char* key_name, int case_sensitive)
|
||||
void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback)
|
||||
void glfwWaylandActivateWindow(GLFWwindow *handle, const char *activation_token)
|
||||
bool glfwWaylandSetTitlebarColor(GLFWwindow *handle, uint32_t color, bool use_system_color)
|
||||
unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, \
|
||||
const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||
|
||||
6
glfw/wl_window.c
vendored
6
glfw/wl_window.c
vendored
@ -2217,6 +2217,12 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
|
||||
return window->wl.surface;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwWaylandActivateWindow(GLFWwindow* handle, const char *activation_token) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT();
|
||||
if (activation_token && activation_token[0]) xdg_activation_v1_activate(_glfw.wl.xdg_activation_v1, activation_token, window->wl.surface);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetNativeKeyForName(const char* keyName, bool caseSensitive) {
|
||||
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
|
||||
}
|
||||
|
||||
@ -296,7 +296,8 @@ class Boss:
|
||||
|
||||
def startup_first_child(self, os_window_id: Optional[int], startup_sessions: Iterable[Session] = ()) -> None:
|
||||
si = startup_sessions or create_sessions(get_options(), self.args, default_session=get_options().startup_session)
|
||||
focused_os_window = 0
|
||||
focused_os_window = wid = 0
|
||||
token = os.environ.pop('XDG_ACTIVATION_TOKEN', '')
|
||||
for startup_session in si:
|
||||
wid = self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||
if startup_session.focus_os_window:
|
||||
@ -308,7 +309,9 @@ class Boss:
|
||||
else:
|
||||
change_os_window_state(self.args.start_as)
|
||||
if focused_os_window > 0:
|
||||
focus_os_window(focused_os_window, True)
|
||||
focus_os_window(focused_os_window, True, token)
|
||||
elif token and is_wayland() and wid:
|
||||
focus_os_window(wid, True, token)
|
||||
|
||||
def add_os_window(
|
||||
self,
|
||||
@ -630,6 +633,7 @@ class Boss:
|
||||
if isinstance(data, dict) and data.get('cmd') == 'new_instance':
|
||||
from .cli_stub import CLIOptions
|
||||
startup_id = data.get('startup_id')
|
||||
activation_token = data.get('activation_token', '')
|
||||
args, rest = parse_args(data['args'][1:], result_class=CLIOptions)
|
||||
cmdline_args_for_open = data.get('cmdline_args_for_open')
|
||||
if cmdline_args_for_open:
|
||||
@ -642,7 +646,7 @@ class Boss:
|
||||
args.session = PreReadSession(data['stdin'])
|
||||
if not os.path.isabs(args.directory):
|
||||
args.directory = os.path.join(data['cwd'], args.directory)
|
||||
focused_os_window = 0
|
||||
focused_os_window = os_window_id = 0
|
||||
for session in create_sessions(opts, args, respect_cwd=True):
|
||||
os_window_id = self.add_os_window(
|
||||
session, wclass=args.cls, wname=args.name, opts_for_size=opts, startup_id=startup_id,
|
||||
@ -654,7 +658,9 @@ class Boss:
|
||||
if data.get('notify_on_os_window_death'):
|
||||
self.os_window_death_actions[os_window_id] = partial(self.notify_on_os_window_death, data['notify_on_os_window_death'])
|
||||
if focused_os_window > 0:
|
||||
focus_os_window(focused_os_window, True)
|
||||
focus_os_window(focused_os_window, True, activation_token or '')
|
||||
elif activation_token and is_wayland() and os_window_id:
|
||||
focus_os_window(os_window_id, True, activation_token or '')
|
||||
else:
|
||||
log_error('Unknown message received from peer, ignoring')
|
||||
return None
|
||||
|
||||
@ -148,6 +148,7 @@ def process_env() -> Dict[str, str]:
|
||||
ssl_env_var = getattr(sys, 'kitty_ssl_env_var', None)
|
||||
if ssl_env_var is not None:
|
||||
ans.pop(ssl_env_var, None)
|
||||
ans.pop('XDG_ACTIVATION_TOKEN', None)
|
||||
return ans
|
||||
|
||||
|
||||
|
||||
@ -754,7 +754,7 @@ def global_font_size(val: float = -1.) -> float:
|
||||
pass
|
||||
|
||||
|
||||
def focus_os_window(os_window_id: int, also_raise: bool = True) -> bool:
|
||||
def focus_os_window(os_window_id: int, also_raise: bool = True, activation_token: Optional[str] = None) -> bool:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
3
kitty/glfw-wrapper.c
generated
3
kitty/glfw-wrapper.c
generated
@ -449,6 +449,9 @@ load_glfw(const char* path) {
|
||||
*(void **) (&glfwRequestWaylandFrameEvent_impl) = dlsym(handle, "glfwRequestWaylandFrameEvent");
|
||||
if (glfwRequestWaylandFrameEvent_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwWaylandActivateWindow_impl) = dlsym(handle, "glfwWaylandActivateWindow");
|
||||
if (glfwWaylandActivateWindow_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwWaylandSetTitlebarColor_impl) = dlsym(handle, "glfwWaylandSetTitlebarColor");
|
||||
if (glfwWaylandSetTitlebarColor_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
|
||||
5
kitty/glfw-wrapper.h
generated
5
kitty/glfw-wrapper.h
generated
@ -1454,6 +1454,7 @@ typedef void (* GLFWjoystickfun)(int,int);
|
||||
|
||||
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
||||
typedef void (* GLFWtickcallback)(void*);
|
||||
typedef void (* GLFWactivationcallback)(GLFWwindow *window, const char *token, void *data);
|
||||
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset, size_t right_margin);
|
||||
typedef char* (* GLFWcurrentselectionfun)(void);
|
||||
typedef void (* GLFWclipboarddatafreefun)(void* data);
|
||||
@ -2205,6 +2206,10 @@ typedef void (*glfwRequestWaylandFrameEvent_func)(GLFWwindow*, unsigned long lon
|
||||
GFW_EXTERN glfwRequestWaylandFrameEvent_func glfwRequestWaylandFrameEvent_impl;
|
||||
#define glfwRequestWaylandFrameEvent glfwRequestWaylandFrameEvent_impl
|
||||
|
||||
typedef void (*glfwWaylandActivateWindow_func)(GLFWwindow*, const char*);
|
||||
GFW_EXTERN glfwWaylandActivateWindow_func glfwWaylandActivateWindow_impl;
|
||||
#define glfwWaylandActivateWindow glfwWaylandActivateWindow_impl
|
||||
|
||||
typedef bool (*glfwWaylandSetTitlebarColor_func)(GLFWwindow*, uint32_t, bool);
|
||||
GFW_EXTERN glfwWaylandSetTitlebarColor_func glfwWaylandSetTitlebarColor_impl;
|
||||
#define glfwWaylandSetTitlebarColor glfwWaylandSetTitlebarColor_impl
|
||||
|
||||
@ -1037,13 +1037,17 @@ destroy_os_window(OSWindow *w) {
|
||||
}
|
||||
|
||||
void
|
||||
focus_os_window(OSWindow *w, bool also_raise) {
|
||||
focus_os_window(OSWindow *w, bool also_raise, const char *activation_token) {
|
||||
if (w->handle) {
|
||||
#ifdef __APPLE__
|
||||
if (!also_raise) cocoa_focus_window(glfwGetCocoaWindow(w->handle));
|
||||
else glfwFocusWindow(w->handle);
|
||||
(void)activation_token;
|
||||
#else
|
||||
(void)also_raise;
|
||||
if (global_state.is_wayland && activation_token && activation_token[0] && also_raise) {
|
||||
glfwWaylandActivateWindow(w->handle, activation_token);
|
||||
return;
|
||||
}
|
||||
glfwFocusWindow(w->handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ def talk_to_instance(args: CLIOptions) -> None:
|
||||
if args.session == '-':
|
||||
stdin = sys.stdin.read()
|
||||
data = {'cmd': 'new_instance', 'args': tuple(sys.argv), 'cmdline_args_for_open': getattr(sys, 'cmdline_args_for_open', []),
|
||||
'startup_id': os.environ.get('DESKTOP_STARTUP_ID'),
|
||||
'startup_id': os.environ.get('DESKTOP_STARTUP_ID'), 'activation_token': os.environ.get('XDG_ACTIVATION_TOKEN'),
|
||||
'cwd': os.getcwd(), 'stdin': stdin}
|
||||
notify_socket = None
|
||||
if args.wait_for_single_instance_window_close:
|
||||
|
||||
@ -653,7 +653,7 @@ enter_event() {
|
||||
// On cocoa there is no way to configure the window manager to
|
||||
// focus windows on mouse enter, so we do it ourselves
|
||||
if (OPT(focus_follows_mouse) && !global_state.callback_os_window->is_focused) {
|
||||
focus_os_window(global_state.callback_os_window, false);
|
||||
focus_os_window(global_state.callback_os_window, false, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -822,9 +822,10 @@ PYWRAP0(current_application_quit_request) {
|
||||
PYWRAP1(focus_os_window) {
|
||||
id_type os_window_id;
|
||||
int also_raise = 1;
|
||||
PA("K|p", &os_window_id, &also_raise);
|
||||
const char *activation_token = NULL;
|
||||
PA("K|pz", &os_window_id, &also_raise, &activation_token);
|
||||
WITH_OS_WINDOW(os_window_id)
|
||||
if (!os_window->is_focused) focus_os_window(os_window, also_raise);
|
||||
if (!os_window->is_focused || (activation_token && activation_token[0])) focus_os_window(os_window, also_raise, activation_token);
|
||||
Py_RETURN_TRUE;
|
||||
END_WITH_OS_WINDOW
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
@ -270,7 +270,7 @@ bool make_window_context_current(id_type);
|
||||
void hide_mouse(OSWindow *w);
|
||||
bool is_mouse_hidden(OSWindow *w);
|
||||
void destroy_os_window(OSWindow *w);
|
||||
void focus_os_window(OSWindow *w, bool also_raise);
|
||||
void focus_os_window(OSWindow *w, bool also_raise, const char *activation_token);
|
||||
void set_os_window_title(OSWindow *w, const char *title);
|
||||
OSWindow* os_window_for_kitty_window(id_type);
|
||||
OSWindow* add_os_window(void);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user