Update
This commit is contained in:
parent
5e0d7f9550
commit
45cdc5f9ca
23
Cargo.toml
23
Cargo.toml
@ -6,23 +6,24 @@ authors = ["Julian Ospald <hasufell@posteo.de>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
alsa = "^0.1.8"
|
alsa = "^0.1.8"
|
||||||
alsa-sys = "^0.1.1"
|
alsa-sys = "^0.1.1"
|
||||||
libc = "^0.2.23"
|
error-chain = { path = "3rdparty/error-chain" }
|
||||||
gdk-sys = { git = "https://github.com/gtk-rs/sys" }
|
ffi = "^0.0.2"
|
||||||
|
flexi_logger = "^0.5.1"
|
||||||
gdk-pixbuf = { git = "https://github.com/gtk-rs/gdk-pixbuf.git" }
|
gdk-pixbuf = { git = "https://github.com/gtk-rs/gdk-pixbuf.git" }
|
||||||
gdk-pixbuf-sys = { git = "https://github.com/gtk-rs/sys" }
|
gdk-pixbuf-sys = { git = "https://github.com/gtk-rs/sys" }
|
||||||
gtk-sys = { git = "https://github.com/gtk-rs/sys" }
|
gdk-sys = { git = "https://github.com/gtk-rs/sys" }
|
||||||
|
gio = { git = "https://github.com/gtk-rs/gio.git" }
|
||||||
glib = { git = "https://github.com/gtk-rs/glib.git" }
|
glib = { git = "https://github.com/gtk-rs/glib.git" }
|
||||||
glib-sys = { git = "https://github.com/gtk-rs/sys" }
|
glib-sys = { git = "https://github.com/gtk-rs/sys" }
|
||||||
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
|
gobject-sys = { git = "https://github.com/gtk-rs/sys" }
|
||||||
ffi = "^0.0.2"
|
gtk-sys = { git = "https://github.com/gtk-rs/sys" }
|
||||||
flexi_logger = "^0.5.1"
|
libc = "^0.2.23"
|
||||||
log = "^0.3.8"
|
log = "^0.3.8"
|
||||||
error-chain = { path = "3rdparty/error-chain" }
|
|
||||||
toml = "^0.4.2"
|
|
||||||
serde_derive = "^1.0.9"
|
|
||||||
serde = "^1.0.9"
|
serde = "^1.0.9"
|
||||||
xdg = "*"
|
serde_derive = "^1.0.9"
|
||||||
|
toml = "^0.4.2"
|
||||||
which = "*"
|
which = "*"
|
||||||
|
xdg = "*"
|
||||||
|
|
||||||
[dependencies.gtk]
|
[dependencies.gtk]
|
||||||
git = "https://github.com/gtk-rs/gtk.git"
|
git = "https://github.com/gtk-rs/gtk.git"
|
||||||
@ -33,12 +34,12 @@ git = "https://github.com/gtk-rs/gdk.git"
|
|||||||
features = [ "v3_10", "v3_12", "v3_22" ]
|
features = [ "v3_10", "v3_12", "v3_22" ]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 2 # controls the `--opt-level` the compiler builds with
|
opt-level = 0 # controls the `--opt-level` the compiler builds with
|
||||||
debug = true # controls whether the compiler passes `-C debuginfo`
|
debug = true # controls whether the compiler passes `-C debuginfo`
|
||||||
# a value of `true` is equivalent to `2`
|
# a value of `true` is equivalent to `2`
|
||||||
rpath = false # controls whether the compiler passes `-C rpath`
|
rpath = false # controls whether the compiler passes `-C rpath`
|
||||||
lto = false # controls `-C lto` for binaries and staticlibs
|
lto = false # controls `-C lto` for binaries and staticlibs
|
||||||
debug-assertions = true # controls whether debug assertions are enabled
|
debug-assertions = false # controls whether debug assertions are enabled
|
||||||
codegen-units = 1 # controls whether the compiler passes `-C codegen-units`
|
codegen-units = 1 # controls whether the compiler passes `-C codegen-units`
|
||||||
# `codegen-units` is ignored when `lto = true`
|
# `codegen-units` is ignored when `lto = true`
|
||||||
panic = 'unwind' # panic strategy (`-C panic=...`), can also be 'abort'
|
panic = 'unwind' # panic strategy (`-C panic=...`), can also be 'abort'
|
||||||
|
58
Makefile
Normal file
58
Makefile
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
INSTALL = install
|
||||||
|
INSTALL_DIR = $(INSTALL) -d
|
||||||
|
INSTALL_BIN = $(INSTALL) -m 755
|
||||||
|
INSTALL_DATA = $(INSTALL) -m 644
|
||||||
|
|
||||||
|
|
||||||
|
PREFIX=/usr/local
|
||||||
|
BINDIR=$(PREFIX)/bin
|
||||||
|
SHAREDIR=$(PREFIX)/share
|
||||||
|
DATADIR=$(SHAREDIR)/pnmixer
|
||||||
|
PIXMAPSDIR=$(DATADIR)/pixmaps
|
||||||
|
ICONSDIR=$(SHAREDIR)/icons/hicolor/128x128/apps
|
||||||
|
DESKTOPDIR=$(SHAREDIR)/applications
|
||||||
|
|
||||||
|
|
||||||
|
CARGO ?= cargo
|
||||||
|
CARGO_ARGS ?=
|
||||||
|
CARGO_BUILD_ARGS ?= --release
|
||||||
|
CARGO_BUILD ?= $(CARGO) $(CARGO_ARGS) build $(CARGO_BUILD_ARGS)
|
||||||
|
CARGO_INSTALL_ARGS ?= --root="$(DESTDIR)/$(PREFIX)"
|
||||||
|
CARGO_INSTALL ?= $(CARGO) $(CARGO_ARGS) install $(CARGO_INSTALL_ARGS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pnmixer-rs: Cargo.toml
|
||||||
|
PIXMAPSDIR=$(PIXMAPSDIR) $(CARGO_BUILD)
|
||||||
|
|
||||||
|
|
||||||
|
install: install-data
|
||||||
|
$(INSTALL_DIR) "$(DESTDIR)/$(BINDIR)"
|
||||||
|
$(INSTALL_BIN) target/release/pnmixer "$(DESTDIR)/$(BINDIR)/pnmixer"
|
||||||
|
|
||||||
|
|
||||||
|
install-data: install-pixmaps install-icons install-desktop
|
||||||
|
|
||||||
|
|
||||||
|
install-pixmaps:
|
||||||
|
$(INSTALL_DIR) "$(DESTDIR)/$(PIXMAPSDIR)"
|
||||||
|
$(INSTALL_DATA) data/pixmaps/pnmixer-about.png "$(DESTDIR)/$(PIXMAPSDIR)/pnmixer-about.png"
|
||||||
|
$(INSTALL_DATA) data/pixmaps/pnmixer-high.png "$(DESTDIR)/$(PIXMAPSDIR)/pnmixer-high.png"
|
||||||
|
$(INSTALL_DATA) data/pixmaps/pnmixer-low.png "$(DESTDIR)/$(PIXMAPSDIR)/pnmixer-low.png"
|
||||||
|
$(INSTALL_DATA) data/pixmaps/pnmixer-medium.png "$(DESTDIR)/$(PIXMAPSDIR)/pnmixer-medium.png"
|
||||||
|
$(INSTALL_DATA) data/pixmaps/pnmixer-muted.png "$(DESTDIR)/$(PIXMAPSDIR)/pnmixer-muted.png"
|
||||||
|
$(INSTALL_DATA) data/pixmaps/pnmixer-off.png "$(DESTDIR)/$(PIXMAPSDIR)/pnmixer-off.png"
|
||||||
|
|
||||||
|
|
||||||
|
install-icons:
|
||||||
|
$(INSTALL_DIR) "$(DESTDIR)/$(ICONSDIR)"
|
||||||
|
$(INSTALL_DATA) data/icons/pnmixer.png "$(DESTDIR)/$(ICONSDIR)/pnmixer.png"
|
||||||
|
|
||||||
|
|
||||||
|
install-desktop:
|
||||||
|
$(INSTALL_DIR) "$(DESTDIR)/$(DESKTOPDIR)"
|
||||||
|
$(INSTALL_DATA) data/desktop/pnmixer.desktop "$(DESTDIR)/$(DESKTOPDIR)/pnmixer.desktop"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: pnmixer-rs install install-data install-pixmaps install-icons install-desktop
|
@ -1,5 +1,5 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=PNMixer
|
Name=PNMixer-rs
|
||||||
_GenericName=System Tray Mixer
|
_GenericName=System Tray Mixer
|
||||||
_Comment=An audio mixer for the system tray
|
_Comment=An audio mixer for the system tray
|
||||||
Exec=pnmixer
|
Exec=pnmixer
|
@ -12,8 +12,6 @@
|
|||||||
<property name="destroy_with_parent">True</property>
|
<property name="destroy_with_parent">True</property>
|
||||||
<property name="icon_name">input-keyboard</property>
|
<property name="icon_name">input-keyboard</property>
|
||||||
<property name="type_hint">dialog</property>
|
<property name="type_hint">dialog</property>
|
||||||
<signal name="key-press-event" handler="on_hotkey_dialog_key_press_event" swapped="no"/>
|
|
||||||
<signal name="key-release-event" handler="on_hotkey_dialog_key_release_event" swapped="no"/>
|
|
||||||
<child internal-child="vbox">
|
<child internal-child="vbox">
|
||||||
<object class="GtkBox" id="dialog-vbox1">
|
<object class="GtkBox" id="dialog-vbox1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Mute/Unmute Volume</property>
|
<property name="tooltip_text" translatable="yes">Mute/Unmute Volume</property>
|
||||||
<signal name="activate" handler="on_mute_item_activate" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box0">
|
<object class="GtkBox" id="box0">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -71,7 +70,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Open Volume Control</property>
|
<property name="tooltip_text" translatable="yes">Open Volume Control</property>
|
||||||
<signal name="activate" handler="on_mixer_item_activate" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box1">
|
<object class="GtkBox" id="box1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -108,7 +106,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Preferences</property>
|
<property name="tooltip_text" translatable="yes">Preferences</property>
|
||||||
<signal name="activate" handler="on_prefs_item_activate" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box2">
|
<object class="GtkBox" id="box2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -146,7 +143,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Reload Sound</property>
|
<property name="tooltip_text" translatable="yes">Reload Sound</property>
|
||||||
<signal name="activate" handler="on_reload_item_activate" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box3">
|
<object class="GtkBox" id="box3">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -184,7 +180,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">About</property>
|
<property name="tooltip_text" translatable="yes">About</property>
|
||||||
<signal name="activate" handler="on_about_item_activate" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box4">
|
<object class="GtkBox" id="box4">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -229,7 +224,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Quit</property>
|
<property name="tooltip_text" translatable="yes">Quit</property>
|
||||||
<signal name="activate" handler="gtk_main_quit" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="box5">
|
<object class="GtkBox" id="box5">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
<property name="skip_taskbar_hint">True</property>
|
<property name="skip_taskbar_hint">True</property>
|
||||||
<property name="skip_pager_hint">True</property>
|
<property name="skip_pager_hint">True</property>
|
||||||
<property name="decorated">False</property>
|
<property name="decorated">False</property>
|
||||||
<signal name="button-press-event" handler="on_popup_window_event" swapped="no"/>
|
|
||||||
<signal name="grab-broken-event" handler="on_popup_window_event" swapped="no"/>
|
|
||||||
<signal name="key-press-event" handler="on_popup_window_event" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="vbox1">
|
<object class="GtkBox" id="vbox1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -36,7 +33,6 @@
|
|||||||
<property name="round_digits">0</property>
|
<property name="round_digits">0</property>
|
||||||
<property name="digits">0</property>
|
<property name="digits">0</property>
|
||||||
<property name="height_request">200</property>
|
<property name="height_request">200</property>
|
||||||
<signal name="value-changed" handler="on_vol_scale_value_changed" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
@ -58,7 +54,6 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_mute_check_toggled" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@ -73,7 +68,6 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<signal name="clicked" handler="on_mixer_button_clicked" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@ -69,7 +69,6 @@
|
|||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_noti_enable_check_toggled" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
@ -233,7 +232,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="GtkDialog" id="prefs_dialog">
|
<object class="GtkDialog" id="prefs_dialog">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">PNMixer Preferences</property>
|
<property name="title" translatable="yes">PNMixer-rs Preferences</property>
|
||||||
<property name="resizable">False</property>
|
<property name="resizable">False</property>
|
||||||
<property name="icon_name">preferences-system</property>
|
<property name="icon_name">preferences-system</property>
|
||||||
<property name="type_hint">dialog</property>
|
<property name="type_hint">dialog</property>
|
||||||
@ -447,7 +446,6 @@
|
|||||||
<object class="GtkComboBoxText" id="card_combo">
|
<object class="GtkComboBoxText" id="card_combo">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<signal name="changed" handler="on_card_combo_changed" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
@ -581,7 +579,6 @@
|
|||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_vol_meter_draw_check_toggled" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
@ -744,6 +741,35 @@
|
|||||||
<property name="top_attach">0</property>
|
<property name="top_attach">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label32">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="label" translatable="yes">Fine Scroll Step:</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="fine_scroll_step_spin">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="invisible_char">•</property>
|
||||||
|
<property name="text" translatable="yes">0,00</property>
|
||||||
|
<property name="primary_icon_activatable">False</property>
|
||||||
|
<property name="secondary_icon_activatable">False</property>
|
||||||
|
<property name="adjustment">fine_scroll_step_adjustment</property>
|
||||||
|
<property name="digits">2</property>
|
||||||
|
<property name="numeric">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child type="label">
|
<child type="label">
|
||||||
@ -805,7 +831,6 @@
|
|||||||
<object class="GtkComboBoxText" id="middle_click_combo">
|
<object class="GtkComboBoxText" id="middle_click_combo">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<signal name="changed" handler="on_middle_click_combo_changed" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
@ -891,7 +916,6 @@
|
|||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_hotkeys_enable_check_toggled" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@ -976,7 +1000,6 @@
|
|||||||
<object class="GtkEventBox" id="hotkeys_mute_eventbox">
|
<object class="GtkEventBox" id="hotkeys_mute_eventbox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<signal name="button-press-event" handler="on_hotkey_event_box_button_press_event" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="hotkeys_mute_label">
|
<object class="GtkLabel" id="hotkeys_mute_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -997,7 +1020,6 @@
|
|||||||
<object class="GtkEventBox" id="hotkeys_up_eventbox">
|
<object class="GtkEventBox" id="hotkeys_up_eventbox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<signal name="button-press-event" handler="on_hotkey_event_box_button_press_event" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="hotkeys_up_label">
|
<object class="GtkLabel" id="hotkeys_up_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -1018,7 +1040,6 @@
|
|||||||
<object class="GtkEventBox" id="hotkeys_down_eventbox">
|
<object class="GtkEventBox" id="hotkeys_down_eventbox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<signal name="button-press-event" handler="on_hotkey_event_box_button_press_event" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="hotkeys_down_label">
|
<object class="GtkLabel" id="hotkeys_down_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -233,6 +233,7 @@ extern "C" fn watch_cb(chan: *mut glib_sys::GIOChannel,
|
|||||||
|
|
||||||
let acard =
|
let acard =
|
||||||
unsafe { mem::transmute::<glib_sys::gpointer, &AlsaCard>(data) };
|
unsafe { mem::transmute::<glib_sys::gpointer, &AlsaCard>(data) };
|
||||||
|
let cb = &acard.cb;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mixer_ptr =
|
let mixer_ptr =
|
||||||
@ -261,15 +262,21 @@ extern "C" fn watch_cb(chan: *mut glib_sys::GIOChannel,
|
|||||||
glib_sys::G_IO_STATUS_AGAIN => {
|
glib_sys::G_IO_STATUS_AGAIN => {
|
||||||
debug!("G_IO_STATUS_AGAIN");
|
debug!("G_IO_STATUS_AGAIN");
|
||||||
continue;
|
continue;
|
||||||
}
|
},
|
||||||
// TODO: handle these failure cases
|
// TODO: handle these failure cases
|
||||||
glib_sys::G_IO_STATUS_NORMAL => debug!("G_IO_STATUS_NORMAL"),
|
glib_sys::G_IO_STATUS_NORMAL => {
|
||||||
glib_sys::G_IO_STATUS_ERROR => debug!("G_IO_STATUS_ERROR"),
|
error!("Alsa failed to clear the channel");
|
||||||
glib_sys::G_IO_STATUS_EOF => debug!("G_IO_STATUS_EOF"),
|
cb(AlsaEvent::AlsaCardError);
|
||||||
|
},
|
||||||
|
glib_sys::G_IO_STATUS_ERROR => (),
|
||||||
|
glib_sys::G_IO_STATUS_EOF => {
|
||||||
|
error!("GIO error has occurred");
|
||||||
|
cb(AlsaEvent::AlsaCardError);
|
||||||
|
},
|
||||||
|
_ => warn!("Unknown status from g_io_channel_read_chars()"),
|
||||||
}
|
}
|
||||||
return true as glib_sys::gboolean;
|
return true as glib_sys::gboolean;
|
||||||
}
|
}
|
||||||
let cb = &acard.cb;
|
|
||||||
cb(AlsaEvent::AlsaCardValuesChanged);
|
cb(AlsaEvent::AlsaCardValuesChanged);
|
||||||
|
|
||||||
return true as glib_sys::gboolean;
|
return true as glib_sys::gboolean;
|
||||||
|
@ -5,6 +5,7 @@ use prefs::*;
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use ui_entry::Gui;
|
use ui_entry::Gui;
|
||||||
use ui_prefs_dialog::show_prefs_dialog;
|
use ui_prefs_dialog::show_prefs_dialog;
|
||||||
|
use notif::*;
|
||||||
|
|
||||||
|
|
||||||
// TODO: notify popups
|
// TODO: notify popups
|
||||||
@ -17,6 +18,7 @@ pub struct AppS {
|
|||||||
_cant_construct: (),
|
_cant_construct: (),
|
||||||
pub gui: Gui,
|
pub gui: Gui,
|
||||||
pub audio: Audio,
|
pub audio: Audio,
|
||||||
|
pub notif: Notif,
|
||||||
pub prefs: RefCell<Prefs>,
|
pub prefs: RefCell<Prefs>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,11 +44,14 @@ impl AppS {
|
|||||||
.channel
|
.channel
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
|
let notif = Notif::new(&prefs.borrow());
|
||||||
|
|
||||||
return AppS {
|
return AppS {
|
||||||
_cant_construct: (),
|
_cant_construct: (),
|
||||||
gui: gui,
|
gui,
|
||||||
audio: Audio::new(Some(card_name), Some(chan_name)).unwrap(),
|
audio: Audio::new(Some(card_name), Some(chan_name)).unwrap(),
|
||||||
prefs: prefs,
|
notif,
|
||||||
|
prefs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,9 +69,4 @@ impl AppS {
|
|||||||
debug!("Update PopupWindow!");
|
debug!("Update PopupWindow!");
|
||||||
return self.gui.popup_window.update(&self.audio);
|
return self.gui.popup_window.update(&self.audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
pub fn show_preferences(&self) {
|
|
||||||
// show_prefs_dialog(self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
52
src/audio.rs
52
src/audio.rs
@ -90,9 +90,22 @@ impl Audio {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let acard = AlsaCard::new(card_name, elem_name, cb);
|
||||||
|
|
||||||
|
/* additionally dispatch signals */
|
||||||
|
if acard.is_err() {
|
||||||
|
invoke_handlers(&handlers.borrow(),
|
||||||
|
AudioSignal::NoCard,
|
||||||
|
AudioUser::Unknown);
|
||||||
|
} else {
|
||||||
|
invoke_handlers(&handlers.borrow(),
|
||||||
|
AudioSignal::CardInitialized,
|
||||||
|
AudioUser::Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
let audio = Audio {
|
let audio = Audio {
|
||||||
_cannot_construct: (),
|
_cannot_construct: (),
|
||||||
acard: RefCell::new(AlsaCard::new(card_name, elem_name, cb)?),
|
acard: RefCell::new(acard?),
|
||||||
last_action_timestamp: last_action_timestamp.clone(),
|
last_action_timestamp: last_action_timestamp.clone(),
|
||||||
handlers: handlers.clone(),
|
handlers: handlers.clone(),
|
||||||
scroll_step: Cell::new(5),
|
scroll_step: Cell::new(5),
|
||||||
@ -126,17 +139,10 @@ impl Audio {
|
|||||||
let mut ac = self.acard.borrow_mut();
|
let mut ac = self.acard.borrow_mut();
|
||||||
*ac = AlsaCard::new(card_name, elem_name, cb)?;
|
*ac = AlsaCard::new(card_name, elem_name, cb)?;
|
||||||
}
|
}
|
||||||
debug!("Old card name: {}",
|
|
||||||
self.acard
|
|
||||||
.borrow()
|
|
||||||
.card_name()
|
|
||||||
.unwrap());
|
|
||||||
debug!("Old chan name: {}",
|
|
||||||
self.acard
|
|
||||||
.borrow()
|
|
||||||
.chan_name()
|
|
||||||
.unwrap());
|
|
||||||
|
|
||||||
|
// invoke_handlers(&self.handlers.borrow(),
|
||||||
|
// AudioSignal::CardCleanedUp,
|
||||||
|
// user);
|
||||||
invoke_handlers(&self.handlers.borrow(),
|
invoke_handlers(&self.handlers.borrow(),
|
||||||
AudioSignal::CardInitialized,
|
AudioSignal::CardInitialized,
|
||||||
user);
|
user);
|
||||||
@ -216,9 +222,6 @@ impl Audio {
|
|||||||
|
|
||||||
self.set_vol(new_vol, user)?;
|
self.set_vol(new_vol, user)?;
|
||||||
|
|
||||||
invoke_handlers(&self.handlers.borrow(),
|
|
||||||
AudioSignal::ValuesChanged,
|
|
||||||
user);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,9 +248,6 @@ impl Audio {
|
|||||||
|
|
||||||
self.set_vol(new_vol, user)?;
|
self.set_vol(new_vol, user)?;
|
||||||
|
|
||||||
invoke_handlers(&self.handlers.borrow(),
|
|
||||||
AudioSignal::ValuesChanged,
|
|
||||||
user);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +307,11 @@ fn invoke_handlers(handlers: &Vec<Box<Fn(AudioSignal, AudioUser)>>,
|
|||||||
debug!("Invoking handlers for signal {:?} by user {:?}",
|
debug!("Invoking handlers for signal {:?} by user {:?}",
|
||||||
signal,
|
signal,
|
||||||
user);
|
user);
|
||||||
|
if handlers.is_empty() {
|
||||||
|
debug!("No handler found");
|
||||||
|
} else {
|
||||||
|
debug!("Executing handlers")
|
||||||
|
}
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let unboxed = handler.as_ref();
|
let unboxed = handler.as_ref();
|
||||||
unboxed(signal, user);
|
unboxed(signal, user);
|
||||||
@ -332,10 +337,17 @@ fn on_alsa_event(last_action_timestamp: &mut i64,
|
|||||||
/* external change */
|
/* external change */
|
||||||
match alsa_event {
|
match alsa_event {
|
||||||
// TODO: invoke handlers with AudioUserUnknown
|
// TODO: invoke handlers with AudioUserUnknown
|
||||||
AlsaEvent::AlsaCardError => debug!("AlsaCardError"),
|
AlsaEvent::AlsaCardError => {
|
||||||
AlsaEvent::AlsaCardDiconnected => debug!("AlsaCardDiconnected"),
|
invoke_handlers(handlers,
|
||||||
|
self::AudioSignal::CardError,
|
||||||
|
self::AudioUser::Unknown);
|
||||||
|
},
|
||||||
|
AlsaEvent::AlsaCardDiconnected => {
|
||||||
|
invoke_handlers(handlers,
|
||||||
|
self::AudioSignal::CardDisconnected,
|
||||||
|
self::AudioUser::Unknown);
|
||||||
|
},
|
||||||
AlsaEvent::AlsaCardValuesChanged => {
|
AlsaEvent::AlsaCardValuesChanged => {
|
||||||
debug!("AlsaCardValuesChanged");
|
|
||||||
invoke_handlers(handlers,
|
invoke_handlers(handlers,
|
||||||
self::AudioSignal::ValuesChanged,
|
self::AudioSignal::ValuesChanged,
|
||||||
self::AudioUser::Unknown);
|
self::AudioUser::Unknown);
|
||||||
|
@ -20,6 +20,7 @@ extern crate gdk;
|
|||||||
extern crate gdk_pixbuf;
|
extern crate gdk_pixbuf;
|
||||||
extern crate gdk_pixbuf_sys;
|
extern crate gdk_pixbuf_sys;
|
||||||
extern crate gdk_sys;
|
extern crate gdk_sys;
|
||||||
|
extern crate gio;
|
||||||
extern crate glib;
|
extern crate glib;
|
||||||
extern crate glib_sys;
|
extern crate glib_sys;
|
||||||
extern crate gobject_sys;
|
extern crate gobject_sys;
|
||||||
|
@ -122,6 +122,7 @@ impl Default for VolColor {
|
|||||||
pub struct BehaviorPrefs {
|
pub struct BehaviorPrefs {
|
||||||
pub vol_control_cmd: Option<String>,
|
pub vol_control_cmd: Option<String>,
|
||||||
pub vol_scroll_step: f64,
|
pub vol_scroll_step: f64,
|
||||||
|
pub vol_fine_scroll_step: f64,
|
||||||
pub middle_click_action: MiddleClickAction,
|
pub middle_click_action: MiddleClickAction,
|
||||||
pub custom_command: Option<String>, // TODO: fine scroll step?
|
pub custom_command: Option<String>, // TODO: fine scroll step?
|
||||||
}
|
}
|
||||||
@ -131,6 +132,7 @@ impl Default for BehaviorPrefs {
|
|||||||
return BehaviorPrefs {
|
return BehaviorPrefs {
|
||||||
vol_control_cmd: None,
|
vol_control_cmd: None,
|
||||||
vol_scroll_step: 5.0,
|
vol_scroll_step: 5.0,
|
||||||
|
vol_fine_scroll_step: 1.0,
|
||||||
middle_click_action: MiddleClickAction::default(),
|
middle_click_action: MiddleClickAction::default(),
|
||||||
custom_command: None,
|
custom_command: None,
|
||||||
};
|
};
|
||||||
|
@ -43,16 +43,28 @@ pub fn pixbuf_new_from_theme(icon_name: &str,
|
|||||||
|
|
||||||
pub fn pixbuf_new_from_file(filename: &str) -> Result<gdk_pixbuf::Pixbuf> {
|
pub fn pixbuf_new_from_file(filename: &str) -> Result<gdk_pixbuf::Pixbuf> {
|
||||||
ensure!(!filename.is_empty(), "Filename is empty");
|
ensure!(!filename.is_empty(), "Filename is empty");
|
||||||
|
let mut syspath = String::new();
|
||||||
|
let sysdir = option_env!("PIXMAPSDIR").map(|s|{
|
||||||
|
syspath = format!("{}/{}", s, filename);
|
||||||
|
Path::new(syspath.as_str())
|
||||||
|
});
|
||||||
|
let cargopath = format!("./data/pixmaps/{}",
|
||||||
|
filename);
|
||||||
|
let cargodir = Path::new(cargopath.as_str());
|
||||||
|
|
||||||
let s = format!("{}/data/pixmaps/{}", env!("CARGO_MANIFEST_DIR"), filename);
|
// prefer local dir
|
||||||
let path = Path::new(s.as_str());
|
let final_dir = {
|
||||||
|
if cargodir.exists() {
|
||||||
if path.exists() {
|
cargodir
|
||||||
let str_path = path.to_str().ok_or("Path is not valid unicode")?;
|
} else if sysdir.is_some() && sysdir.unwrap().exists() {
|
||||||
|
sysdir.unwrap()
|
||||||
|
} else {
|
||||||
|
bail!("No valid path found")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let str_path = final_dir.to_str().ok_or("Path is not valid unicode")?;
|
||||||
|
debug!("Loading icon from {}", str_path);
|
||||||
// TODO: propagate error
|
// TODO: propagate error
|
||||||
return Ok(gdk_pixbuf::Pixbuf::new_from_file(str_path).unwrap());
|
return Ok(gdk_pixbuf::Pixbuf::new_from_file(str_path).unwrap());
|
||||||
} else {
|
|
||||||
bail!("Uh-oh");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
use app_state::*;
|
use app_state::*;
|
||||||
|
use audio::{AudioUser, AudioSignal};
|
||||||
|
use gtk::DialogExt;
|
||||||
|
use gtk::MessageDialogExt;
|
||||||
|
use gtk::WidgetExt;
|
||||||
|
use gtk::WindowExt;
|
||||||
use gtk;
|
use gtk;
|
||||||
|
use gtk_sys::{GTK_DIALOG_DESTROY_WITH_PARENT, GTK_RESPONSE_YES};
|
||||||
|
use notif::*;
|
||||||
use prefs::*;
|
use prefs::*;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use support_audio::*;
|
||||||
use ui_popup_menu::*;
|
use ui_popup_menu::*;
|
||||||
use ui_popup_window::*;
|
use ui_popup_window::*;
|
||||||
use ui_prefs_dialog::*;
|
use ui_prefs_dialog::*;
|
||||||
use ui_tray_icon::*;
|
use ui_tray_icon::*;
|
||||||
use audio::{AudioUser, AudioSignal};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -39,16 +46,25 @@ impl Gui {
|
|||||||
|
|
||||||
pub fn init(appstate: Rc<AppS>) {
|
pub fn init(appstate: Rc<AppS>) {
|
||||||
{
|
{
|
||||||
|
/* "global" audio signal handler */
|
||||||
let apps = appstate.clone();
|
let apps = appstate.clone();
|
||||||
appstate.audio.connect_handler(
|
appstate.audio.connect_handler(
|
||||||
Box::new(move |s, u| match (s, u) {
|
Box::new(move |s, u| match (s, u) {
|
||||||
(AudioSignal::ValuesChanged, AudioUser::Unknown) => {
|
(AudioSignal::CardDisconnected, _) => {
|
||||||
debug!("Appstate references: {}!", Rc::strong_count(&apps));
|
try_w!(audio_reload(&apps.audio,
|
||||||
|
&apps.prefs.borrow(),
|
||||||
|
AudioUser::Unknown));
|
||||||
|
},
|
||||||
|
(AudioSignal::CardError, _) => {
|
||||||
|
if run_audio_error_dialog(&apps.gui.popup_menu.menu_window) == (GTK_RESPONSE_YES as i32) {
|
||||||
|
try_w!(audio_reload(&apps.audio,
|
||||||
|
&apps.prefs.borrow(),
|
||||||
|
AudioUser::Unknown));
|
||||||
}
|
}
|
||||||
_ => debug!("Nix"),
|
},
|
||||||
}),
|
_ => (),
|
||||||
);
|
}
|
||||||
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,3 +73,28 @@ pub fn init(appstate: Rc<AppS>) {
|
|||||||
init_popup_menu(appstate.clone());
|
init_popup_menu(appstate.clone());
|
||||||
init_prefs_callback(appstate.clone());
|
init_prefs_callback(appstate.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn run_audio_error_dialog(parent: >k::Window) -> i32 {
|
||||||
|
error!("Connection with audio failed, you probably need to restart pnmixer.");
|
||||||
|
|
||||||
|
let dialog = gtk::MessageDialog::new(
|
||||||
|
Some(parent),
|
||||||
|
gtk::DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
gtk::MessageType::Error,
|
||||||
|
gtk::ButtonsType::YesNo,
|
||||||
|
"Warning: Connection to sound system failed."
|
||||||
|
);
|
||||||
|
dialog.set_property_secondary_text(Some("Do you want to re-initialize the audio connection ?
|
||||||
|
|
||||||
|
If you do not, you will either need to restart PNMixer
|
||||||
|
or select the 'Reload Audio' option in the right-click
|
||||||
|
menu in order for PNMixer to function."));
|
||||||
|
|
||||||
|
dialog.set_title("PNMixer-rs Error");
|
||||||
|
|
||||||
|
let resp = dialog.run();
|
||||||
|
dialog.destroy();
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
@ -127,7 +127,7 @@ fn create_about_dialog() -> gtk::AboutDialog {
|
|||||||
let about_dialog: gtk::AboutDialog = gtk::AboutDialog::new();
|
let about_dialog: gtk::AboutDialog = gtk::AboutDialog::new();
|
||||||
|
|
||||||
about_dialog.set_license(Some(
|
about_dialog.set_license(Some(
|
||||||
"PNMixer is free software; you can redistribute it and/or modify it
|
"PNMixer-rs is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License v3 as published
|
under the terms of the GNU General Public License v3 as published
|
||||||
by the Free Software Foundation.
|
by the Free Software Foundation.
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.",
|
|||||||
about_dialog.set_copyright(Some("Copyright © 2017 Julian Ospald"));
|
about_dialog.set_copyright(Some("Copyright © 2017 Julian Ospald"));
|
||||||
about_dialog.set_authors(&["Julian Ospald"]);
|
about_dialog.set_authors(&["Julian Ospald"]);
|
||||||
about_dialog.set_artists(&["Paul Davey"]);
|
about_dialog.set_artists(&["Paul Davey"]);
|
||||||
about_dialog.set_program_name("pnmixer-rs");
|
about_dialog.set_program_name("PNMixer-rs");
|
||||||
about_dialog.set_logo_icon_name("pnmixer");
|
about_dialog.set_logo_icon_name("pnmixer");
|
||||||
about_dialog.set_version(VERSION);
|
about_dialog.set_version(VERSION);
|
||||||
about_dialog.set_website("https://github.com/hasufell/pnmixer-rust");
|
about_dialog.set_website("https://github.com/hasufell/pnmixer-rust");
|
||||||
|
@ -9,6 +9,7 @@ use glib;
|
|||||||
use gtk::ToggleButtonExt;
|
use gtk::ToggleButtonExt;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk;
|
use gtk;
|
||||||
|
use prefs::*;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use support_cmd::*;
|
use support_cmd::*;
|
||||||
@ -71,6 +72,13 @@ impl PopupWindow {
|
|||||||
glib::signal_handler_unblock(&self.mute_check,
|
glib::signal_handler_unblock(&self.mute_check,
|
||||||
self.toggle_signal.get());
|
self.toggle_signal.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_vol_increment(&self, prefs: &Prefs) {
|
||||||
|
self.vol_scale_adj
|
||||||
|
.set_page_increment(prefs.behavior_prefs.vol_scroll_step);
|
||||||
|
self.vol_scale_adj
|
||||||
|
.set_step_increment(prefs.behavior_prefs.vol_fine_scroll_step);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -104,7 +112,6 @@ pub fn init_popup_window(appstate: Rc<AppS>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mute_check.connect_toggled */
|
/* mute_check.connect_toggled */
|
||||||
@ -174,6 +181,7 @@ pub fn init_popup_window(appstate: Rc<AppS>) {
|
|||||||
|
|
||||||
|
|
||||||
fn on_popup_window_show(appstate: &AppS) {
|
fn on_popup_window_show(appstate: &AppS) {
|
||||||
|
appstate.gui.popup_window.set_vol_increment(&appstate.prefs.borrow());
|
||||||
try_w!(appstate.gui.popup_window.update(&appstate.audio));
|
try_w!(appstate.gui.popup_window.update(&appstate.audio));
|
||||||
appstate.gui
|
appstate.gui
|
||||||
.popup_window
|
.popup_window
|
||||||
|
@ -6,7 +6,6 @@ use gtk::ResponseType;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk;
|
use gtk;
|
||||||
use prefs::*;
|
use prefs::*;
|
||||||
use std::mem;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use support_alsa::*;
|
use support_alsa::*;
|
||||||
use support_audio::*;
|
use support_audio::*;
|
||||||
@ -34,6 +33,7 @@ pub struct PrefsDialog {
|
|||||||
/* BehaviorPrefs */
|
/* BehaviorPrefs */
|
||||||
vol_control_entry: gtk::Entry,
|
vol_control_entry: gtk::Entry,
|
||||||
scroll_step_spin: gtk::SpinButton,
|
scroll_step_spin: gtk::SpinButton,
|
||||||
|
fine_scroll_step_spin: gtk::SpinButton,
|
||||||
middle_click_combo: gtk::ComboBoxText,
|
middle_click_combo: gtk::ComboBoxText,
|
||||||
custom_entry: gtk::Entry,
|
custom_entry: gtk::Entry,
|
||||||
|
|
||||||
@ -68,6 +68,8 @@ impl PrefsDialog {
|
|||||||
|
|
||||||
vol_control_entry: builder.get_object("vol_control_entry").unwrap(),
|
vol_control_entry: builder.get_object("vol_control_entry").unwrap(),
|
||||||
scroll_step_spin: builder.get_object("scroll_step_spin").unwrap(),
|
scroll_step_spin: builder.get_object("scroll_step_spin").unwrap(),
|
||||||
|
fine_scroll_step_spin: builder.get_object("fine_scroll_step_spin")
|
||||||
|
.unwrap(),
|
||||||
middle_click_combo: builder.get_object("middle_click_combo")
|
middle_click_combo: builder.get_object("middle_click_combo")
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
custom_entry: builder.get_object("custom_entry").unwrap(),
|
custom_entry: builder.get_object("custom_entry").unwrap(),
|
||||||
@ -113,6 +115,8 @@ impl PrefsDialog {
|
|||||||
.unwrap_or(&String::from(""))
|
.unwrap_or(&String::from(""))
|
||||||
.as_str());
|
.as_str());
|
||||||
self.scroll_step_spin.set_value(prefs.behavior_prefs.vol_scroll_step);
|
self.scroll_step_spin.set_value(prefs.behavior_prefs.vol_scroll_step);
|
||||||
|
self.fine_scroll_step_spin
|
||||||
|
.set_value(prefs.behavior_prefs.vol_fine_scroll_step);
|
||||||
|
|
||||||
// TODO: make sure these values always match, must be a better way
|
// TODO: make sure these values always match, must be a better way
|
||||||
// also check to_prefs()
|
// also check to_prefs()
|
||||||
@ -184,6 +188,7 @@ impl PrefsDialog {
|
|||||||
let behavior_prefs = BehaviorPrefs {
|
let behavior_prefs = BehaviorPrefs {
|
||||||
vol_control_cmd,
|
vol_control_cmd,
|
||||||
vol_scroll_step: self.scroll_step_spin.get_value(),
|
vol_scroll_step: self.scroll_step_spin.get_value(),
|
||||||
|
vol_fine_scroll_step: self.fine_scroll_step_spin.get_value(),
|
||||||
middle_click_action: self.middle_click_combo.get_active().into(),
|
middle_click_action: self.middle_click_combo.get_active().into(),
|
||||||
custom_command,
|
custom_command,
|
||||||
};
|
};
|
||||||
@ -234,6 +239,11 @@ pub fn show_prefs_dialog(appstate: &Rc<AppS>) {
|
|||||||
pub fn init_prefs_callback(appstate: Rc<AppS>) {
|
pub fn init_prefs_callback(appstate: Rc<AppS>) {
|
||||||
let apps = appstate.clone();
|
let apps = appstate.clone();
|
||||||
appstate.audio.connect_handler(Box::new(move |s, u| {
|
appstate.audio.connect_handler(Box::new(move |s, u| {
|
||||||
|
/* skip if prefs window is not present */
|
||||||
|
if apps.gui.prefs_dialog.borrow().is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
match (s, u) {
|
match (s, u) {
|
||||||
(AudioSignal::CardInitialized, _) => (),
|
(AudioSignal::CardInitialized, _) => (),
|
||||||
(AudioSignal::CardCleanedUp, _) => {
|
(AudioSignal::CardCleanedUp, _) => {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
use app_state::*;
|
use app_state::*;
|
||||||
use audio::*;
|
use audio::*;
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
use glib;
|
||||||
|
use gio;
|
||||||
use gdk;
|
use gdk;
|
||||||
use gdk_pixbuf;
|
use gdk_pixbuf;
|
||||||
use gdk_pixbuf_sys::GDK_COLORSPACE_RGB;
|
use gdk_pixbuf_sys;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk;
|
use gtk;
|
||||||
use prefs::{Prefs, MiddleClickAction};
|
use prefs::{Prefs, MiddleClickAction};
|
||||||
@ -12,6 +14,7 @@ use std::cell::RefCell;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use support_cmd::*;
|
use support_cmd::*;
|
||||||
use support_ui::*;
|
use support_ui::*;
|
||||||
|
use ui_prefs_dialog::show_prefs_dialog;
|
||||||
|
|
||||||
|
|
||||||
// TODO tooltip
|
// TODO tooltip
|
||||||
@ -78,6 +81,36 @@ impl TrayIcon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn update_tooltip(&self, audio: &Audio) {
|
||||||
|
let cardname = audio.acard
|
||||||
|
.borrow()
|
||||||
|
.card_name()
|
||||||
|
.unwrap_or(String::from("Unknown card"));
|
||||||
|
let channame = audio.acard
|
||||||
|
.borrow()
|
||||||
|
.chan_name()
|
||||||
|
.unwrap_or(String::from("unknown channel"));
|
||||||
|
let vol = audio.vol()
|
||||||
|
.map(|s| format!("{}", s.round()))
|
||||||
|
.unwrap_or(String::from("unknown volume"));
|
||||||
|
let mute_info = {
|
||||||
|
if !audio.has_mute() {
|
||||||
|
"\nNo mute switch"
|
||||||
|
} else if audio.get_mute().unwrap_or(false) {
|
||||||
|
"\nMuted"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.status_icon.set_tooltip_text(format!("{} ({})\nVolume: {}{}",
|
||||||
|
cardname,
|
||||||
|
channame,
|
||||||
|
vol,
|
||||||
|
mute_info)
|
||||||
|
.as_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn update_all(&self,
|
pub fn update_all(&self,
|
||||||
prefs: &Prefs,
|
prefs: &Prefs,
|
||||||
audio: &Audio,
|
audio: &Audio,
|
||||||
@ -104,6 +137,7 @@ impl TrayIcon {
|
|||||||
*self.volmeter.borrow_mut() = Some(volmeter);
|
*self.volmeter.borrow_mut() = Some(volmeter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.update_tooltip(&audio);
|
||||||
return self.update_pixbuf(audio.vol()?, audio.vol_level());
|
return self.update_pixbuf(audio.vol()?, audio.vol_level());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,7 +176,7 @@ impl VolMeter {
|
|||||||
pixbuf: &gdk_pixbuf::Pixbuf)
|
pixbuf: &gdk_pixbuf::Pixbuf)
|
||||||
-> Result<gdk_pixbuf::Pixbuf> {
|
-> Result<gdk_pixbuf::Pixbuf> {
|
||||||
|
|
||||||
ensure!(pixbuf.get_colorspace() == GDK_COLORSPACE_RGB,
|
ensure!(pixbuf.get_colorspace() == gdk_pixbuf_sys::GDK_COLORSPACE_RGB,
|
||||||
"Invalid colorspace in pixbuf");
|
"Invalid colorspace in pixbuf");
|
||||||
ensure!(pixbuf.get_bits_per_sample() == 8,
|
ensure!(pixbuf.get_bits_per_sample() == 8,
|
||||||
"Invalid bits per sample in pixbuf");
|
"Invalid bits per sample in pixbuf");
|
||||||
@ -310,6 +344,7 @@ pub fn init_tray_icon(appstate: Rc<AppS>) {
|
|||||||
let apps = appstate.clone();
|
let apps = appstate.clone();
|
||||||
appstate.audio.connect_handler(Box::new(move |s, u| match (s, u) {
|
appstate.audio.connect_handler(Box::new(move |s, u| match (s, u) {
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
|
apps.gui.tray_icon.update_tooltip(&apps.audio);
|
||||||
try_w!(apps.gui.tray_icon.update_audio(&apps.audio));
|
try_w!(apps.gui.tray_icon.update_audio(&apps.audio));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -400,7 +435,7 @@ fn on_tray_icon_scroll_event(appstate: &AppS,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn on_tray_button_release_event(appstate: &AppS,
|
fn on_tray_button_release_event(appstate: &Rc<AppS>,
|
||||||
event_button: &gdk::EventButton)
|
event_button: &gdk::EventButton)
|
||||||
-> bool {
|
-> bool {
|
||||||
let button = event_button.get_button();
|
let button = event_button.get_button();
|
||||||
@ -421,7 +456,8 @@ fn on_tray_button_release_event(appstate: &AppS,
|
|||||||
try_wr!(audio.toggle_mute(AudioUser::Popup), false);
|
try_wr!(audio.toggle_mute(AudioUser::Popup), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&MiddleClickAction::ShowPreferences => (),
|
// TODO
|
||||||
|
&MiddleClickAction::ShowPreferences => show_prefs_dialog(&appstate),
|
||||||
&MiddleClickAction::VolumeControl => {
|
&MiddleClickAction::VolumeControl => {
|
||||||
try_wr!(execute_vol_control_command(&appstate.prefs.borrow()),
|
try_wr!(execute_vol_control_command(&appstate.prefs.borrow()),
|
||||||
false);
|
false);
|
||||||
|
Loading…
Reference in New Issue
Block a user