Install custom build of Gala
sudo apt-get install bzr
bzr branch lp:~gala-dev/gala/no-depth-alt-tab
sudo apt-get build-dep gala
cd ~/no-depth-alt-tab
./autogen.sh
make
sudo make install
Install custom build of Gala
sudo apt-get install bzr
bzr branch lp:~gala-dev/gala/no-depth-alt-tab
sudo apt-get build-dep gala
cd ~/no-depth-alt-tab
./autogen.sh
make
sudo make install
| // | |
| // Copyright (C) 2012 Tom Beckmann, Rico Tzschichholz | |
| // | |
| // This program is free software: you can redistribute it and/or modify | |
| // it under the terms of the GNU General Public License as published by | |
| // the Free Software Foundation, either version 3 of the License, or | |
| // (at your option) any later version. | |
| // | |
| // This program is distributed in the hope that it will be useful, | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| // GNU General Public License for more details. | |
| // | |
| // You should have received a copy of the GNU General Public License | |
| // along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| // | |
| using Clutter; | |
| using Meta; | |
| namespace Gala | |
| { | |
| public class WindowSwitcher : Clutter.Actor | |
| { | |
| const int MIN_DELTA = 100; | |
| public WindowManager wm { get; construct; } | |
| Utils.WindowIcon? current_window = null; | |
| Actor window_clones; | |
| List<Actor> clone_sort_order; | |
| WindowActor? dock_window; | |
| Actor dock; | |
| Plank.Drawing.DockSurface? dock_surface; | |
| Plank.Drawing.DockTheme dock_theme; | |
| Plank.DockPreferences dock_settings; | |
| float dock_y_offset; | |
| float dock_height_offset; | |
| FileMonitor monitor; | |
| uint modifier_mask; | |
| int64 last_switch = 0; | |
| bool closing = false; | |
| ModalProxy modal_proxy; | |
| // estimated value, if possible | |
| float dock_width = 0.0f; | |
| int n_dock_items = 0; | |
| public WindowSwitcher (WindowManager wm) | |
| { | |
| Object (wm: wm); | |
| } | |
| construct | |
| { | |
| // pull drawing methods from libplank | |
| var settings_file = Environment.get_user_config_dir () + "/plank/dock1/settings"; | |
| dock_settings = new Plank.DockPreferences.with_filename (settings_file); | |
| dock_settings.notify.connect (update_dock); | |
| dock_settings.notify["Theme"].connect (load_dock_theme); | |
| var launcher_folder = Plank.Services.Paths.AppConfigFolder.get_child ("dock1").get_child ("launchers"); | |
| if (launcher_folder.query_exists ()) { | |
| try { | |
| monitor = launcher_folder.monitor (FileMonitorFlags.NONE); | |
| monitor.changed.connect (update_n_dock_items); | |
| } catch (Error e) { warning (e.message); } | |
| // initial update, pretend a file was created | |
| update_n_dock_items (launcher_folder, null, FileMonitorEvent.CREATED); | |
| } | |
| dock = new Actor (); | |
| dock.layout_manager = new BoxLayout (); | |
| var dock_canvas = new Canvas (); | |
| dock_canvas.draw.connect (draw_dock_background); | |
| dock.content = dock_canvas; | |
| dock.actor_removed.connect (icon_removed); | |
| dock.notify["allocation"].connect (() => | |
| dock_canvas.set_size ((int) dock.width, (int) dock.height)); | |
| load_dock_theme (); | |
| window_clones = new Actor (); | |
| window_clones.actor_removed.connect (window_removed); | |
| add_child (window_clones); | |
| add_child (dock); | |
| wm.get_screen ().monitors_changed.connect (update_dock); | |
| visible = false; | |
| } | |
| ~WindowSwitcher () | |
| { | |
| if (monitor != null) | |
| monitor.cancel (); | |
| wm.get_screen ().monitors_changed.disconnect (update_dock); | |
| } | |
| void load_dock_theme () | |
| { | |
| if (dock_theme != null) | |
| dock_theme.notify.disconnect (update_dock); | |
| dock_theme = new Plank.Drawing.DockTheme (dock_settings.Theme); | |
| dock_theme.load ("dock"); | |
| dock_theme.notify.connect (update_dock); | |
| update_dock (); | |
| } | |
| /** | |
| * set the values which don't get set every time and need to be updated when the theme changes | |
| */ | |
| void update_dock () | |
| { | |
| var screen = wm.get_screen (); | |
| var geometry = screen.get_monitor_geometry (screen.get_primary_monitor ()); | |
| var layout = (BoxLayout) dock.layout_manager; | |
| var position = dock_settings.Position; | |
| var icon_size = dock_settings.IconSize; | |
| var scaled_icon_size = icon_size / 10.0f; | |
| var horizontal = dock_settings.is_horizontal_dock (); | |
| var top_padding = (float) dock_theme.TopPadding * scaled_icon_size; | |
| var bottom_padding = (float) dock_theme.BottomPadding * scaled_icon_size; | |
| var item_padding = (float) dock_theme.ItemPadding * scaled_icon_size; | |
| var line_width = dock_theme.LineWidth; | |
| var top_offset = 2 * line_width + top_padding; | |
| var bottom_offset = (dock_theme.BottomRoundness > 0 ? 2 * line_width : 0) + bottom_padding; | |
| layout.spacing = (uint) item_padding; | |
| layout.orientation = horizontal ? Orientation.HORIZONTAL : Orientation.VERTICAL; | |
| dock_y_offset = -top_offset; | |
| dock_height_offset = top_offset + bottom_offset; | |
| var height = icon_size + (top_offset > 0 ? top_offset : 0) + bottom_offset; | |
| dock.anchor_gravity = horizontal ? Gravity.NORTH : Gravity.WEST; | |
| if (horizontal) { | |
| dock.height = height; | |
| dock.x = Math.ceilf (geometry.x + geometry.width / 2.0f); | |
| } else { | |
| dock.width = height; | |
| dock.y = Math.ceilf (geometry.y + geometry.height / 2.0f); | |
| } | |
| switch (position) { | |
| case Gtk.PositionType.TOP: | |
| dock.y = Math.ceilf (geometry.y); | |
| break; | |
| case Gtk.PositionType.BOTTOM: | |
| dock.y = Math.ceilf (geometry.y + geometry.height - height); | |
| break; | |
| case Gtk.PositionType.LEFT: | |
| dock.x = Math.ceilf (geometry.x); | |
| break; | |
| case Gtk.PositionType.RIGHT: | |
| dock.x = Math.ceilf (geometry.x + geometry.width - height); | |
| break; | |
| } | |
| dock_surface = null; | |
| } | |
| bool draw_dock_background (Cairo.Context cr) | |
| { | |
| cr.set_operator (Cairo.Operator.CLEAR); | |
| cr.paint (); | |
| cr.set_operator (Cairo.Operator.OVER); | |
| var position = dock_settings.Position; | |
| var width = (int) dock.width; | |
| var height = (int) dock.height; | |
| switch (position) { | |
| case Gtk.PositionType.RIGHT: | |
| width += (int) dock_height_offset; | |
| break; | |
| case Gtk.PositionType.LEFT: | |
| width -= (int) dock_y_offset; | |
| break; | |
| case Gtk.PositionType.TOP: | |
| height -= (int) dock_y_offset; | |
| break; | |
| case Gtk.PositionType.BOTTOM: | |
| height += (int) dock_height_offset; | |
| break; | |
| } | |
| if (dock_surface == null || dock_surface.Width != width || dock_surface.Height != height) { | |
| var dummy_surface = new Plank.Drawing.DockSurface.with_surface (1, 1, cr.get_target ()); | |
| dock_surface = dock_theme.create_background (width, height, position, dummy_surface); | |
| } | |
| float x = 0, y = 0; | |
| switch (position) { | |
| case Gtk.PositionType.RIGHT: | |
| x = dock_y_offset; | |
| break; | |
| case Gtk.PositionType.BOTTOM: | |
| y = dock_y_offset; | |
| break; | |
| case Gtk.PositionType.LEFT: | |
| x = 0; | |
| break; | |
| case Gtk.PositionType.TOP: | |
| y = 0; | |
| break; | |
| } | |
| cr.set_source_surface (dock_surface.Internal, x, y); | |
| cr.paint (); | |
| return false; | |
| } | |
| void place_dock () | |
| { | |
| var icon_size = dock_settings.IconSize; | |
| var scaled_icon_size = icon_size / 10.0f; | |
| var line_width = dock_theme.LineWidth; | |
| var horiz_padding = dock_theme.HorizPadding * scaled_icon_size; | |
| var item_padding = (float) dock_theme.ItemPadding * scaled_icon_size; | |
| var items_offset = (int) (2 * line_width + (horiz_padding > 0 ? horiz_padding : 0)); | |
| if (n_dock_items > 0) | |
| dock_width = n_dock_items * (item_padding + icon_size) + items_offset * 2; | |
| else | |
| dock_width = (dock_window != null ? dock_window.width : 300.0f); | |
| if (dock_settings.is_horizontal_dock ()) { | |
| dock.width = dock_width; | |
| dock.get_first_child ().margin_left = items_offset; | |
| dock.get_last_child ().margin_right = items_offset; | |
| } else { | |
| dock.height = dock_width; | |
| dock.get_first_child ().margin_top = items_offset; | |
| dock.get_last_child ().margin_bottom = items_offset; | |
| } | |
| dock.opacity = 255; | |
| } | |
| void animate_dock_width () | |
| { | |
| dock.save_easing_state (); | |
| dock.set_easing_duration (10); | |
| dock.set_easing_mode (AnimationMode.EASE_OUT_CUBIC); | |
| float dest_width; | |
| if (dock_settings.is_horizontal_dock ()) { | |
| dock.layout_manager.get_preferred_width (dock, dock.height, null, out dest_width); | |
| dock.width = dest_width; | |
| } else { | |
| dock.layout_manager.get_preferred_height (dock, dock.width, null, out dest_width); | |
| dock.height = dest_width; | |
| } | |
| dock.restore_easing_state (); | |
| } | |
| bool clicked_icon (Clutter.ButtonEvent event) { | |
| unowned Utils.WindowIcon icon = (Utils.WindowIcon) event.source; | |
| if (current_window != icon) { | |
| current_window = icon; | |
| dim_windows (); | |
| // wait for the dimming to finish | |
| Timeout.add (250, () => { | |
| close (wm.get_screen ().get_display ().get_current_time ()); | |
| return false; | |
| }); | |
| } else | |
| close (event.time); | |
| return true; | |
| } | |
| void window_removed (Actor actor) | |
| { | |
| clone_sort_order.remove (actor); | |
| } | |
| void icon_removed (Actor actor) | |
| { | |
| if (dock.get_n_children () == 1) { | |
| close (wm.get_screen ().get_display ().get_current_time ()); | |
| return; | |
| } | |
| if (actor == current_window) { | |
| current_window = (Utils.WindowIcon) current_window.get_next_sibling (); | |
| if (current_window == null) | |
| current_window = (Utils.WindowIcon) dock.get_first_child (); | |
| dim_windows (); | |
| } | |
| animate_dock_width (); | |
| } | |
| public override bool key_release_event (Clutter.KeyEvent event) | |
| { | |
| if ((get_current_modifiers () & modifier_mask) == 0) | |
| close (event.time); | |
| return true; | |
| } | |
| public override void key_focus_out () | |
| { | |
| close (wm.get_screen ().get_display ().get_current_time ()); | |
| } | |
| public void handle_switch_windows (Display display, Screen screen, Window? window, | |
| #if HAS_MUTTER314 | |
| Clutter.KeyEvent event, KeyBinding binding) | |
| #else | |
| X.Event event, KeyBinding binding) | |
| #endif | |
| { | |
| var now = get_monotonic_time () / 1000; | |
| if (now - last_switch < MIN_DELTA) | |
| return; | |
| // if we were still closing while the next invocation comes in, we need to cleanup | |
| // things right away | |
| if (visible && closing) { | |
| close_cleanup (); | |
| } | |
| last_switch = now; | |
| var workspace = screen.get_active_workspace (); | |
| var binding_name = binding.get_name (); | |
| var backward = binding_name.has_suffix ("-backward"); | |
| // FIXME for unknown reasons, switch-applications-backward won't be emitted, so we | |
| // test manually if shift is held down | |
| backward = binding_name == "switch-applications" | |
| && (get_current_modifiers () & ModifierType.SHIFT_MASK) != 0; | |
| if (visible && !closing) { | |
| current_window = next_window (workspace, backward); | |
| dim_windows (); | |
| return; | |
| } | |
| if (!collect_windows (workspace)) | |
| return; | |
| set_primary_modifier (binding.get_mask ()); | |
| current_window = next_window (workspace, backward); | |
| place_dock (); | |
| visible = true; | |
| closing = false; | |
| modal_proxy = wm.push_modal (); | |
| modal_proxy.keybinding_filter = (binding) => { | |
| // if it's not built-in, we can block it right away | |
| if (!binding.is_builtin ()) | |
| return true; | |
| // otherwise we determine by name if it's meant for us | |
| var name = binding.get_name (); | |
| return !(name == "switch-applications" || name == "switch-applications-backward" | |
| || name == "switch-windows" || name == "switch-windows-backward"); | |
| }; | |
| animate_dock_width (); | |
| dim_windows (); | |
| grab_key_focus (); | |
| if ((get_current_modifiers () & modifier_mask) == 0) | |
| close (wm.get_screen ().get_display ().get_current_time ()); | |
| } | |
| void close_cleanup () | |
| { | |
| var screen = wm.get_screen (); | |
| var workspace = screen.get_active_workspace (); | |
| dock.destroy_all_children (); | |
| dock_window = null; | |
| visible = false; | |
| closing = false; | |
| window_clones.destroy_all_children (); | |
| // need to go through all the windows because of hidden dialogs | |
| unowned List<WindowActor>? window_actors = Compositor.get_window_actors (screen); | |
| foreach (var actor in window_actors) { | |
| unowned Window window = actor.get_meta_window (); | |
| if (window.get_workspace () == workspace | |
| && window.showing_on_its_workspace ()) | |
| actor.show (); | |
| } | |
| } | |
| void close (uint time) | |
| { | |
| if (closing) | |
| return; | |
| closing = true; | |
| last_switch = 0; | |
| var screen = wm.get_screen (); | |
| var workspace = screen.get_active_workspace (); | |
| foreach (var actor in clone_sort_order) { | |
| unowned InternalUtils.SafeWindowClone clone = (InternalUtils.SafeWindowClone) actor; | |
| // current window stays on top | |
| if (clone.window == current_window.window) | |
| continue; | |
| // reset order | |
| window_clones.set_child_below_sibling (clone, null); | |
| if (!clone.window.minimized) { | |
| clone.save_easing_state (); | |
| clone.set_easing_duration (150); | |
| clone.set_easing_mode (AnimationMode.EASE_OUT_CUBIC); | |
| clone.z_position = 0; | |
| clone.opacity = 255; | |
| clone.restore_easing_state (); | |
| } | |
| } | |
| if (current_window != null) { | |
| current_window.window.activate (time); | |
| current_window = null; | |
| } | |
| wm.pop_modal (modal_proxy); | |
| if (dock_window != null) | |
| dock_window.opacity = 0; | |
| var dest_width = (dock_width > 0 ? dock_width : 600.0f); | |
| set_child_above_sibling (dock, null); | |
| if (dock_window != null) { | |
| dock_window.show (); | |
| dock_window.save_easing_state (); | |
| dock_window.set_easing_mode (AnimationMode.LINEAR); | |
| dock_window.set_easing_duration (250); | |
| dock_window.opacity = 255; | |
| dock_window.restore_easing_state (); | |
| } | |
| dock.save_easing_state (); | |
| dock.set_easing_duration (250); | |
| dock.set_easing_mode (AnimationMode.EASE_OUT_CUBIC); | |
| if (dock_settings.is_horizontal_dock ()) | |
| dock.width = dest_width; | |
| else | |
| dock.height = dest_width; | |
| dock.opacity = 0; | |
| dock.restore_easing_state (); | |
| var transition = dock.get_transition ("opacity"); | |
| if (transition != null) | |
| transition.completed.connect (() => close_cleanup ()); | |
| else | |
| close_cleanup (); | |
| } | |
| Utils.WindowIcon? add_window (Window window) | |
| { | |
| var actor = window.get_compositor_private () as WindowActor; | |
| if (actor == null) | |
| return null; | |
| actor.hide (); | |
| var clone = new InternalUtils.SafeWindowClone (window, true); | |
| clone.x = actor.x; | |
| clone.y = actor.y; | |
| window_clones.add_child (clone); | |
| var icon = new Utils.WindowIcon (window, dock_settings.IconSize, true); | |
| icon.reactive = true; | |
| icon.opacity = 100; | |
| icon.x_expand = true; | |
| icon.y_expand = true; | |
| icon.x_align = ActorAlign.CENTER; | |
| icon.y_align = ActorAlign.CENTER; | |
| icon.button_release_event.connect (clicked_icon); | |
| dock.add_child (icon); | |
| return icon; | |
| } | |
| void dim_windows () | |
| { | |
| var window_opacity = (int) Math.floor (AppearanceSettings.get_default ().alt_tab_window_opacity * 255); | |
| foreach (var actor in window_clones.get_children ()) { | |
| unowned InternalUtils.SafeWindowClone clone = (InternalUtils.SafeWindowClone) actor; | |
| actor.save_easing_state (); | |
| actor.set_easing_duration (50); | |
| actor.set_easing_mode (AnimationMode.EASE_OUT_QUAD); | |
| if (clone.window == current_window.window) { | |
| window_clones.set_child_above_sibling (actor, null); | |
| actor.z_position = 0; | |
| actor.opacity = 255; | |
| } else { | |
| // actor.z_position = -200; | |
| // actor.opacity = window_opacity; | |
| } | |
| actor.restore_easing_state (); | |
| } | |
| foreach (var actor in dock.get_children ()) { | |
| unowned Utils.WindowIcon icon = (Utils.WindowIcon) actor; | |
| icon.save_easing_state (); | |
| icon.set_easing_duration (50); | |
| icon.set_easing_mode (AnimationMode.LINEAR); | |
| if (icon == current_window) | |
| icon.opacity = 255; | |
| else | |
| icon.opacity = 100; | |
| icon.restore_easing_state (); | |
| } | |
| } | |
| /** | |
| * Adds the suitable windows on the given workspace to the switcher | |
| * | |
| * @return whether the switcher should actually be started or if there are | |
| * not enough windows | |
| */ | |
| bool collect_windows (Workspace workspace) | |
| { | |
| var screen = workspace.get_screen (); | |
| var display = screen.get_display (); | |
| #if HAS_MUTTER314 | |
| var windows = display.get_tab_list (TabList.NORMAL, workspace); | |
| var current = display.get_tab_current (TabList.NORMAL, workspace); | |
| #else | |
| var windows = display.get_tab_list (TabList.NORMAL, screen, workspace); | |
| var current = display.get_tab_current (TabList.NORMAL, screen, workspace); | |
| #endif | |
| if (windows.length () < 1) | |
| return false; | |
| if (windows.length () == 1) { | |
| var window = windows.data; | |
| if (window.minimized) | |
| window.unminimize (); | |
| else | |
| Utils.bell (screen); | |
| window.activate (display.get_current_time ()); | |
| return false; | |
| } | |
| foreach (var window in windows) { | |
| var clone = add_window (window); | |
| if (window == current) | |
| current_window = clone; | |
| } | |
| clone_sort_order = window_clones.get_children ().copy (); | |
| if (current_window == null) | |
| current_window = (Utils.WindowIcon) dock.get_child_at_index (0); | |
| // hide the others | |
| foreach (var actor in Compositor.get_window_actors (screen)) { | |
| var window = actor.get_meta_window (); | |
| var type = window.window_type; | |
| if (type != WindowType.DOCK | |
| && type != WindowType.DESKTOP | |
| && type != WindowType.NOTIFICATION) | |
| actor.hide (); | |
| if (window.title in BehaviorSettings.get_default ().dock_names | |
| && type == WindowType.DOCK) { | |
| dock_window = actor; | |
| dock_window.hide (); | |
| } | |
| } | |
| return true; | |
| } | |
| Utils.WindowIcon next_window (Workspace workspace, bool backward) | |
| { | |
| Actor actor; | |
| if (!backward) { | |
| actor = current_window.get_next_sibling (); | |
| if (actor == null) | |
| actor = dock.get_first_child (); | |
| } else { | |
| actor = current_window.get_previous_sibling (); | |
| if (actor == null) | |
| actor = dock.get_last_child (); | |
| } | |
| return (Utils.WindowIcon) actor; | |
| } | |
| /** | |
| * copied from gnome-shell, finds the primary modifier in the mask and saves it | |
| * to our modifier_mask field | |
| * | |
| * @param mask The modifier mask to extract the primary one from | |
| */ | |
| void set_primary_modifier (uint mask) | |
| { | |
| if (mask == 0) | |
| modifier_mask = 0; | |
| else { | |
| modifier_mask = 1; | |
| while (mask > 1) { | |
| mask >>= 1; | |
| modifier_mask <<= 1; | |
| } | |
| } | |
| } | |
| /** | |
| * Counts the launcher items to get an estimate of the window size | |
| */ | |
| void update_n_dock_items (File folder, File? other_file, FileMonitorEvent event) | |
| { | |
| if (event != FileMonitorEvent.CREATED && event != FileMonitorEvent.DELETED) | |
| return; | |
| var count = 0; | |
| try { | |
| var children = folder.enumerate_children ("", 0); | |
| while (children.next_file () != null) | |
| count++; | |
| } catch (Error e) { warning (e.message); } | |
| n_dock_items = count; | |
| } | |
| Gdk.ModifierType get_current_modifiers () | |
| { | |
| Gdk.ModifierType modifiers; | |
| double[] axes = {}; | |
| Gdk.Display.get_default ().get_device_manager ().get_client_pointer () | |
| .get_state (Gdk.get_default_root_window (), axes, out modifiers); | |
| return modifiers; | |
| } | |
| } | |
| } |
Same issue as @wochap. I've tried tinkering with the source files without success. Any solution to this would be greatly appreciated!
dependencies are tough (Freya) :
linux@eos:~/no-depth-alt-tab$ sudo apt-get build-dep gala
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages have unmet dependencies:
libgranite-dev : Depends: libgranite3 (= 0.3.1+r871+pkg84~ubuntu0.3.1) but 0.3.1+r889+pkg84~daily~ubuntu0.3.1.1 is to be installed
E: Build-dependencies for gala could not be satisfied.
EOS Loki
I get this error when i ran
make