finished application laucnher and bluetooth widget
This commit is contained in:
@@ -5,52 +5,106 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gobject = require("gears").object
|
||||
local gtable = require("gears").table
|
||||
local gcolor = require("gears").color
|
||||
local gshape = require("gears").shape
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local wibox = require("wibox")
|
||||
local base = require("wibox.widget.base")
|
||||
local lgi = require("lgi")
|
||||
local dbus_proxy = require("dbus_proxy")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
}
|
||||
local context_menu = require("src.modules.context_menu")
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
|
||||
local capi = {
|
||||
awesome = awesome
|
||||
}
|
||||
|
||||
local device = { mt = {} }
|
||||
|
||||
function device:connect()
|
||||
self.device:Connect()
|
||||
self.widget:get_children_by_id("con")[1].image = gcolor.recolor_image(icondir .. "link.svg",
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
capi.awesome.emit_signal("bluetooth::disconnect", device)
|
||||
function device:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
function device:disconnect()
|
||||
self.device:Disconnect()
|
||||
self.widget:get_children_by_id("con")[1].image = gcolor.recolor_image(icondir .. "link-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
capi.awesome.emit_signal("bluetooth::connect", device)
|
||||
function device:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
device.set_widget = base.set_widget_common
|
||||
|
||||
function device:get_widget()
|
||||
return self._private.widget
|
||||
end
|
||||
|
||||
function device:toggle_connect()
|
||||
if not self.device.Connected then
|
||||
|
||||
--TODO: Implement device passcode support, I have no idea how to get the
|
||||
--TODO: Methods from Agent1 implemented
|
||||
--[[ self._private.AgentManager1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
path = "/org/bluez",
|
||||
interface = "org.bluez.AgentManager1"
|
||||
}
|
||||
|
||||
self._private.Agent1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
path = "/org/bluez",
|
||||
interface = "org.bluez.Agent1",
|
||||
}
|
||||
|
||||
self._private.AgentManager1:RegisterAgent(self._private.Agent1.object_path, "")
|
||||
self._private.AgentManager1:RequestDefaultAgent(self._private.Agent1.object_path) ]]
|
||||
|
||||
self.device:ConnectAsync()
|
||||
else
|
||||
self.device:DisconnectAsync()
|
||||
end
|
||||
end
|
||||
|
||||
function device:toggle_pair()
|
||||
if self.device.Paired then
|
||||
self.device:PairAsync()
|
||||
else
|
||||
self.device:CancelPairingAsync()
|
||||
end
|
||||
end
|
||||
|
||||
function device:toggle_trusted()
|
||||
self.device:Set("org.bluez.Device1", "Trusted", lgi.GLib.Variant("b", not self.device.Trusted))
|
||||
self.device.Trusted = { signature = "b", value = not self.device.Trusted }
|
||||
|
||||
end
|
||||
|
||||
function device:rename(newname)
|
||||
self.device:Set("org.bluez.Device1", "Alias", lgi.GLib.Variant("s", newname))
|
||||
self.device.Alias = { signature = "s", value = newname }
|
||||
return self.device:Get("org.bluez.Device1", "Alias")
|
||||
end
|
||||
|
||||
function device.new(args)
|
||||
args = args or {}
|
||||
args.device = args.device or {}
|
||||
args.battery = args.battery or {}
|
||||
|
||||
local ret = gobject { enable_properties = true, enable_auto_signals = true }
|
||||
gtable.crush(ret, device, true)
|
||||
|
||||
if args.device then
|
||||
ret.device = args.device
|
||||
end
|
||||
if args.battery then
|
||||
ret.battery = args.battery
|
||||
end
|
||||
|
||||
local icon = device.Icon or "bluetooth-on"
|
||||
local device_widget = wibox.widget {
|
||||
|
||||
local inputbox = awful.widget.inputbox {
|
||||
text = args.device.Alias or args.device.Name,
|
||||
halign = "left",
|
||||
valign = "center",
|
||||
}
|
||||
|
||||
local ret = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
@@ -75,9 +129,11 @@ function device.new(args)
|
||||
{
|
||||
{
|
||||
{
|
||||
text = ret.device.Alias or ret.device.Name,
|
||||
id = "alias",
|
||||
widget = wibox.widget.textbox
|
||||
inputbox,
|
||||
widget = wibox.container.constraint,
|
||||
strategy = "min",
|
||||
width = dpi(400),
|
||||
id = "const"
|
||||
},
|
||||
{
|
||||
text = "Connecting...",
|
||||
@@ -150,33 +206,133 @@ function device.new(args)
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
device = ret.device,
|
||||
widget = wibox.container.background
|
||||
}
|
||||
})
|
||||
|
||||
if ret.device.Connected then
|
||||
device_widget:get_children_by_id("con")[1].image = gcolor.recolor_image(icondir .. "link.svg",
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
else
|
||||
device_widget:get_children_by_id("con")[1].image = gcolor.recolor_image(icondir .. "link-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
gtable.crush(ret, device, true)
|
||||
|
||||
if args.device then
|
||||
ret.device = args.device
|
||||
end
|
||||
|
||||
device_widget:buttons(
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(ret.device.Connected and icondir .. "link.svg" or
|
||||
icondir .. "link-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
|
||||
local cm = context_menu {
|
||||
widget_template = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
widget = wibox.widget.imagebox,
|
||||
resize = true,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
id = "icon_role",
|
||||
},
|
||||
widget = wibox.container.constraint,
|
||||
stragety = "exact",
|
||||
width = dpi(24),
|
||||
height = dpi(24),
|
||||
id = "const"
|
||||
},
|
||||
{
|
||||
widget = wibox.widget.textbox,
|
||||
valign = "center",
|
||||
halign = "left",
|
||||
id = "text_role"
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
},
|
||||
widget = wibox.container.margin
|
||||
},
|
||||
widget = wibox.container.background,
|
||||
}, spacing = dpi(10),
|
||||
entries = {
|
||||
{
|
||||
name = ret.device.Connected and "Disconnect" or "Connect",
|
||||
icon = gcolor.recolor_image(ret.device.Connected and icondir .. "bluetooth-off.svg" or
|
||||
icondir .. "bluetooth-on.svg",
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_connect()
|
||||
end,
|
||||
id = "connected"
|
||||
},
|
||||
{
|
||||
name = "Pair",
|
||||
icon = gcolor.recolor_image(ret.device.Paired and icondir .. "link-off.svg" or
|
||||
icondir .. "link.svg",
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_pair()
|
||||
end
|
||||
},
|
||||
{
|
||||
name = ret.device.Trusted and "Untrust" or "Trust",
|
||||
icon = gcolor.recolor_image(ret.device.Trusted and icondir .. "untrusted.svg" or icondir .. "trusted.svg",
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
ret:toggle_trusted()
|
||||
end,
|
||||
id = "trusted"
|
||||
},
|
||||
{
|
||||
name = "Rename",
|
||||
icon = gcolor.recolor_image(icondir .. "edit.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
inputbox:focus()
|
||||
inputbox:connect_signal("submit", function(text)
|
||||
text = text:get_text()
|
||||
inputbox.markup = ret:rename(text)
|
||||
end)
|
||||
end
|
||||
},
|
||||
{
|
||||
name = "Remove",
|
||||
icon = gcolor.recolor_image(icondir .. "delete.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
callback = function()
|
||||
args.remove_callback(ret.device)
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret:buttons(
|
||||
gtable.join(
|
||||
awful.button({}, 1, function()
|
||||
if ret.device.Connected then
|
||||
ret:disconnect()
|
||||
else
|
||||
ret:connect()
|
||||
ret:toggle_connect()
|
||||
end),
|
||||
awful.button({}, 3, function()
|
||||
for _, value in ipairs(cm.widget.children) do
|
||||
value.id = value.id or ""
|
||||
if value.id:match("connected") then
|
||||
value:get_children_by_id("text_role")[1].text = ret.device.Connected and "Disconnect" or "Connect"
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Connected and
|
||||
icondir .. "bluetooth-off.svg" or icondir .. "bluetooth-on.svg",
|
||||
Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match("trusted") then
|
||||
value:get_children_by_id("text_role")[1].text = ret.device.Trusted and "Untrust" or "Trust"
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Trusted and
|
||||
icondir .. "untrusted.svg" or icondir .. "trusted.svg", Theme_config.bluetooth_controller.icon_color)
|
||||
elseif value.id:match("paired") then
|
||||
value:get_children_by_id("icon_role")[1].image = gcolor.recolor_image(ret.device.Paired and
|
||||
icondir .. "link-off.svg" or icondir .. "link.svg", Theme_config.bluetooth_controller.icon_color)
|
||||
end
|
||||
end
|
||||
cm:toggle()
|
||||
end)
|
||||
)
|
||||
)
|
||||
|
||||
Hover_signal(device_widget)
|
||||
capi.awesome.connect_signal(ret.device.object_path .. "_updated", function(d)
|
||||
ret:get_children_by_id("con")[1].image = gcolor.recolor_image(d.Connected and icondir .. "link.svg" or
|
||||
icondir .. "link-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color_dark)
|
||||
end)
|
||||
|
||||
ret.widget = device_widget
|
||||
Hover_signal(ret)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
-- Awesome Libs
|
||||
local awful = require("awful")
|
||||
local dpi = require("beautiful").xresources.apply_dpi
|
||||
local gobject = require("gears").object
|
||||
local gtable = require("gears").table
|
||||
local gcolor = require("gears").color
|
||||
local gshape = require("gears").shape
|
||||
local gfilesystem = require("gears").filesystem
|
||||
local wibox = require("wibox")
|
||||
local base = require("wibox.widget.base")
|
||||
local dbus_proxy = require("dbus_proxy")
|
||||
local lgi = require("lgi")
|
||||
local gtimer = require("gears.timer")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local bt_device = require("src.modules.bluetooth.device")
|
||||
|
||||
@@ -18,54 +22,218 @@ local rubato = require("src.lib.rubato")
|
||||
|
||||
local icondir = gfilesystem.get_configuration_dir() .. "src/assets/icons/bluetooth/"
|
||||
|
||||
local dnd_widget = require("awful.widget.toggle_widget")
|
||||
|
||||
local capi = {
|
||||
awesome = awesome,
|
||||
mouse = mouse,
|
||||
mousegrabber = mousegrabber,
|
||||
}
|
||||
|
||||
local bluetooth = { mt = {} }
|
||||
|
||||
bluetooth.devices = {
|
||||
paired = { layout = wibox.layout.fixed.vertical },
|
||||
discovered = { layout = wibox.layout.fixed.vertical }
|
||||
}
|
||||
|
||||
function bluetooth:get_devices()
|
||||
return self.devices
|
||||
function bluetooth:layout(_, width, height)
|
||||
if self._private.widget then
|
||||
return { base.place_widget_at(self._private.widget, 0, 0, width, height) }
|
||||
end
|
||||
end
|
||||
|
||||
local function add_device(self, device, battery)
|
||||
--Check if the device is already in the list
|
||||
for _, status in pairs(self.devices) do
|
||||
for _, dev in ipairs(status) do
|
||||
if dev.device.Address == device.Address then
|
||||
return
|
||||
function bluetooth:fit(context, width, height)
|
||||
local w, h = 0, 0
|
||||
if self._private.widget then
|
||||
w, h = base.fit_widget(self, context, self._private.widget, width, height)
|
||||
end
|
||||
return w, h
|
||||
end
|
||||
|
||||
bluetooth.set_widget = base.set_widget_common
|
||||
|
||||
function bluetooth:get_widget()
|
||||
return self._private.widget
|
||||
end
|
||||
|
||||
function bluetooth:get_paired_devices()
|
||||
return self:get_children_by_id("connected_device_list")[1].children
|
||||
end
|
||||
|
||||
function bluetooth:get_discovered_devices()
|
||||
return self:get_children_by_id("discovered_device_list")[1].children
|
||||
end
|
||||
|
||||
function bluetooth:remove_device_information(device)
|
||||
-- Either disconnect async and have to remove the device "twice"
|
||||
-- or do it sync but awesome freezes for a second or two
|
||||
print("bruh?")
|
||||
device:DisconnectAsync(function(_, _, out, err)
|
||||
print(out, err)
|
||||
self._private.Adapter1:RemoveDevice(device.object_path)
|
||||
end)
|
||||
end
|
||||
|
||||
function bluetooth:add_device(device, object_path)
|
||||
|
||||
local plist = self:get_children_by_id("connected_device_list")[1]
|
||||
local dlist = self:get_children_by_id("discovered_device_list")[1]
|
||||
|
||||
for _, value in pairs(dlist.children) do
|
||||
-- I'm not sure why Connected is in both cases true when its a new connection but eh just take it, it works
|
||||
if value.device.Address:match(device.Address) and (device.Connected ~= value.device.Connected) then
|
||||
print("Bad ", value.device.Alias)
|
||||
return
|
||||
elseif value.device.Address:match(device.Address) and (device.Connected == value.device.Connected) then
|
||||
print("Good ", value.device.Alias)
|
||||
dlist:remove_widgets(value)
|
||||
plist:add(plist:add(bt_device {
|
||||
device = device,
|
||||
path = object_path,
|
||||
remove_callback = function()
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
}))
|
||||
return;
|
||||
end
|
||||
end
|
||||
for _, value in pairs(plist.children) do
|
||||
if value.device.Address:match(device.Address) then return end
|
||||
end
|
||||
|
||||
if device.Paired then
|
||||
plist:add(bt_device {
|
||||
device = device,
|
||||
path = object_path,
|
||||
remove_callback = function()
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
})
|
||||
else
|
||||
dlist:add(bt_device {
|
||||
device = device,
|
||||
path = object_path,
|
||||
remove_callback = function()
|
||||
self:remove_device_information(device)
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function bluetooth:remove_device(object_path)
|
||||
local plist = self:get_children_by_id("connected_device_list")[1]
|
||||
local dlist = self:get_children_by_id("discovered_device_list")[1]
|
||||
for _, d in ipairs(dlist.children) do
|
||||
if d.device.object_path == object_path then
|
||||
dlist:remove_widgets(d)
|
||||
end
|
||||
end
|
||||
for _, d in ipairs(plist.children) do
|
||||
if d.device.object_path == object_path then
|
||||
plist:remove_widgets(d)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function bluetooth:update_device(new_device, object_path)
|
||||
for _, device in ipairs(self.devices.paired:get_children()) do
|
||||
if device.path == object_path then
|
||||
device.device:update(new_device)
|
||||
end
|
||||
end
|
||||
for _, device in ipairs(self.devices.discovered:get_children()) do
|
||||
if device.path == object_path then
|
||||
device.device:update(new_device)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function bluetooth:scan()
|
||||
self._private.Adapter1:StartDiscovery()
|
||||
end
|
||||
|
||||
function bluetooth:stop_scan()
|
||||
self._private.Adapter1:StopDiscovery()
|
||||
end
|
||||
|
||||
function bluetooth:toggle()
|
||||
local powered = self._private.Adapter1.Powered
|
||||
|
||||
self._private.Adapter1:Set("org.bluez.Adapter1", "Powered", lgi.GLib.Variant("b", not powered))
|
||||
self._private.Adapter1.Powered = {
|
||||
signature = "b",
|
||||
value = not powered
|
||||
}
|
||||
end
|
||||
|
||||
function bluetooth:open_settings()
|
||||
awful.spawn("blueman-manager")
|
||||
end
|
||||
|
||||
function bluetooth:get_device_info(object_path)
|
||||
if (not object_path) or (not object_path:match("/org/bluez/hci0/dev")) then return end
|
||||
|
||||
local Device1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.bluez.Device1",
|
||||
path = object_path
|
||||
}
|
||||
|
||||
local Device1Properties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = object_path
|
||||
}
|
||||
|
||||
if (not Device1.Name) or (Device1.Name == "") then return end
|
||||
|
||||
local just_notified = false
|
||||
|
||||
local notify_timer = gtimer {
|
||||
timeout = 3,
|
||||
autostart = false,
|
||||
single_shot = true,
|
||||
callback = function()
|
||||
just_notified = false
|
||||
end
|
||||
}
|
||||
|
||||
Device1Properties:connect_signal(function(_, _, changed_props)
|
||||
if changed_props["Connected"] ~= nil then
|
||||
if not just_notified then
|
||||
naughty.notification({
|
||||
app_icon = icondir .. "bluetooth-on.svg",
|
||||
app_name = "Bluetooth",
|
||||
title = Device1.Name,
|
||||
icon = gcolor.recolor_image(icondir .. Device1.Icon .. ".svg", Theme_config.bluetooth_controller.icon_color),
|
||||
timeout = 5,
|
||||
message = "Device " ..
|
||||
Device1.Name .. " is now " .. (changed_props["Connected"] and "connected" or "disconnected"),
|
||||
category = Device1.Connected and "device.added" or "device.removed",
|
||||
})
|
||||
just_notified = true
|
||||
notify_timer:start()
|
||||
end
|
||||
end
|
||||
end
|
||||
if device.Paired then
|
||||
table.insert(self.devices.paired, bt_device.new { device = device, battery = battery }.widget)
|
||||
else
|
||||
table.insert(self.devices.discovered, bt_device.new { device = device, battery = battery }.widget)
|
||||
end
|
||||
capi.awesome.emit_signal(object_path .. "_updated", Device1)
|
||||
end, "PropertiesChanged")
|
||||
|
||||
self:add_device(Device1, object_path)
|
||||
end
|
||||
|
||||
local function remove_device(self, device)
|
||||
for i, dev in pairs(self.devices) do
|
||||
if dev.Address == device.Address then
|
||||
table.remove(self.devices, i)
|
||||
end
|
||||
end
|
||||
local function send_state_notification(powered)
|
||||
naughty.notification {
|
||||
app_icon = gcolor.recolor_image(icondir .. "bluetooth-on.svg", Theme_config.bluetooth_controller.icon_color),
|
||||
app_name = "Bluetooth",
|
||||
title = "Bluetooth",
|
||||
message = powered and "Enabled" or "Disabled",
|
||||
icon = gcolor.recolor_image(powered and icondir .. "bluetooth-on.svg" or icondir .. "bluetooth-off.svg",
|
||||
Theme_config.bluetooth_controller.icon_color),
|
||||
category = powered and "device.added" or "device.removed",
|
||||
}
|
||||
end
|
||||
|
||||
function bluetooth.new(args)
|
||||
args = args or {}
|
||||
|
||||
local ret = gobject { enable_properties = true, enable_auto_signals = true }
|
||||
gtable.crush(ret, bluetooth, true)
|
||||
|
||||
local bluetooth_container = wibox.widget {
|
||||
local ret = base.make_widget_from_value(wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
@@ -198,29 +366,15 @@ function bluetooth.new(args)
|
||||
},
|
||||
{
|
||||
{ -- action buttons
|
||||
{ -- turn off
|
||||
{
|
||||
{
|
||||
image = gcolor.recolor_image(icondir .. "power.svg",
|
||||
Theme_config.bluetooth_controller.power_icon_color),
|
||||
resize = false,
|
||||
valign = "center",
|
||||
halign = "center",
|
||||
widget = wibox.widget.imagebox,
|
||||
id = "icon"
|
||||
},
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
id = "center"
|
||||
{
|
||||
dnd_widget {
|
||||
color = Theme_config.bluetooth_controller.power_bg,
|
||||
size = dpi(40)
|
||||
},
|
||||
border_width = dpi(2),
|
||||
border_color = Theme_config.bluetooth_controller.border_color,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
bg = Theme_config.bluetooth_controller.power_bg,
|
||||
widget = wibox.container.background,
|
||||
id = "power",
|
||||
id = "dnd",
|
||||
widget = wibox.container.place,
|
||||
valign = "center",
|
||||
halign = "center"
|
||||
},
|
||||
nil,
|
||||
{ -- refresh
|
||||
@@ -236,16 +390,16 @@ function bluetooth.new(args)
|
||||
widget = wibox.container.margin,
|
||||
margins = dpi(5),
|
||||
},
|
||||
border_width = dpi(2),
|
||||
border_color = Theme_config.bluetooth_controller.border_color,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(4))
|
||||
end,
|
||||
bg = Theme_config.bluetooth_controller.refresh_bg,
|
||||
id = "scan",
|
||||
widget = wibox.container.background
|
||||
},
|
||||
layout = wibox.layout.align.horizontal
|
||||
},
|
||||
id = "marg_dnd",
|
||||
widget = wibox.container.margin,
|
||||
top = dpi(10),
|
||||
},
|
||||
@@ -266,28 +420,91 @@ function bluetooth.new(args)
|
||||
widget = wibox.container.background
|
||||
},
|
||||
width = dpi(400),
|
||||
forced_width = dpi(400),
|
||||
strategy = "exact",
|
||||
widget = wibox.container.constraint
|
||||
})
|
||||
|
||||
local dnd = ret:get_children_by_id("dnd")[1]:get_widget()
|
||||
|
||||
dnd:connect_signal("dnd::toggle", function(enable)
|
||||
ret:toggle()
|
||||
end)
|
||||
|
||||
gtable.crush(ret, bluetooth, true)
|
||||
|
||||
--#region Bluetooth Proxies
|
||||
-- Create a proxy for the freedesktop ObjectManager
|
||||
ret._private.ObjectManager = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.ObjectManager",
|
||||
path = "/"
|
||||
}
|
||||
|
||||
capi.awesome.connect_signal(
|
||||
"bluetooth::device_changed",
|
||||
function(device, battery)
|
||||
add_device(ret, device, battery)
|
||||
remove_device(ret, device)
|
||||
bluetooth_container:get_children_by_id("connected_device_list")[1].children = ret:get_devices().paired
|
||||
bluetooth_container:get_children_by_id("discovered_device_list")[1].children = ret:get_devices().discovered
|
||||
end
|
||||
)
|
||||
-- Create a proxy for the bluez Adapter1 interface
|
||||
ret._private.Adapter1 = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.bluez.Adapter1",
|
||||
path = "/org/bluez/hci0"
|
||||
}
|
||||
|
||||
local connected_margin = bluetooth_container:get_children_by_id("connected_margin")[1]
|
||||
local connected_list = bluetooth_container:get_children_by_id("connected_list")[1]
|
||||
local connected = bluetooth_container:get_children_by_id("connected")[1].center
|
||||
-- Create a proxy for the bluez Adapter1 Properties interface
|
||||
ret._private.Adapter1Properties = dbus_proxy.Proxy:new {
|
||||
bus = dbus_proxy.Bus.SYSTEM,
|
||||
name = "org.bluez",
|
||||
interface = "org.freedesktop.DBus.Properties",
|
||||
path = "/org/bluez/hci0"
|
||||
}
|
||||
|
||||
-- Connect to the ObjectManager's InterfacesAdded signal
|
||||
ret._private.ObjectManager:connect_signal(function(_, interface)
|
||||
ret:get_device_info(interface)
|
||||
end, "InterfacesAdded")
|
||||
|
||||
-- Connect to the ObjectManager's InterfacesRemoved signal
|
||||
ret._private.ObjectManager:connect_signal(function(_, interface)
|
||||
ret:remove_device(interface)
|
||||
end, "InterfacesRemoved")
|
||||
|
||||
-- Connect to the Adapter1's PropertiesChanged signal
|
||||
ret._private.Adapter1Properties:connect_signal(function(_, _, data)
|
||||
if data.Powered ~= nil then
|
||||
send_state_notification(data.Powered)
|
||||
if data.Powered then
|
||||
dnd:set_enabled()
|
||||
ret:scan()
|
||||
else
|
||||
dnd:set_disabled()
|
||||
end
|
||||
ret:emit_signal("bluetooth::status", data.Powered)
|
||||
end
|
||||
end, "PropertiesChanged")
|
||||
|
||||
gtimer.delayed_call(function()
|
||||
for path, _ in pairs(ret._private.ObjectManager:GetManagedObjects()) do
|
||||
ret:get_device_info(path)
|
||||
end
|
||||
if ret._private.Adapter1.Powered then
|
||||
dnd:set_enabled()
|
||||
ret:scan()
|
||||
else
|
||||
dnd:set_disabled()
|
||||
end
|
||||
ret:emit_signal("bluetooth::status", ret._private.Adapter1.Powered)
|
||||
send_state_notification(ret._private.Adapter1.Powered)
|
||||
end)
|
||||
--#endregion
|
||||
|
||||
--#region Dropdown logic
|
||||
local connected_margin = ret:get_children_by_id("connected_margin")[1]
|
||||
local connected_list = ret:get_children_by_id("connected_list")[1]
|
||||
local connected = ret:get_children_by_id("connected")[1].center
|
||||
|
||||
connected_margin:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
capi.awesome.emit_signal("bluetooth::scan")
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = connected_list.forced_height,
|
||||
@@ -297,7 +514,7 @@ function bluetooth.new(args)
|
||||
end
|
||||
}
|
||||
if connected_list.forced_height == 0 then
|
||||
local size = (#ret:get_devices().paired * 60) + 1
|
||||
local size = (#ret:get_paired_devices() * 60) + 1
|
||||
if size < 210 then
|
||||
rubato_timer.target = dpi(size)
|
||||
end
|
||||
@@ -317,16 +534,14 @@ function bluetooth.new(args)
|
||||
end
|
||||
)
|
||||
|
||||
local discovered_margin = bluetooth_container:get_children_by_id("discovered_margin")[1]
|
||||
local discovered_list = bluetooth_container:get_children_by_id("discovered_list")[1]
|
||||
local discovered_bg = bluetooth_container:get_children_by_id("discovered_bg")[1]
|
||||
local discovered = bluetooth_container:get_children_by_id("discovered")[1].center
|
||||
local discovered_margin = ret:get_children_by_id("discovered_margin")[1]
|
||||
local discovered_list = ret:get_children_by_id("discovered_list")[1]
|
||||
local discovered_bg = ret:get_children_by_id("discovered_bg")[1]
|
||||
local discovered = ret:get_children_by_id("discovered")[1].center
|
||||
|
||||
discovered_margin:connect_signal(
|
||||
"button::press",
|
||||
function()
|
||||
capi.awesome.emit_signal("bluetooth::scan")
|
||||
|
||||
local rubato_timer = rubato.timed {
|
||||
duration = 0.2,
|
||||
pos = discovered_list.forced_height,
|
||||
@@ -337,7 +552,7 @@ function bluetooth.new(args)
|
||||
}
|
||||
|
||||
if discovered_list.forced_height == 0 then
|
||||
local size = (#ret:get_devices().discovered * 60) + 1
|
||||
local size = (#ret:get_discovered_devices() * 60) + 1
|
||||
if size > 210 then
|
||||
size = 210
|
||||
end
|
||||
@@ -357,52 +572,17 @@ function bluetooth.new(args)
|
||||
end
|
||||
end
|
||||
)
|
||||
--#endregion
|
||||
|
||||
ret.widget = awful.popup {
|
||||
widget = bluetooth_container,
|
||||
ontop = true,
|
||||
bg = Theme_config.bluetooth_controller.container_bg,
|
||||
stretch = false,
|
||||
visible = false,
|
||||
screen = args.screen,
|
||||
placement = function(c) awful.placement.align(c,
|
||||
{ position = "top_right", margins = { right = dpi(360), top = dpi(60) } })
|
||||
end,
|
||||
shape = function(cr, width, height)
|
||||
gshape.rounded_rect(cr, width, height, dpi(12))
|
||||
end
|
||||
}
|
||||
ret:get_children_by_id("scan")[1]:buttons({
|
||||
awful.button({}, 1, function()
|
||||
ret:scan()
|
||||
end)
|
||||
})
|
||||
|
||||
awesome.connect_signal(
|
||||
"bluetooth_controller::toggle",
|
||||
function()
|
||||
if ret.widget.screen == capi.mouse.screen then
|
||||
ret.widget.visible = not ret.widget.visible
|
||||
end
|
||||
end
|
||||
)
|
||||
Hover_signal(ret:get_children_by_id("scan")[1])
|
||||
|
||||
|
||||
ret.widget:connect_signal(
|
||||
"mouse::leave",
|
||||
function()
|
||||
capi.mousegrabber.run(
|
||||
function()
|
||||
capi.awesome.emit_signal("bluetooth_controller::toggle", args.screen)
|
||||
capi.mousegrabber.stop()
|
||||
return true
|
||||
end,
|
||||
"arrow"
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
ret.widget:connect_signal(
|
||||
"mouse::enter",
|
||||
function()
|
||||
capi.mousegrabber.stop()
|
||||
end
|
||||
)
|
||||
return ret
|
||||
end
|
||||
|
||||
function bluetooth.mt:__call(...)
|
||||
|
||||
Reference in New Issue
Block a user