mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 02:31:45 +02:00
Detach tab via drag and drop now implemented
This commit is contained in:
2
glfw/wl_window.c
vendored
2
glfw/wl_window.c
vendored
@@ -3227,7 +3227,7 @@ static void
|
|||||||
drag_source_dnd_drop_performed(void *data UNUSED, struct wl_data_source *source UNUSED) {
|
drag_source_dnd_drop_performed(void *data UNUSED, struct wl_data_source *source UNUSED) {
|
||||||
_GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id);
|
_GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id);
|
||||||
if (window) {
|
if (window) {
|
||||||
GLFWDragEvent ev = {.type=GLFW_DRAG_ACTION_CHANGED};
|
GLFWDragEvent ev = {.type=GLFW_DRAG_DROPPED};
|
||||||
_glfwInputDragSourceRequest(window, &ev);
|
_glfwInputDragSourceRequest(window, &ev);
|
||||||
} else drag_source_cancelled(data, source);
|
} else drag_source_cancelled(data, source);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1917,6 +1917,7 @@ class Boss:
|
|||||||
set_tab_being_dragged()
|
set_tab_being_dragged()
|
||||||
for tm in self.all_tab_managers:
|
for tm in self.all_tab_managers:
|
||||||
tm.on_tab_drop_move(0, False, 0, 0)
|
tm.on_tab_drop_move(0, False, 0, 0)
|
||||||
|
tm.layout_tab_bar() # ensure tab bar is fully updated
|
||||||
return
|
return
|
||||||
central, tab_bar = viewport_for_window(os_window_id)[:2]
|
central, tab_bar = viewport_for_window(os_window_id)[:2]
|
||||||
if central.left <= x < central.right and central.top <= y < central.bottom:
|
if central.left <= x < central.right and central.top <= y < central.bottom:
|
||||||
@@ -1932,6 +1933,18 @@ class Boss:
|
|||||||
if (tab_id := tm.tab_bar.tab_id_at(x)) and (tab := self.tab_for_id(tab_id)) and (w := tab.active_window):
|
if (tab_id := tm.tab_bar.tab_id_at(x)) and (tab := self.tab_for_id(tab_id)) and (w := tab.active_window):
|
||||||
w.on_drop(drop)
|
w.on_drop(drop)
|
||||||
|
|
||||||
|
def on_drag_source_finished(
|
||||||
|
self, was_dropped: bool, was_canceled: bool, accepted_mime_type: str, action: int, data: dict[str, bytes] | None
|
||||||
|
) -> None:
|
||||||
|
if data and (tidb := data.get(f'application/net.kovidgoyal.kitty-tab-{os.getpid()}')):
|
||||||
|
set_tab_being_dragged()
|
||||||
|
for tm in self.all_tab_managers:
|
||||||
|
tm.on_tab_drop_move(0, False, 0, 0)
|
||||||
|
if not was_dropped: # detach tab into new OS Window
|
||||||
|
tab_id = int(tidb.decode())
|
||||||
|
if (tab := self.tab_for_id(tab_id)):
|
||||||
|
self._move_tab_to(tab)
|
||||||
|
|
||||||
@ac('win', '''
|
@ac('win', '''
|
||||||
Focus the nth OS window if positive or the previously active OS windows if negative. When the number is larger
|
Focus the nth OS window if positive or the previously active OS windows if negative. When the number is larger
|
||||||
than the number of OS windows focus the last OS window. A value of zero will refocus the currently focused OS window,
|
than the number of OS windows focus the last OS window. A value of zero will refocus the currently focused OS window,
|
||||||
|
|||||||
10
kitty/glfw.c
10
kitty/glfw.c
@@ -746,6 +746,7 @@ on_drop(GLFWwindow *window, GLFWDropEvent *ev) {
|
|||||||
Py_CLEAR(global_state.drop_dest.data);
|
Py_CLEAR(global_state.drop_dest.data);
|
||||||
if (ev->from_self) {
|
if (ev->from_self) {
|
||||||
if (global_state.drag_source.drag_data) {
|
if (global_state.drag_source.drag_data) {
|
||||||
|
global_state.drag_source.was_dropped = true;
|
||||||
WINDOW_CALLBACK(on_drop, "OOii", global_state.drag_source.drag_data, Py_True,
|
WINDOW_CALLBACK(on_drop, "OOii", global_state.drag_source.drag_data, Py_True,
|
||||||
global_state.callback_os_window->last_drag_event.x, global_state.callback_os_window->last_drag_event.y);
|
global_state.callback_os_window->last_drag_event.x, global_state.callback_os_window->last_drag_event.y);
|
||||||
} else log_error("Got a drop from self but drag_source.drag_data is NULL");
|
} else log_error("Got a drop from self but drag_source.drag_data is NULL");
|
||||||
@@ -804,12 +805,17 @@ drag_source_callback(GLFWwindow *window UNUSED, GLFWDragEvent *ev) {
|
|||||||
ds.accepted_mime_type = ev->mime_type ? strdup(ev->mime_type) : NULL;
|
ds.accepted_mime_type = ev->mime_type ? strdup(ev->mime_type) : NULL;
|
||||||
break;
|
break;
|
||||||
case GLFW_DRAG_ACTION_CHANGED: ds.action = ev->action; break;
|
case GLFW_DRAG_ACTION_CHANGED: ds.action = ev->action; break;
|
||||||
case GLFW_DRAG_DROPPED: ds.was_dropped = true; break;
|
case GLFW_DRAG_DROPPED:
|
||||||
|
ds.was_dropped = true;
|
||||||
|
break;
|
||||||
case GLFW_DRAG_CANCELLED:
|
case GLFW_DRAG_CANCELLED:
|
||||||
ds.was_canceled = true;
|
ds.was_canceled = true;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case GLFW_DRAG_FINSHED:
|
case GLFW_DRAG_FINSHED:
|
||||||
ds.is_active = false;
|
call_boss(on_drag_source_finished, "OOsiO",
|
||||||
|
ds.was_dropped ? Py_True : Py_False, ds.was_canceled ? Py_True: Py_False,
|
||||||
|
ds.accepted_mime_type ? ds.accepted_mime_type : "",
|
||||||
|
ds.action, ds.drag_data ? ds.drag_data : Py_None);
|
||||||
free_drag_source();
|
free_drag_source();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user