Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions snowcap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ rust-version.workspace = true

[dependencies]
anyhow = { workspace = true }
bitflags = { workspace = true }
iced = { version = "0.14.0", default-features = false, features = [
"wgpu",
"tokio",
Expand Down
63 changes: 63 additions & 0 deletions snowcap/api/lua/snowcap/grpc/defs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ local snowcap_layer_v1_Layer = {
---@field input_region snowcap.widget.v1.InputRegion?
---@field mouse_area snowcap.widget.v1.MouseArea?
---@field text_input snowcap.widget.v1.TextInput?
---@field wlr_task_list snowcap.widget.v1.WlrTaskList?

---@class snowcap.widget.v1.Text
---@field text string?
Expand Down Expand Up @@ -982,6 +983,31 @@ local snowcap_layer_v1_Layer = {
---@field submit google.protobuf.Empty?
---@field paste string?

---@class snowcap.widget.v1.WlrTaskList
---@field widget_id integer?
---@field on_enter boolean?
---@field on_update boolean?
---@field on_leave boolean?
---@field child snowcap.widget.v1.WidgetDef?

---@class snowcap.widget.v1.WlrTaskList.Event
---@field enter snowcap.widget.v1.WlrTaskList.WlrTaskData?
---@field update snowcap.widget.v1.WlrTaskList.WlrTaskData?
---@field leave integer?

---@class snowcap.widget.v1.WlrTaskList.WlrTaskData
---@field id integer?
---@field title string?
---@field app_id string?
---@field state snowcap.widget.v1.WlrTaskList.WlrTaskState?
---@field outputs string[]?

---@class snowcap.widget.v1.WlrTaskList.WlrTaskState
---@field maximized boolean?
---@field minimized boolean?
---@field activated boolean?
---@field fullscreen boolean?

---@class snowcap.widget.v1.GetWidgetEventsRequest
---@field layer_id integer?
---@field decoration_id integer?
Expand All @@ -991,6 +1017,7 @@ local snowcap_layer_v1_Layer = {
---@field button snowcap.widget.v1.Button.Event?
---@field mouse_area snowcap.widget.v1.MouseArea.Event?
---@field text_input snowcap.widget.v1.TextInput.Event?
---@field wlr_task_list snowcap.widget.v1.WlrTaskList.Event?

---@class snowcap.widget.v1.GetWidgetEventsResponse
---@field widget_events snowcap.widget.v1.WidgetEvent[]?
Expand Down Expand Up @@ -1029,9 +1056,35 @@ local snowcap_layer_v1_Layer = {
---@class snowcap.operation.v1.TextInput.SelectAll
---@field id string?

---@class snowcap.operation.v1.WlrTaskList
---@field maximize snowcap.operation.v1.WlrTaskList.MaximizeToplevel?
---@field minimize snowcap.operation.v1.WlrTaskList.MinimizeToplevel?
---@field fullscreen snowcap.operation.v1.WlrTaskList.FullscreenToplevel?
---@field activate snowcap.operation.v1.WlrTaskList.ActivateToplevel?
---@field close snowcap.operation.v1.WlrTaskList.CloseToplevel?

---@class snowcap.operation.v1.WlrTaskList.MaximizeToplevel
---@field id integer?
---@field maximize boolean?

---@class snowcap.operation.v1.WlrTaskList.MinimizeToplevel
---@field id integer?
---@field minimize boolean?

---@class snowcap.operation.v1.WlrTaskList.FullscreenToplevel
---@field id integer?
---@field fullscreen boolean?

---@class snowcap.operation.v1.WlrTaskList.ActivateToplevel
---@field id integer?

---@class snowcap.operation.v1.WlrTaskList.CloseToplevel
---@field id integer?

---@class snowcap.operation.v1.Operation
---@field focusable snowcap.operation.v1.Focusable?
---@field text_input snowcap.operation.v1.TextInput?
---@field wlr_task_list snowcap.operation.v1.WlrTaskList?

---@class snowcap.decoration.v1.Bounds
---@field left integer?
Expand Down Expand Up @@ -1321,6 +1374,10 @@ snowcap.widget.v1.TextInput.Icon = {}
snowcap.widget.v1.TextInput.Style = {}
snowcap.widget.v1.TextInput.Style.Inner = {}
snowcap.widget.v1.TextInput.Event = {}
snowcap.widget.v1.WlrTaskList = {}
snowcap.widget.v1.WlrTaskList.Event = {}
snowcap.widget.v1.WlrTaskList.WlrTaskData = {}
snowcap.widget.v1.WlrTaskList.WlrTaskState = {}
snowcap.widget.v1.GetWidgetEventsRequest = {}
snowcap.widget.v1.WidgetEvent = {}
snowcap.widget.v1.GetWidgetEventsResponse = {}
Expand All @@ -1336,6 +1393,12 @@ snowcap.operation.v1.TextInput.MoveCursor = {}
snowcap.operation.v1.TextInput.MoveCursorFront = {}
snowcap.operation.v1.TextInput.MoveCursorEnd = {}
snowcap.operation.v1.TextInput.SelectAll = {}
snowcap.operation.v1.WlrTaskList = {}
snowcap.operation.v1.WlrTaskList.MaximizeToplevel = {}
snowcap.operation.v1.WlrTaskList.MinimizeToplevel = {}
snowcap.operation.v1.WlrTaskList.FullscreenToplevel = {}
snowcap.operation.v1.WlrTaskList.ActivateToplevel = {}
snowcap.operation.v1.WlrTaskList.CloseToplevel = {}
snowcap.operation.v1.Operation = {}
snowcap.decoration = {}
snowcap.decoration.v1 = {}
Expand Down
140 changes: 140 additions & 0 deletions snowcap/api/lua/snowcap/widget.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
---@field input_region snowcap.widget.InputRegion?
---@field mouse_area snowcap.widget.MouseArea?
---@field text_input snowcap.widget.TextInput?
---@field wlr_task_list snowcap.widget.WlrTaskList?

---@class snowcap.widget.Border
---@field color snowcap.widget.Color?
Expand Down Expand Up @@ -436,6 +437,43 @@ local text_input_event_type = {
PASTE = "press",
}

---@class snowcap.widget.WlrTaskList
---@field package widget_id integer?
---@field on_enter (fun(task: snowcap.widget.wlr_task_list.WlrTaskData): any)?
---@field on_update (fun(task: snowcap.widget.wlr_task_list.WlrTaskData): any)?
---@field on_leave (fun(integer): any)?
---@field child snowcap.widget.WidgetDef?

---@class snowcap.widget.wlr_task_list.Callbacks
---@field on_enter (fun(task: snowcap.widget.wlr_task_list.WlrTaskData): any)?
---@field on_update (fun(task: snowcap.widget.wlr_task_list.WlrTaskData): any)?
---@field on_leave (fun(integer): any)?

---@class snowcap.widget.wlr_task_list.WlrTaskData
---@field id integer?
---@field title string?
---@field app_id string?
---@field state snowcap.widget.v1.WlrTaskList.WlrTaskState?
---@field outputs string[]?

---@class snowcap.widget.wlr_task_list.WlrTaskState
---@field maximized boolean?
---@field minimized boolean?
---@field activated boolean?
---@field fullscreen boolean?

---@class snowcap.widget.wlr_task_list.Event
---@field enter? snowcap.widget.wlr_task_list.WlrTaskState
---@field update? snowcap.widget.wlr_task_list.WlrTaskState
---@field leave? integer

---@enum snowcap.widget.wlr_task_list.event.Type
local wlr_task_list_event_type = {
ENTER = "enter",
UPDATE = "update",
LEAVE = "leave",
}

---@class snowcap.widget.Length
---@field fill {}?
---@field fill_portion integer?
Expand Down Expand Up @@ -640,6 +678,7 @@ local font = {
---@field button fun(widget: snowcap.widget.WidgetDef)?
---@field mouse_area fun(widget: snowcap.widget.WidgetDef)?
---@field text_input fun(widget: snowcap.widget.WidgetDef)?
---@field wlr_task_list fun(widget: snowcap.widget.WidgetDef)?

local widget = {
length = length,
Expand Down Expand Up @@ -832,6 +871,19 @@ local function text_input_into_api(def)
}
end

---@param def snowcap.widget.WlrTaskList
---@return snowcap.widget.v1.WlrTaskList
local function wlr_task_list_into_api(def)
---@type snowcap.widget.v1.WlrTaskList
return {
widget_id = def.widget_id,
on_enter = def.on_enter ~= nil,
on_update = def.on_update ~= nil,
on_leave = def.on_leave ~= nil,
child = widget.widget_def_into_api(def.child)
}
end

---@param def snowcap.widget.WidgetDef
---@return snowcap.widget.v1.WidgetDef
function widget.widget_def_into_api(def)
Expand Down Expand Up @@ -865,6 +917,9 @@ function widget.widget_def_into_api(def)
if def.text_input then
def.text_input = text_input_into_api(def.text_input)
end
if def.wlr_task_list then
def.wlr_task_list = wlr_task_list_into_api(def.wlr_task_list)
end

return def --[[@as snowcap.widget.v1.WidgetDef]]
end
Expand Down Expand Up @@ -1001,6 +1056,26 @@ function widget.text_input(text_input)
}
end

---@param wlr_task_list snowcap.widget.WlrTaskList
---@return snowcap.widget.WidgetDef
function widget.wlr_task_list(wlr_task_list)
local has_cb = false

has_cb = has_cb or wlr_task_list.on_enter ~= nil
has_cb = has_cb or wlr_task_list.on_update ~= nil
has_cb = has_cb or wlr_task_list.on_leave ~= nil

if has_cb then
wlr_task_list.widget_id = widget_id_counter
widget_id_counter = widget_id_counter + 1
end

---@type snowcap.widget.WidgetDef
return {
wlr_task_list = wlr_task_list
}
end

---@private
---@lcat nodoc
---@param wgt snowcap.widget.WidgetDef
Expand All @@ -1026,6 +1101,8 @@ function widget._traverse_widget_tree(wgt, callbacks, with_widget)
widget._traverse_widget_tree(wgt.input_region.child, callbacks, with_widget)
elseif wgt.mouse_area then
widget._traverse_widget_tree(wgt.mouse_area.child, callbacks, with_widget)
elseif wgt.wlr_task_list then
widget._traverse_widget_tree(wgt.wlr_task_list.child, callbacks, with_widget)
end
end

Expand Down Expand Up @@ -1065,6 +1142,20 @@ local function collect_text_input_callbacks(text_input)
}
end

---@package
---@lcat nodoc
---
---@param task_list snowcap.widget.WlrTaskList
---
---@return snowcap.widget.wlr_task_list.Callbacks
local function collect_wlr_task_list_callbacks(task_list)
return {
on_enter = task_list.on_enter,
on_update = task_list.on_update,
on_leave = task_list.on_leave,
}
end

---@private
---@lcat nodoc
---@param callbacks any[]
Expand All @@ -1081,6 +1172,10 @@ function widget._collect_callbacks(callbacks, wgt)
if wgt.text_input and wgt.text_input.widget_id then
callbacks[wgt.text_input.widget_id] = collect_text_input_callbacks(wgt.text_input)
end

if wgt.wlr_task_list and wgt.wlr_task_list.widget_id then
callbacks[wgt.wlr_task_list.widget_id] = collect_wlr_task_list_callbacks(wgt.wlr_task_list)
end
end

---@private
Expand Down Expand Up @@ -1192,6 +1287,46 @@ function widget._text_input_process_event(callbacks, event)
return msg
end

---@private
---@lcat nodoc
---
---@param callbacks snowcap.widget.wlr_task_list.Callbacks
---@param event snowcap.widget.wlr_task_list.Event
---@return any?
function widget._wlr_task_list_process_event(callbacks, event)
callbacks = callbacks or {}

local translate = {
[wlr_task_list_event_type.ENTER] = "on_enter",
[wlr_task_list_event_type.UPDATE] = "on_update",
[wlr_task_list_event_type.LEAVE] = "on_leave",
}

local event_type = nil
local cb = nil

for k, v in pairs(translate) do
if event[k] ~= nil then
event_type = k
cb = callbacks[v]

break
end
end

if cb == nil then
return nil
end

local ok, val = pcall(cb, event[event_type])

if not ok then
require("snowcap.log").error(val)
end

return val
end

---@private
---@lcat nodoc
---@param callbacks any[]
Expand All @@ -1212,6 +1347,11 @@ function widget._message_from_event(callbacks, event)
---@diagnostic disable-next-line:param-type-mismatch
msg = widget._text_input_process_event(callbacks[widget_id], event.text_input)
end
elseif event.wlr_task_list then
if callbacks[widget_id] ~= nil then
---@diagnostic disable-next-line:param-type-mismatch
msg = widget._wlr_task_list_process_event(callbacks[widget_id], event.wlr_task_list)
end
end

return msg
Expand Down
Loading
Loading