diff --git a/wingpanel/schemas/io.elementary.desktop.wingpanel.gschema.xml b/wingpanel-qq/schemas/io.elementary.desktop.wingpanel.gschema.xml
index c81abd5..890e277 100644
--- a/wingpanel/schemas/io.elementary.desktop.wingpanel.gschema.xml
+++ b/wingpanel-qq/schemas/io.elementary.desktop.wingpanel.gschema.xml
@@ -6,5 +6,23 @@
Sets if the panel uses transparency.
Disable this to provide higher contrasts and make indicators better readable.
+
+
+
+
+
+
+
+
+ 'Disabled'
+ Sets if and how the panel will autohide.
+ Enable this to increase available desktop area and reduce clutter.
+
+
+
+ 200
+ Sets how long before the panel will autohide in milliseconds.
+ Increase or decrease this value to your preference.
+
diff --git a/wingpanel/src/PanelWindow.vala b/wingpanel-qq/src/PanelWindow.vala
index c48b5ea..81ec2f2 100644
--- a/wingpanel/src/PanelWindow.vala
+++ b/wingpanel-qq/src/PanelWindow.vala
@@ -21,6 +21,9 @@ public class Wingpanel.PanelWindow : Gtk.Window {
public Services.PopoverManager popover_manager;
private Widgets.Panel panel;
+
+ uint timeout;
+
private int monitor_number;
private int monitor_width;
private int monitor_height;
@@ -30,6 +33,11 @@ public class Wingpanel.PanelWindow : Gtk.Window {
private bool expanded = false;
private int panel_displacement;
private uint shrink_timeout = 0;
+ private bool hiding = false;
+ private bool strut = true;
+ private string autohide = Services.PanelSettings.get_default ().autohide;
+ private int autohide_delay = Services.PanelSettings.get_default ().delay;
+ private Wnck.Screen wnck_screen = Wnck.Screen.get_default ();
public PanelWindow (Gtk.Application application) {
Object (
@@ -71,17 +79,40 @@ public class Wingpanel.PanelWindow : Gtk.Window {
application.add_accelerator ("Tab", "app.cycle", null);
application.add_accelerator ("Tab", "app.cycle-back", null);
+ Services.PanelSettings.get_default ().notify["autohide"].connect (() => {
+ autohide = Services.PanelSettings.get_default ().autohide;
+ update_autohide_mode ();
+ });
+
+ Services.PanelSettings.get_default ().notify["delay"].connect (() => {
+ autohide_delay = Services.PanelSettings.get_default ().delay;
+ });
+
add (panel);
}
private bool animation_step () {
- if (panel_displacement <= panel_height * (-1)) {
- return false;
+ if (hiding) {
+ if (panel_displacement >= -1 || popover_manager.current_indicator != null) {
+ timeout = 0;
+ if (strut == true) {
+ update_panel_dimensions ();
+ }
+ return false;
+ }
+ panel_displacement++;
+ } else {
+ if (panel_displacement <= panel_height * (-1)) {
+ timeout = 0;
+ if (strut == true) {
+ update_panel_dimensions ();
+ }
+ return false;
+ }
+ panel_displacement--;
}
- panel_displacement--;
-
- update_panel_dimensions ();
+ animate_panel ();
return true;
}
@@ -91,7 +115,174 @@ public class Wingpanel.PanelWindow : Gtk.Window {
Services.BackgroundManager.initialize (this.monitor_number, panel_height);
- Timeout.add (300 / panel_height, animation_step);
+ update_autohide_mode ();
+ }
+
+ private void active_window_changed (Wnck.Window? prev_active_window) {
+ unowned Wnck.Window? active_window = wnck_screen.get_active_window();
+ if (autohide == "Dodge" || autohide == "Dodge-Float")
+ update_visibility_active_change (active_window);
+
+ if (prev_active_window != null)
+ prev_active_window.state_changed.disconnect (active_window_state_changed);
+ if (active_window != null)
+ active_window.state_changed.connect (active_window_state_changed);
+ }
+
+ private void active_workspace_changed (Wnck.Workspace? prev_active_workspace) {
+ unowned Wnck.Window? active_window = wnck_screen.get_active_window();
+ if (autohide == "Dodge" || autohide == "Dodge-Float")
+ update_visibility_active_change (active_window);
+ }
+
+ private void viewports_changed (Wnck.Screen? screen) {
+ unowned Wnck.Window? active_window = wnck_screen.get_active_window();
+ if (autohide == "Dodge" || autohide == "Dodge-Float")
+ update_visibility_active_change (active_window);
+ }
+
+ private void active_window_state_changed (Wnck.Window? window,
+ Wnck.WindowState changed_mask, Wnck.WindowState new_state) {
+ if (autohide == "Dodge" || autohide == "Dodge-Float")
+ update_visibility_active_change (window);
+ }
+
+ private void update_visibility_active_change (Wnck.Window? active_window) {
+ if (should_hide_active_change (active_window)) {
+ hide_panel ();
+ } else {
+ show_panel ();
+ }
+ }
+
+ private bool should_hide_active_change (Wnck.Window? active_window) {
+ unowned Wnck.Workspace active_workspace = wnck_screen.get_active_workspace ();
+
+ return ((active_window != null) && !active_window.is_minimized () && right_type (active_window)
+ && active_window.is_visible_on_workspace (active_workspace)
+ && active_window.is_in_viewport (active_workspace)
+ && (active_window.get_window_type () == Wnck.WindowType.DIALOG) ?
+ would_intersect_shown_panel (active_window) :
+ (in_panel_x_range (active_window) && is_maximized_at_all (active_window)));
+ }
+
+ private bool would_intersect_shown_panel (Wnck.Window? window) {
+ Gdk.Rectangle shown_panel_rect = Gdk.Rectangle ();
+ shown_panel_rect.x = monitor_x;
+ shown_panel_rect.y = monitor_y;
+ shown_panel_rect.width = monitor_width;
+ shown_panel_rect.height = panel_height;
+
+ int xp, yp, widthp, heightp;
+ window.get_geometry (out xp, out yp, out widthp, out heightp);
+
+ Gdk.Rectangle window_rect = Gdk.Rectangle ();
+ window_rect.x = xp;
+ window_rect.width = widthp;
+ if (strut && is_maximized_at_all (window)) {
+ window_rect.y = yp - panel_height;
+ window_rect.height = heightp + panel_height;
+ } else {
+ window_rect.y = yp;
+ window_rect.height = heightp;
+ }
+
+ return window_rect.intersect (shown_panel_rect, null);
+ }
+
+ private bool in_panel_x_range (Wnck.Window? window) {
+ int xp, yp, widthp, heightp;
+ window.get_geometry (out xp, out yp, out widthp, out heightp);
+ if (xp > monitor_x)
+ return (monitor_x + monitor_width > xp);
+ else if (xp < monitor_x)
+ return (xp + widthp > monitor_x);
+ else
+ return (xp + widthp > 0 && monitor_x + monitor_width > 0);
+ }
+
+ private bool right_type (Wnck.Window? active_window) {
+ unowned Wnck.WindowType type = active_window.get_window_type ();
+ return (type == Wnck.WindowType.NORMAL || type == Wnck.WindowType.DIALOG
+ || type == Wnck.WindowType.TOOLBAR || type == Wnck.WindowType.UTILITY);
+ }
+
+ private bool is_maximized_at_all (Wnck.Window window) {
+ return (window.is_maximized_horizontally ()
+ || window.is_maximized_vertically ()
+ || window.is_fullscreen ());
+ }
+
+ private bool hide_panel () {
+ if (timeout > 0) {
+ Source.remove (timeout);
+ }
+ if (autohide == "Dodge" || autohide == "Dodge-Float") {
+ if (!should_hide_active_change (wnck_screen.get_active_window())) {
+ return true;
+ }
+ }
+ if (popover_manager.current_indicator == null) {
+ Thread.usleep (autohide_delay * 1000);
+ }
+ strut = true;
+ hiding = true;
+ timeout = Timeout.add (100 / panel_height, animation_step);
+ return true;
+ }
+
+ private bool show_panel () {
+ if (timeout > 0) {
+ Source.remove (timeout);
+ }
+ if (popover_manager.current_indicator == null && autohide != "Disabled") {
+ Thread.usleep (autohide_delay * 1000);
+ }
+ if (autohide == "Dodge-Float" || autohide == "Float") {
+ strut = false;
+ } else {
+ strut = true;
+ }
+ hiding = false;
+ if (autohide == "Disabled") {
+ timeout = Timeout.add (300 / panel_height, animation_step);
+ } else {
+ timeout = Timeout.add (100 / panel_height, animation_step);
+ }
+ return true;
+ }
+
+ private void update_autohide_mode () {
+ switch (autohide) {
+ case "Disabled":
+ this.enter_notify_event.disconnect (show_panel);
+ this.motion_notify_event.disconnect (show_panel);
+ this.leave_notify_event.disconnect (hide_panel);
+ wnck_screen.active_window_changed.disconnect (active_window_changed);
+ wnck_screen.active_workspace_changed.disconnect (active_workspace_changed);
+ wnck_screen.viewports_changed.disconnect (viewports_changed);
+ show_panel ();
+ break;
+ case "Dodge":
+ case "Dodge-Float":
+ this.enter_notify_event.connect (show_panel);
+ this.motion_notify_event.connect (show_panel);
+ this.leave_notify_event.connect (hide_panel);
+ wnck_screen.active_window_changed.connect (active_window_changed);
+ wnck_screen.active_workspace_changed.connect (active_workspace_changed);
+ wnck_screen.viewports_changed.connect (viewports_changed);
+ show_panel ();
+ break;
+ default:
+ this.enter_notify_event.connect (show_panel);
+ this.motion_notify_event.connect (show_panel);
+ this.leave_notify_event.connect (hide_panel);
+ wnck_screen.active_window_changed.disconnect (active_window_changed);
+ wnck_screen.active_workspace_changed.disconnect (active_workspace_changed);
+ wnck_screen.viewports_changed.disconnect (viewports_changed);
+ hide_panel ();
+ break;
+ }
}
private void update_panel_dimensions () {
@@ -114,6 +196,24 @@ public class Wingpanel.PanelWindow : Gtk.Window {
update_struts ();
}
+ private void animate_panel () {
+ panel_height = panel.get_allocated_height ();
+
+ monitor_number = screen.get_primary_monitor ();
+ Gdk.Rectangle monitor_dimensions;
+ this.screen.get_monitor_geometry (monitor_number, out monitor_dimensions);
+
+ monitor_width = monitor_dimensions.width;
+ monitor_height = monitor_dimensions.height;
+
+ this.set_size_request (monitor_width, (popover_manager.current_indicator != null ? monitor_height : -1));
+
+ monitor_x = monitor_dimensions.x;
+ monitor_y = monitor_dimensions.y;
+
+ this.move (monitor_x, monitor_y - (panel_height + panel_displacement));
+ }
+
private void update_visual () {
var visual = this.screen.get_rgba_visual ();
diff --git a/wingpanel/src/Services/Settings.vala b/wingpanel-qq/src/Services/Settings.vala
index 3bcd0a7..eeecbb8 100644
--- a/wingpanel/src/Services/Settings.vala
+++ b/wingpanel-qq/src/Services/Settings.vala
@@ -23,6 +23,10 @@ namespace Wingpanel.Services {
public bool use_transparency { get; set; }
+ public string autohide { get; set; }
+
+ public int delay { get; set; }
+
public PanelSettings () {
base ("io.elementary.desktop.wingpanel");
}
--- src/wingpanel/CMakeLists.txt~ 2018-09-17 00:14:55.430071710 +0900
+++ src/wingpanel/CMakeLists.txt 2018-09-17 00:34:08.600075830 +0900
@@ -76,6 +76,7 @@
gee-0.8
gmodule-2.0
gtk+-3.0
+ libwnck-3.0
)
set (LIB_PKG
@@ -84,11 +85,15 @@
gee-0.8
gmodule-2.0
gtk+-3.0>=3.22
+ libwnck-3.0>=3.24
)
find_package(PkgConfig)
pkg_check_modules (LIB REQUIRED ${LIB_PKG})
+add_definitions (-DWNCK_I_KNOW_THIS_IS_UNSTABLE ${WNCK_CFLAGS})
+link_libraries (${WNCK_LIBRARIES})
+
set (GLOBAL_VALAC_OPTIONS
--vapidir=${CMAKE_BINARY_DIR}/lib
--vapidir=vapi
diff --git a/.travis.yml b/.travis.yml
index dddddf1..4efb6c0 100644
--- src/wingpanel/.travis.yml
+++ src/wingpanel/.travis.yml
@@ -4,7 +4,7 @@ services:
- docker
env:
- - DEPENDENCY_PACKAGES="cmake libgala-dev libgee-0.8-dev libgirepository1.0-dev libglib2.0-dev libgranite-dev libgtk-3-dev valac"
+ - DEPENDENCY_PACKAGES="cmake libgala-dev libgee-0.8-dev libgirepository1.0-dev libglib2.0-dev libgranite-dev libgtk-3-dev libwnck-3-dev valac"
install:
- docker pull elementary/docker:juno-unstable