mirror of
https://github.com/morgan9e/dash-to-panel
synced 2026-04-14 00:04:17 +09:00
Add option to ungroup the application instances and show their window titles
New features - ungroup aplication instances, while keeping them grouped by application - when ungrouped, display the window titles and allow the customization of their font-size and width - when ungrouped, optionally have the favorite application icons serve as launchers - customize the focused application indicator's color and opacity Bug fixes - fix icons not showing up immediately when lauching an application - fix message "g_signal_handler_disconnect: assertion 'handler_id > 0" occurring when destroying an icon - fix message "st_widget_get_theme_node called on the widget [# StIcon:last-child first-child] which is not in the stage." occurring after disabling the extension - fix message "[.../dash-to-panel@jderose9.github.com/windowPreview.js 1008]: reference to undefined property 0" occurring when restarting gnome-shell - fix message "[.../dash-to-panel@jderose9.github.com/taskbar.js 753]: reference to undefined property 0" occurring when restarting gnome-shell
This commit is contained in:
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@
|
||||
UUID = dash-to-panel@jderose9.github.com
|
||||
BASE_MODULES = extension.js stylesheet.css metadata.json COPYING README.md
|
||||
EXTRA_MODULES = appIcons.js convenience.js panel.js panelStyle.js overview.js taskbar.js windowPreview.js prefs.js Settings.ui
|
||||
EXTRA_IMAGES = highlight_bg.svg highlight_stacked_bg.svg
|
||||
EXTRA_IMAGES = highlight_stacked_bg.svg
|
||||
TOLOCALIZE = prefs.js appIcons.js
|
||||
MSGSRC = $(wildcard po/*.po)
|
||||
ifeq ($(strip $(DESTDIR)),)
|
||||
|
||||
424
Settings.ui
424
Settings.ui
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<!-- Generated with glade 3.20.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkAdjustment" id="appicon_margin_adjustment">
|
||||
@@ -8,6 +8,12 @@
|
||||
<property name="step_increment">0.01</property>
|
||||
<property name="page_increment">0.10000000000000001</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="focus_highlight_opacity_adjustment">
|
||||
<property name="lower">5</property>
|
||||
<property name="upper">100</property>
|
||||
<property name="step_increment">5</property>
|
||||
<property name="page_increment">5</property>
|
||||
</object>
|
||||
<object class="GtkBox" id="box_middle_click_options">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
@@ -408,6 +414,7 @@
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="row_spacing">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="focus_highlight_label">
|
||||
@@ -434,6 +441,59 @@
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="focus_highlight_color_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Highlight color</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="focus_highlight_color_colorbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="focus_highlight_opacity_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Highlight opacity</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="focus_highlight_opacity_spinbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="text" translatable="yes">0</property>
|
||||
<property name="adjustment">focus_highlight_opacity_adjustment</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -457,7 +517,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Height (px)</property>
|
||||
<property name="label" translatable="yes">Indicator height (px)</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -504,7 +564,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Color - Override Theme</property>
|
||||
<property name="label" translatable="yes">Indicator color - Override Theme</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -547,7 +607,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">1 window open</property>
|
||||
<property name="label" translatable="yes">1 window open (or ungrouped)</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -733,7 +793,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">1 window open</property>
|
||||
<property name="label" translatable="yes">1 window open (or ungrouped)</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -888,6 +948,277 @@
|
||||
<property name="step_increment">25</property>
|
||||
<property name="page_increment">100</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="group_apps_label_font_size_adjustment">
|
||||
<property name="lower">6</property>
|
||||
<property name="upper">24</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">100</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="group_apps_label_max_width_adjustment">
|
||||
<property name="lower">40</property>
|
||||
<property name="upper">320</property>
|
||||
<property name="step_increment">10</property>
|
||||
<property name="page_increment">100</property>
|
||||
</object>
|
||||
<object class="GtkBox" id="box_group_apps_options">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame_group_apps_options">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="listbox_group_apps_options">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="listbox_group_apps_label_font_size">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid_group_apps_label_font_size">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="group_apps_label_font_size_spinbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="text" translatable="yes">0</property>
|
||||
<property name="adjustment">group_apps_label_font_size_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_label_font_size_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Font size (px) of the application titles (default is 14)</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="listbox_group_apps_label_max_width">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid_group_apps_label_max_width">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_label_max_width_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Maximum width (px) of the application titles (default is 160)</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="group_apps_label_max_width_spinbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="text" translatable="yes">0</property>
|
||||
<property name="adjustment">group_apps_label_max_width_adjustment</property>
|
||||
<property name="numeric">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="listbox_group_apps_use_fixed_width">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid_group_apps_use_fixed_width">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_use_fixed_width_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Use a fixed width for the application titles</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="group_apps_use_fixed_width_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_use_fixed_width_description">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">The application titles all have the same width, even if their texts are shorter than the maximum width. The maximum width value is used as the fixed width.</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="max_width_chars">40</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="listbox_group_apps_underline_unfocused">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid_group_apps_underline_unfocused">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_underline_unfocused_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Display running indicators on unfocused applications</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="group_apps_underline_unfocused_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="listbox_group_apps_use_launchers">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid_group_apps_use_launchers">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_use_launchers_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Use the favorite icons as application launchers</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="group_apps_use_launchers_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="leave_timeout_adjustment">
|
||||
<property name="upper">9999</property>
|
||||
<property name="step_increment">25</property>
|
||||
@@ -2300,8 +2631,8 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Show favorite applications</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
@@ -2659,6 +2990,87 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="group_apps_row">
|
||||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="isolate_workspaces_grid1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="column_spacing">32</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="group_apps_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Group applications</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="group_apps_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="show_group_apps_options_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="xalign">0.46000000834465027</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image_window_previews_options1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">emblem-system-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="group_apps_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
|
||||
312
appIcons.js
312
appIcons.js
@@ -95,16 +95,40 @@ var taskbarAppIcon = new Lang.Class({
|
||||
Name: 'DashToPanel.TaskbarAppIcon',
|
||||
Extends: AppDisplay.AppIcon,
|
||||
|
||||
_init: function(settings, app, iconParams, onActivateOverride) {
|
||||
_init: function(settings, appInfo, iconParams, onActivateOverride) {
|
||||
|
||||
// a prefix is required to avoid conflicting with the parent class variable
|
||||
this._dtpSettings = settings;
|
||||
this._nWindows = 0;
|
||||
this.window = appInfo.window;
|
||||
this.isLauncher = appInfo.isLauncher;
|
||||
|
||||
this.parent(app, iconParams, onActivateOverride);
|
||||
this.parent(appInfo.app, iconParams, onActivateOverride);
|
||||
|
||||
this._dot.set_width(0);
|
||||
this._focused = tracker.focus_app == this.app;
|
||||
this._isGroupApps = this._dtpSettings.get_boolean('group-apps');
|
||||
|
||||
if (appInfo.window) {
|
||||
let outbox = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
let box = new St.BoxLayout();
|
||||
|
||||
this._windowTitle = new St.Label({
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
style_class: 'overview-label'
|
||||
});
|
||||
|
||||
this._updateWindowTitle();
|
||||
this._updateWindowTitleStyle();
|
||||
|
||||
this.actor.remove_actor(this._iconContainer);
|
||||
box.add_child(this._iconContainer);
|
||||
box.add_child(this._windowTitle);
|
||||
|
||||
outbox.add_child(box);
|
||||
this.actor.set_child(outbox);
|
||||
}
|
||||
|
||||
// Monitor windows-changes instead of app state.
|
||||
// Keep using the same Id and function callback (that is extended)
|
||||
@@ -113,38 +137,54 @@ var taskbarAppIcon = new Lang.Class({
|
||||
this._stateChangedId = 0;
|
||||
}
|
||||
|
||||
this._stateChangedId = this.app.connect('windows-changed',
|
||||
Lang.bind(this, this.onWindowsChanged));
|
||||
this._focusAppChangedId = tracker.connect('notify::focus-app',
|
||||
Lang.bind(this, this._onFocusAppChanged));
|
||||
|
||||
if (!this.window) {
|
||||
this._stateChangedId = this.app.connect('windows-changed',
|
||||
Lang.bind(this, this.onWindowsChanged));
|
||||
|
||||
this._focusWindowChangedId = 0;
|
||||
this._titleWindowChangeId = 0;
|
||||
} else {
|
||||
this._focusWindowChangedId = global.display.connect('notify::focus-window',
|
||||
Lang.bind(this, this._onFocusAppChanged));
|
||||
|
||||
this._titleWindowChangeId = this.window.connect('notify::title',
|
||||
Lang.bind(this, this._updateWindowTitle));
|
||||
}
|
||||
|
||||
this._overviewWindowDragEndId = Main.overview.connect('window-drag-end',
|
||||
Lang.bind(this, this._onOverviewWindowDragEnd));
|
||||
|
||||
this._switchWorkspaceId = global.window_manager.connect('switch-workspace',
|
||||
Lang.bind(this, this._onSwitchWorkspace));
|
||||
|
||||
this._focusedDots = null;
|
||||
this._unfocusedDots = null;
|
||||
|
||||
this._showDots();
|
||||
|
||||
this._dtpSettings.connect('changed::dot-position', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-size', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-style-focused', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-style-unfocused', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-override', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-1', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-2', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-3', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-4', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-different', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-1', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-2', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-3', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-4', Lang.bind(this, this._settingsChangeRefresh));
|
||||
this._dtpSettings.connect('changed::focus-highlight', Lang.bind(this, this._settingsChangeRefresh));
|
||||
|
||||
this.windowPreview = null;
|
||||
this._settingsConnectIds = [
|
||||
this._dtpSettings.connect('changed::dot-position', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-size', Lang.bind(this, this._updateDotSize)),
|
||||
this._dtpSettings.connect('changed::dot-style-focused', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-style-unfocused', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-override', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-1', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-2', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-3', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-4', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-different', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-1', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-2', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-3', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::dot-color-unfocused-4', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::focus-highlight', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::focus-highlight-color', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::focus-highlight-opacity', Lang.bind(this, this._settingsChangeRefresh)),
|
||||
this._dtpSettings.connect('changed::group-apps-label-font-size', Lang.bind(this, this._updateWindowTitleStyle)),
|
||||
this._dtpSettings.connect('changed::group-apps-label-max-width', Lang.bind(this, this._updateWindowTitleStyle)),
|
||||
this._dtpSettings.connect('changed::group-apps-use-fixed-width', Lang.bind(this, this._updateWindowTitleStyle)),
|
||||
this._dtpSettings.connect('changed::group-apps-underline-unfocused', Lang.bind(this, this._settingsChangeRefresh))
|
||||
];
|
||||
|
||||
this.forcedOverview = false;
|
||||
|
||||
@@ -236,7 +276,7 @@ var taskbarAppIcon = new Lang.Class({
|
||||
},
|
||||
|
||||
shouldShowTooltip: function() {
|
||||
if (this._dtpSettings.get_boolean("show-window-previews") &&
|
||||
if (!this.isLauncher && this._dtpSettings.get_boolean("show-window-previews") &&
|
||||
getInterestingWindows(this.app, this._dtpSettings).length > 0) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -255,8 +295,20 @@ var taskbarAppIcon = new Lang.Class({
|
||||
if(this._overviewWindowDragEndId)
|
||||
Main.overview.disconnect(this._overviewWindowDragEndId);
|
||||
|
||||
if(this._focusWindowChangedId)
|
||||
global.display.disconnect(this._focusWindowChangedId);
|
||||
|
||||
if(this._titleWindowChangeId)
|
||||
this.window.disconnect(this._titleWindowChangeId);
|
||||
|
||||
if(this._switchWorkspaceId)
|
||||
global.window_manager.disconnect(this._switchWorkspaceId);
|
||||
|
||||
for (let i = 0, l = this._settingsConnectIds.length; i < l; ++i) {
|
||||
if (this._settingsConnectIds[i]) {
|
||||
this._dtpSettings.disconnect(this._settingsConnectIds[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onWindowsChanged: function() {
|
||||
@@ -272,18 +324,17 @@ var taskbarAppIcon = new Lang.Class({
|
||||
// resulting in an error when assigned to the a rect. This is a more like
|
||||
// a workaround to prevent flooding the system with errors.
|
||||
if (this.actor.get_stage() == null)
|
||||
return
|
||||
return;
|
||||
|
||||
let rect = new Meta.Rectangle();
|
||||
|
||||
[rect.x, rect.y] = this.actor.get_transformed_position();
|
||||
[rect.width, rect.height] = this.actor.get_transformed_size();
|
||||
|
||||
let windows = this.app.get_windows();
|
||||
let windows = this.window ? [this.window] : this.app.get_windows();
|
||||
windows.forEach(function(w) {
|
||||
w.set_icon_geometry(rect);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
_showDots: function() {
|
||||
@@ -293,6 +344,21 @@ var taskbarAppIcon = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
let container = this.actor.get_children()[0];
|
||||
|
||||
if (!this._isGroupApps) {
|
||||
this._focusedDots = new St.Widget({
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true, y_expand: true,
|
||||
height: this._getRunningIndicatorHeight(),
|
||||
visible: false
|
||||
});
|
||||
|
||||
let mappedId = this.actor.connect('notify::mapped', () => {
|
||||
this._displayProperIndicator();
|
||||
this.actor.disconnect(mappedId);
|
||||
});
|
||||
} else {
|
||||
this._focusedDots = new St.DrawingArea({ width:1, y_expand: true });
|
||||
this._focusedDots._tweeningToWidth = null;
|
||||
this._unfocusedDots = new St.DrawingArea({width:1, y_expand: true});
|
||||
@@ -318,42 +384,83 @@ var taskbarAppIcon = new Lang.Class({
|
||||
this._displayProperIndicator();
|
||||
}));
|
||||
|
||||
|
||||
this._iconContainer.add_child(this._focusedDots);
|
||||
this._iconContainer.add_child(this._unfocusedDots);
|
||||
container.add_child(this._unfocusedDots);
|
||||
|
||||
this._updateCounterClass();
|
||||
}
|
||||
|
||||
container.add_child(this._focusedDots);
|
||||
},
|
||||
|
||||
_updateDotSize: function() {
|
||||
if (!this._isGroupApps) {
|
||||
this._focusedDots.height = this._getRunningIndicatorHeight();
|
||||
}
|
||||
|
||||
this._settingsChangeRefresh();
|
||||
},
|
||||
|
||||
_settingsChangeRefresh: function() {
|
||||
if (this._isGroupApps) {
|
||||
this._updateCounterClass();
|
||||
this._focusedDots.queue_repaint();
|
||||
this._unfocusedDots.queue_repaint();
|
||||
}
|
||||
|
||||
this._displayProperIndicator(true);
|
||||
},
|
||||
|
||||
_setIconStyle: function() {
|
||||
_updateWindowTitleStyle: function() {
|
||||
if (this._windowTitle) {
|
||||
let useFixedWidth = this._dtpSettings.get_boolean('group-apps-use-fixed-width');
|
||||
let maxLabelWidth = this._dtpSettings.get_int('group-apps-label-max-width');
|
||||
|
||||
this._windowTitle.clutter_text.natural_width = useFixedWidth ? maxLabelWidth : 0;
|
||||
this._windowTitle.clutter_text.natural_width_set = useFixedWidth;
|
||||
this._windowTitle.set_style('font-size: ' + this._dtpSettings.get_int('group-apps-label-font-size') + 'px;' +
|
||||
(useFixedWidth ? '' : 'max-width: ' + maxLabelWidth + 'px;'));
|
||||
}
|
||||
},
|
||||
|
||||
_updateWindowTitle: function() {
|
||||
if (this._windowTitle.text != this.window.title) {
|
||||
this._windowTitle.text = this.window.title;
|
||||
|
||||
if (this._focusedDots) {
|
||||
this._displayProperIndicator();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_setIconStyle: function(isFocused) {
|
||||
let margin = this._dtpSettings.get_int('appicon-margin');
|
||||
let inlineStyle = 'margin: 0 ' + margin + 'px;';
|
||||
|
||||
if(this._dtpSettings.get_boolean('focus-highlight') && tracker.focus_app == this.app && !this._isThemeProvidingIndicator()) {
|
||||
let containerWidth = this._iconContainer.get_width() / St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
if(this._dtpSettings.get_boolean('focus-highlight') &&
|
||||
tracker.focus_app == this.app && !this.isLauncher &&
|
||||
(!this.window || isFocused) && !this._isThemeProvidingIndicator()) {
|
||||
let focusedDotStyle = this._dtpSettings.get_string('dot-style-focused');
|
||||
let isWide = this._isWideDotStyle(focusedDotStyle);
|
||||
let pos = this._dtpSettings.get_string('dot-position');
|
||||
let highlightMargin = isWide ? this._dtpSettings.get_int('dot-size') : 0;
|
||||
|
||||
if(!this.window) {
|
||||
let containerWidth = this._iconContainer.get_width() / St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let backgroundSize = containerWidth + "px " +
|
||||
(containerWidth - (pos == DOT_POSITION.BOTTOM ? highlightMargin : 0)) + "px;";
|
||||
|
||||
if (focusedDotStyle == DOT_STYLE.CILIORA || focusedDotStyle == DOT_STYLE.SEGMENTED)
|
||||
highlightMargin += 1;
|
||||
|
||||
inlineStyle += "background-image: url('" +
|
||||
Me.path + "/img/highlight_" +
|
||||
((this._nWindows > 1 && focusedDotStyle == DOT_STYLE.METRO) ? "stacked_" : "") +
|
||||
"bg.svg'); background-position: 0 " +
|
||||
(pos == DOT_POSITION.TOP ? highlightMargin : 0) +
|
||||
"px; background-size: " +
|
||||
containerWidth + "px " +
|
||||
(containerWidth - (pos == DOT_POSITION.BOTTOM ? highlightMargin : 0)) + "px;";
|
||||
if (this._nWindows > 1 && focusedDotStyle == DOT_STYLE.METRO) {
|
||||
inlineStyle += "background-image: url('" + Me.path + "/img/highlight_stacked_bg.svg');" +
|
||||
"background-position: 0 " + (pos == DOT_POSITION.TOP ? highlightMargin : 0) + "px;" +
|
||||
"background-size: " + backgroundSize;
|
||||
}
|
||||
}
|
||||
|
||||
inlineStyle += "background-color: " + cssHexTocssRgba(this._dtpSettings.get_string('focus-highlight-color'),
|
||||
this._dtpSettings.get_int('focus-highlight-opacity') * 0.01);
|
||||
}
|
||||
|
||||
// graphical glitches if i dont set this on a timeout
|
||||
@@ -416,10 +523,22 @@ var taskbarAppIcon = new Lang.Class({
|
||||
},
|
||||
|
||||
_displayProperIndicator: function (force) {
|
||||
this._setIconStyle();
|
||||
let isFocused = this._isFocusedWindow();
|
||||
|
||||
let containerWidth = this._iconContainer.get_width();
|
||||
let isFocused = (tracker.focus_app == this.app);
|
||||
this._setIconStyle(isFocused);
|
||||
|
||||
if(!this._isGroupApps) {
|
||||
if (this.window && (this._dtpSettings.get_boolean('group-apps-underline-unfocused') || isFocused)) {
|
||||
let dotPosition = this._dtpSettings.get_string('dot-position');
|
||||
|
||||
this._focusedDots.y_align = dotPosition == DOT_POSITION.TOP ? Clutter.ActorAlign.START : Clutter.ActorAlign.END;
|
||||
this._focusedDots.background_color = this._getRunningIndicatorColor(isFocused);
|
||||
this._focusedDots.show();
|
||||
} else if (this._focusedDots.visible) {
|
||||
this._focusedDots.hide();
|
||||
}
|
||||
} else {
|
||||
let containerWidth = this.actor.get_children()[0].width;
|
||||
let focusedDotStyle = this._dtpSettings.get_string('dot-style-focused');
|
||||
let unfocusedDotStyle = this._dtpSettings.get_string('dot-style-unfocused');
|
||||
let focusedIsWide = this._isWideDotStyle(focusedDotStyle);
|
||||
@@ -430,6 +549,7 @@ var taskbarAppIcon = new Lang.Class({
|
||||
let newUnfocusedDotsWidth = 0;
|
||||
let newUnfocusedDotsOpacity = 0;
|
||||
|
||||
isFocused = (tracker.focus_app == this.app);
|
||||
|
||||
if(isFocused)
|
||||
this.actor.add_style_class_name('focused');
|
||||
@@ -461,13 +581,13 @@ var taskbarAppIcon = new Lang.Class({
|
||||
(this._focusedDots.width != newUnfocusedDotsWidth || this._unfocusedDots.width != newFocusedDotsWidth))) {
|
||||
this._animateDotDisplay(this._focusedDots, newFocusedDotsWidth, this._unfocusedDots, newUnfocusedDotsOpacity, force);
|
||||
this._animateDotDisplay(this._unfocusedDots, newUnfocusedDotsWidth, this._focusedDots, newFocusedDotsOpacity, force);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._focusedDots.opacity = newFocusedDotsOpacity;
|
||||
this._unfocusedDots.opacity = newUnfocusedDotsOpacity;
|
||||
this._focusedDots.width = newFocusedDotsWidth;
|
||||
this._unfocusedDots.width = newUnfocusedDotsWidth;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_animateDotDisplay: function (dots, newWidth, otherDots, newOtherOpacity, force) {
|
||||
@@ -490,6 +610,20 @@ var taskbarAppIcon = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_isFocusedWindow: function() {
|
||||
let focusedWindow = global.display.focus_window;
|
||||
|
||||
while (focusedWindow) {
|
||||
if (focusedWindow == this.window) {
|
||||
return true;
|
||||
}
|
||||
|
||||
focusedWindow = focusedWindow.get_transient_for();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_isWideDotStyle: function(dotStyle) {
|
||||
return dotStyle == DOT_STYLE.SEGMENTED ||
|
||||
dotStyle == DOT_STYLE.CILIORA ||
|
||||
@@ -549,16 +683,38 @@ var taskbarAppIcon = new Lang.Class({
|
||||
&& getInterestingWindows(this.app, this._dtpSettings).length > 0
|
||||
|
||||
// We customize the action only when the application is already running
|
||||
if (appIsRunning) {
|
||||
if (appIsRunning && !this.isLauncher) {
|
||||
if (this.window) {
|
||||
//ungrouped applications behaviors
|
||||
switch (buttonAction) {
|
||||
case 'RAISE': case 'CYCLE': case 'CYCLE-MIN': case 'MINIMIZE':
|
||||
if (!Main.overview._shown &&
|
||||
(buttonAction == 'MINIMIZE' ||
|
||||
(buttonAction == 'CYCLE-MIN' && this._isFocusedWindow()))) {
|
||||
this.window.minimize();
|
||||
} else {
|
||||
Main.activateWindow(this.window);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "LAUNCH":
|
||||
this._launchNewInstance();
|
||||
break;
|
||||
|
||||
case "QUIT":
|
||||
this.windows.delete(global.get_current_time());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//grouped application behaviors
|
||||
switch (buttonAction) {
|
||||
case "RAISE":
|
||||
activateAllWindows(this.app, this._dtpSettings);
|
||||
break;
|
||||
|
||||
case "LAUNCH":
|
||||
if(this._dtpSettings.get_boolean('animate-window-launch'))
|
||||
this.animateLaunch();
|
||||
this.app.open_new_window(-1);
|
||||
this._launchNewInstance();
|
||||
break;
|
||||
|
||||
case "MINIMIZE":
|
||||
@@ -612,15 +768,22 @@ var taskbarAppIcon = new Lang.Class({
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(this._dtpSettings.get_boolean('animate-window-launch'))
|
||||
this.animateLaunch();
|
||||
this.app.open_new_window(-1);
|
||||
this._launchNewInstance();
|
||||
}
|
||||
|
||||
Main.overview.hide();
|
||||
},
|
||||
|
||||
_launchNewInstance: function() {
|
||||
if(this._dtpSettings.get_boolean('animate-window-launch')) {
|
||||
this.animateLaunch();
|
||||
}
|
||||
|
||||
this.app.open_new_window(-1);
|
||||
},
|
||||
|
||||
_updateCounterClass: function() {
|
||||
let maxN = 4;
|
||||
this._nWindows = Math.min(getInterestingWindows(this.app, this._dtpSettings).length, maxN);
|
||||
@@ -634,26 +797,39 @@ var taskbarAppIcon = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_drawRunningIndicator: function(area, type, isFocused) {
|
||||
let bodyColor;
|
||||
_getRunningIndicatorHeight: function() {
|
||||
return this._dtpSettings.get_int('dot-size') * St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
},
|
||||
|
||||
_getRunningIndicatorColor: function(isFocused) {
|
||||
let color;
|
||||
|
||||
if(this._dtpSettings.get_boolean('dot-color-override')) {
|
||||
let dotColorSettingPrefix = 'dot-color-';
|
||||
|
||||
if(!isFocused && this._dtpSettings.get_boolean('dot-color-unfocused-different'))
|
||||
dotColorSettingPrefix = 'dot-color-unfocused-';
|
||||
bodyColor = Clutter.color_from_string(this._dtpSettings.get_string(dotColorSettingPrefix + (this._nWindows > 0 ? this._nWindows : 1)))[1];
|
||||
|
||||
color = Clutter.color_from_string(this._dtpSettings.get_string(dotColorSettingPrefix + (this._nWindows > 0 ? this._nWindows : 1)))[1];
|
||||
} else {
|
||||
// Re-use the style - background color, and border width and color -
|
||||
// of the default dot
|
||||
let themeNode = this._dot.get_theme_node();
|
||||
bodyColor = themeNode.get_background_color();
|
||||
if(bodyColor.alpha == 0) // theme didn't provide one, use a default
|
||||
bodyColor = new Clutter.Color({ red: 82, green: 148, blue: 226, alpha: 255 });
|
||||
color = themeNode.get_background_color();
|
||||
|
||||
if(color.alpha == 0) // theme didn't provide one, use a default
|
||||
color = new Clutter.Color({ red: 82, green: 148, blue: 226, alpha: 255 });
|
||||
}
|
||||
|
||||
return color;
|
||||
},
|
||||
|
||||
_drawRunningIndicator: function(area, type, isFocused) {
|
||||
let bodyColor = this._getRunningIndicatorColor(isFocused);
|
||||
let [width, height] = area.get_surface_size();
|
||||
let cr = area.get_context();
|
||||
let n = this._nWindows;
|
||||
let size = this._dtpSettings.get_int('dot-size') * St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let size = this._getRunningIndicatorHeight();
|
||||
let padding = 0; // distance from the margin
|
||||
let yOffset = this._dtpSettings.get_string('dot-position') == DOT_POSITION.TOP ? 0 : (height - padding - size);
|
||||
|
||||
@@ -933,6 +1109,15 @@ function getInterestingWindows(app, settings) {
|
||||
return windows;
|
||||
}
|
||||
|
||||
function cssHexTocssRgba(cssHex, opacity) {
|
||||
var bigint = parseInt(cssHex.slice(1), 16);
|
||||
var r = (bigint >> 16) & 255;
|
||||
var g = (bigint >> 8) & 255;
|
||||
var b = bigint & 255;
|
||||
|
||||
return 'rgba(' + [r, g, b].join(',') + ',' + opacity + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend AppIconMenu
|
||||
*
|
||||
@@ -1048,7 +1233,8 @@ var taskbarSecondaryMenu = new Lang.Class({
|
||||
|
||||
// quit menu
|
||||
let app = this._source.app;
|
||||
let count = getInterestingWindows(app, this._dtpSettings).length;
|
||||
let window = this._source.window;
|
||||
let count = window ? 1 : getInterestingWindows(app, this._dtpSettings).length;
|
||||
if ( count > 0) {
|
||||
this._appendSeparator();
|
||||
let quitFromTaskbarMenuText = "";
|
||||
@@ -1060,7 +1246,7 @@ var taskbarSecondaryMenu = new Lang.Class({
|
||||
this._quitfromTaskbarMenuItem = this._appendMenuItem(quitFromTaskbarMenuText);
|
||||
this._quitfromTaskbarMenuItem.connect('activate', Lang.bind(this, function() {
|
||||
let app = this._source.app;
|
||||
let windows = app.get_windows();
|
||||
let windows = window ? [window] : app.get_windows();
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
this._closeWindowInstance(windows[i])
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1">
|
||||
<rect width="1" height="1" fill="#eeeeee" opacity="0.25"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 165 B |
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 1">
|
||||
<g fill="#eeeeee" opacity="0.25">
|
||||
<rect width="45" height="1"/>
|
||||
<rect x="45" width="1" height="1" opacity="0.2"/>
|
||||
<rect x="46" width="2" height="1" opacity="0.6"/>
|
||||
<g fill="#000000">
|
||||
<rect x="45" width="1" height="1" opacity="0.6"/>
|
||||
<rect x="46" width="2" height="1" opacity="0.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 237 B |
@@ -57,7 +57,7 @@ var dtpOverview = new Lang.Class({
|
||||
// 1 static workspace only)
|
||||
Main.overview._controls.dash.actor.set_width(1);
|
||||
|
||||
this._optionalWorkspaceIsolation();
|
||||
this._isolation = this._optionalWorkspaceIsolation();
|
||||
this._optionalHotKeys();
|
||||
this._optionalNumberOverlay();
|
||||
this._bindSettingsChanges();
|
||||
@@ -75,6 +75,8 @@ var dtpOverview = new Lang.Class({
|
||||
// Remove key bindings
|
||||
this._disableHotKeys();
|
||||
this._disableExtraShortcut();
|
||||
|
||||
this._isolation.disable.apply(this);
|
||||
},
|
||||
|
||||
_bindSettingsChanges: function() {
|
||||
@@ -142,6 +144,8 @@ var dtpOverview = new Lang.Class({
|
||||
return Main.activateWindow(windows[0]);
|
||||
return this.open_new_window(-1);
|
||||
}
|
||||
|
||||
return { disable: disable };
|
||||
},
|
||||
|
||||
// Hotkeys
|
||||
|
||||
10
panel.js
10
panel.js
@@ -328,6 +328,14 @@ var dtpPanel = new Lang.Class({
|
||||
this._dtpSettings.connect('changed::show-showdesktop-button', Lang.bind(this, function() {
|
||||
this._displayShowDesktopButton(this._dtpSettings.get_boolean('show-showdesktop-button'));
|
||||
}));
|
||||
|
||||
this._dtpSettings.connect('changed::group-apps', Lang.bind(this, function() {
|
||||
this.taskbar.resetAppIcons();
|
||||
}));
|
||||
|
||||
this._dtpSettings.connect('changed::group-apps-use-launchers', Lang.bind(this, function() {
|
||||
this.taskbar.resetAppIcons();
|
||||
}));
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
@@ -611,7 +619,7 @@ var dtpPanel = new Lang.Class({
|
||||
let panelBottom = panelTop + this.actor.get_height();
|
||||
let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let isNearEnough = windows.some(Lang.bind(this, function(metaWindow) {
|
||||
if (this._dtpPosition === 'TOP') {
|
||||
if (this.hasOwnProperty('_dtpPosition') && this._dtpPosition === 'TOP') {
|
||||
let verticalPosition = metaWindow.get_frame_rect().y;
|
||||
return verticalPosition < panelBottom + 5 * scale;
|
||||
} else {
|
||||
|
||||
95
prefs.js
95
prefs.js
@@ -283,6 +283,13 @@ const Settings = new Lang.Class({
|
||||
}
|
||||
}));
|
||||
|
||||
this._builder.get_object('focus_highlight_color_colorbutton').connect('notify::color', Lang.bind(this, function(button) {
|
||||
let rgba = button.get_rgba();
|
||||
let css = rgba.to_string();
|
||||
let hexString = cssHexString(css);
|
||||
this._settings.set_string('focus-highlight-color', hexString);
|
||||
}));
|
||||
|
||||
this._builder.get_object('dot_style_options_button').connect('clicked', Lang.bind(this, function() {
|
||||
|
||||
let dialog = new Gtk.Dialog({ title: _('Running Indicator Options'),
|
||||
@@ -337,6 +344,17 @@ const Settings = new Lang.Class({
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
(function() {
|
||||
let rgba = new Gdk.RGBA();
|
||||
rgba.parse(this._settings.get_string('focus-highlight-color'));
|
||||
this._builder.get_object('focus_highlight_color_colorbutton').set_rgba(rgba);
|
||||
}).apply(this);
|
||||
|
||||
this._builder.get_object('focus_highlight_opacity_spinbutton').set_value(this._settings.get_int('focus-highlight-opacity'));
|
||||
this._builder.get_object('focus_highlight_opacity_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
|
||||
this._settings.set_int('focus-highlight-opacity', widget.get_value());
|
||||
}));
|
||||
|
||||
this._builder.get_object('dot_size_spinbutton').set_value(this._settings.get_int('dot-size'));
|
||||
this._builder.get_object('dot_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
|
||||
this._settings.set_int('dot-size', widget.get_value());
|
||||
@@ -348,9 +366,17 @@ const Settings = new Lang.Class({
|
||||
this._settings.set_value('dot-color-override', this._settings.get_default_value('dot-color-override'));
|
||||
this._settings.set_value('dot-color-unfocused-different', this._settings.get_default_value('dot-color-unfocused-different'));
|
||||
|
||||
this._settings.set_value('focus-highlight-color', this._settings.get_default_value('focus-highlight-color'));
|
||||
let rgba = new Gdk.RGBA();
|
||||
rgba.parse(this._settings.get_string('focus-highlight-color'));
|
||||
this._builder.get_object('focus_highlight_color_colorbutton').set_rgba(rgba);
|
||||
|
||||
this._settings.set_value('focus-highlight-opacity', this._settings.get_default_value('focus-highlight-opacity'));
|
||||
this._builder.get_object('focus_highlight_opacity_spinbutton').set_value(this._settings.get_int('focus-highlight-opacity'));
|
||||
|
||||
for (let i = 1; i <= MAX_WINDOW_INDICATOR; i++) {
|
||||
this._settings.set_value('dot-color-' + i, this._settings.get_default_value('dot-color-' + i));
|
||||
let rgba = new Gdk.RGBA();
|
||||
rgba = new Gdk.RGBA();
|
||||
rgba.parse(this._settings.get_string('dot-color-' + i));
|
||||
this._builder.get_object('dot_color_' + i + '_colorbutton').set_rgba(rgba);
|
||||
|
||||
@@ -494,6 +520,73 @@ const Settings = new Lang.Class({
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
this._settings.bind('group-apps',
|
||||
this._builder.get_object('group_apps_switch'),
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
this._settings.bind('group-apps-use-fixed-width',
|
||||
this._builder.get_object('group_apps_use_fixed_width_switch'),
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
this._settings.bind('group-apps-underline-unfocused',
|
||||
this._builder.get_object('group_apps_underline_unfocused_switch'),
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
this._settings.bind('group-apps-use-launchers',
|
||||
this._builder.get_object('group_apps_use_launchers_switch'),
|
||||
'active',
|
||||
Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
this._builder.get_object('show_group_apps_options_button').connect('clicked', Lang.bind(this, function() {
|
||||
let dialog = new Gtk.Dialog({ title: _('Group applications options'),
|
||||
transient_for: this.widget.get_toplevel(),
|
||||
use_header_bar: true,
|
||||
modal: true });
|
||||
|
||||
// GTK+ leaves positive values for application-defined response ids.
|
||||
// Use +1 for the reset action
|
||||
dialog.add_button(_('Reset to defaults'), 1);
|
||||
|
||||
let box = this._builder.get_object('box_group_apps_options');
|
||||
dialog.get_content_area().add(box);
|
||||
|
||||
this._builder.get_object('group_apps_label_font_size_spinbutton').set_value(this._settings.get_int('group-apps-label-font-size'));
|
||||
this._builder.get_object('group_apps_label_font_size_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
|
||||
this._settings.set_int('group-apps-label-font-size', widget.get_value());
|
||||
}));
|
||||
|
||||
this._builder.get_object('group_apps_label_max_width_spinbutton').set_value(this._settings.get_int('group-apps-label-max-width'));
|
||||
this._builder.get_object('group_apps_label_max_width_spinbutton').connect('value-changed', Lang.bind (this, function(widget) {
|
||||
this._settings.set_int('group-apps-label-max-width', widget.get_value());
|
||||
}));
|
||||
|
||||
dialog.connect('response', Lang.bind(this, function(dialog, id) {
|
||||
if (id == 1) {
|
||||
// restore default settings
|
||||
this._settings.set_value('group-apps-label-font-size', this._settings.get_default_value('group-apps-label-font-size'));
|
||||
this._builder.get_object('group_apps_label_font_size_spinbutton').set_value(this._settings.get_int('group-apps-label-font-size'));
|
||||
|
||||
this._settings.set_value('group-apps-label-max-width', this._settings.get_default_value('group-apps-label-max-width'));
|
||||
this._builder.get_object('group_apps_label_max_width_spinbutton').set_value(this._settings.get_int('group-apps-label-max-width'));
|
||||
|
||||
this._settings.set_value('group-apps-use-fixed-width', this._settings.get_default_value('group-apps-use-fixed-width'));
|
||||
this._settings.set_value('group-apps-underline-unfocused', this._settings.get_default_value('group-apps-underline-unfocused'));
|
||||
this._settings.set_value('group-apps-use-launchers', this._settings.get_default_value('group-apps-use-launchers'));
|
||||
} else {
|
||||
// remove the settings box so it doesn't get destroyed;
|
||||
dialog.get_content_area().remove(box);
|
||||
dialog.destroy();
|
||||
}
|
||||
return;
|
||||
}));
|
||||
|
||||
dialog.show_all();
|
||||
|
||||
}));
|
||||
|
||||
this._builder.get_object('click_action_combo').set_active_id(this._settings.get_string('click-action'));
|
||||
this._builder.get_object('click_action_combo').connect('changed', Lang.bind (this, function(widget) {
|
||||
this._settings.set_string('click-action', widget.get_active_id());
|
||||
|
||||
@@ -132,6 +132,16 @@
|
||||
<summary>Highlight icon of focused application</summary>
|
||||
<description>Whether to highlight the background of the currently focused application's icon</description>
|
||||
</key>
|
||||
<key type="s" name="focus-highlight-color">
|
||||
<default>"#5A5A5A"</default>
|
||||
<summary>Color of highlight of focused application</summary>
|
||||
<description>Customize the color of the highlight of the focused application</description>
|
||||
</key>
|
||||
<key type="i" name="focus-highlight-opacity">
|
||||
<default>50</default>
|
||||
<summary>Opacity of highlight of focused application</summary>
|
||||
<description>Customize the opacity of the highlight of the focused application</description>
|
||||
</key>
|
||||
<key name="location-clock" enum="org.gnome.shell.extensions.dash-to-panel.statusAreaPosition">
|
||||
<default>'STATUSLEFT'</default>
|
||||
<summary>Location of the clock</summary>
|
||||
@@ -192,6 +202,36 @@
|
||||
<summary>Provide workspace isolation</summary>
|
||||
<description>Dash shows only windows from the current workspace</description>
|
||||
</key>
|
||||
<key type="b" name="group-apps">
|
||||
<default>true</default>
|
||||
<summary>Group applications</summary>
|
||||
<description>Dash groups the application instances under the same icon</description>
|
||||
</key>
|
||||
<key type="i" name="group-apps-label-font-size">
|
||||
<default>14</default>
|
||||
<summary>Application title font size</summary>
|
||||
<description>When the applications are ungrouped, this defines the application titles font size.</description>
|
||||
</key>
|
||||
<key type="i" name="group-apps-label-max-width">
|
||||
<default>160</default>
|
||||
<summary>Application title max width</summary>
|
||||
<description>When the applications are ungrouped, this defines the application titles maximum width.</description>
|
||||
</key>
|
||||
<key type="b" name="group-apps-use-fixed-width">
|
||||
<default>true</default>
|
||||
<summary>Use a fixed width for the application titles</summary>
|
||||
<description>The application titles all have the same width, even if their texts are shorter than the maximum width. The maximum width value is used as the fixed width.</description>
|
||||
</key>
|
||||
<key type="b" name="group-apps-underline-unfocused">
|
||||
<default>true</default>
|
||||
<summary>Display running indicators on unfocused applications</summary>
|
||||
<description>When the applications are ungrouped, this defines if running applications should display an indicator.</description>
|
||||
</key>
|
||||
<key type="b" name="group-apps-use-launchers">
|
||||
<default>false</default>
|
||||
<summary>Use favorite icons as application launchers</summary>
|
||||
<description>When the applications are ungrouped, this defines if running applications stay separate from the favorite icons.</description>
|
||||
</key>
|
||||
<key type="b" name="customize-click">
|
||||
<default>true</default>
|
||||
<summary>Customize click behaviour</summary>
|
||||
|
||||
@@ -32,6 +32,20 @@
|
||||
border: none;
|
||||
}
|
||||
|
||||
#dashtopanelScrollview .app-well-app .overview-label {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
#dashtopanelScrollview .app-well-app:hover .overview-icon,
|
||||
#dashtopanelScrollview .app-well-app:focus .overview-icon {
|
||||
background: none;
|
||||
}
|
||||
|
||||
#dashtopanelScrollview .app-well-app:hover > :first-child,
|
||||
#dashtopanelScrollview .app-well-app:focus > :first-child {
|
||||
background-color: rgba(238, 238, 236, 0.1);
|
||||
}
|
||||
|
||||
#dashtopanelScrollview .app-well-app-running-dot {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
249
taskbar.js
249
taskbar.js
@@ -304,6 +304,7 @@ var taskbar = new Lang.Class({
|
||||
|
||||
destroy: function() {
|
||||
this._signalsHandler.destroy();
|
||||
this._signalsHandler = 0;
|
||||
},
|
||||
|
||||
_bindSettingsChanges: function () {
|
||||
@@ -439,10 +440,19 @@ var taskbar = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_createAppItem: function(app) {
|
||||
let appIcon = new AppIcons.taskbarAppIcon(this._dtpSettings, app,
|
||||
{ setSizeManually: true,
|
||||
showLabel: false });
|
||||
_createAppItem: function(app, window, isLauncher) {
|
||||
let appIcon = new AppIcons.taskbarAppIcon(
|
||||
this._dtpSettings,
|
||||
{
|
||||
app: app,
|
||||
window: window,
|
||||
isLauncher: isLauncher
|
||||
},
|
||||
{
|
||||
setSizeManually: true,
|
||||
showLabel: false
|
||||
}
|
||||
);
|
||||
|
||||
if (appIcon._draggable) {
|
||||
appIcon._draggable.connect('drag-begin',
|
||||
@@ -518,7 +528,9 @@ var taskbar = new Lang.Class({
|
||||
|
||||
_enableWindowPreview: function() {
|
||||
let appIcons = this._getAppIcons();
|
||||
appIcons.forEach(function (appIcon) {
|
||||
|
||||
appIcons.filter(appIcon => !appIcon.isLauncher)
|
||||
.forEach(function (appIcon) {
|
||||
appIcon.enableWindowPreview(appIcons);
|
||||
});
|
||||
},
|
||||
@@ -683,144 +695,100 @@ var taskbar = new Lang.Class({
|
||||
},
|
||||
|
||||
sortAppsCompareFunction: function(appA, appB) {
|
||||
let windowA = getAppInterestingWindows(appA)[0];
|
||||
let windowB = getAppInterestingWindows(appB)[0];
|
||||
return windowA.get_stable_sequence() > windowB.get_stable_sequence();
|
||||
return getAppStableSequence(appA) - getAppStableSequence(appB);
|
||||
},
|
||||
|
||||
sortWindowsCompareFunction: function(windowA, windowB) {
|
||||
return windowA.get_stable_sequence() - windowB.get_stable_sequence();
|
||||
},
|
||||
|
||||
_redisplay: function () {
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
let running = this._appSystem.get_running().sort(this.sortAppsCompareFunction);
|
||||
if (this._dtpSettings.get_boolean('isolate-workspaces')) {
|
||||
// When using isolation, we filter out apps that have no windows in
|
||||
// the current workspace
|
||||
let settings = this._dtpSettings;
|
||||
running = running.filter(function(_app) {
|
||||
return AppIcons.getInterestingWindows(_app, settings).length != 0;
|
||||
});
|
||||
if (!this._signalsHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
let children = this._box.get_children().filter(function(actor) {
|
||||
let groupApps = this._dtpSettings.get_boolean('group-apps');
|
||||
let showFavorites = this._dtpSettings.get_boolean('show-favorites');
|
||||
//get the currently displayed appIcons
|
||||
let currentAppIcons = this._box.get_children().filter(function(actor) {
|
||||
return actor.child &&
|
||||
actor.child._delegate &&
|
||||
actor.child._delegate.app;
|
||||
actor.child._delegate.app &&
|
||||
!actor.animatingOut;
|
||||
});
|
||||
// Apps currently in the taskbar
|
||||
let oldApps = children.map(function(actor) {
|
||||
return actor.child._delegate.app;
|
||||
});
|
||||
// Apps supposed to be in the taskbar
|
||||
let newApps = [];
|
||||
//get the user's favorite apps
|
||||
let favoriteAppsMap = showFavorites ? AppFavorites.getAppFavorites().getFavoriteMap() : {};
|
||||
let favoriteApps = Object.keys(favoriteAppsMap).map(appId => favoriteAppsMap[appId]);
|
||||
|
||||
// Adding favorites
|
||||
if (this._dtpSettings.get_boolean('show-favorites')) {
|
||||
for (let id in favorites)
|
||||
newApps.push(favorites[id]);
|
||||
}
|
||||
//find the apps that should be in the taskbar: the favorites first, then add the running apps
|
||||
// When using isolation, we filter out apps that have no windows in
|
||||
// the current workspace (this check is done in AppIcons.getInterstingWindows)
|
||||
let runningApps = this._getRunningApps().sort(this.sortAppsCompareFunction);
|
||||
let expectedAppInfos;
|
||||
|
||||
// Adding running apps
|
||||
for (let i = 0; i < running.length; i++) {
|
||||
let app = running[i];
|
||||
if (this._dtpSettings.get_boolean('show-favorites') && (app.get_id() in favorites))
|
||||
continue;
|
||||
newApps.push(app);
|
||||
}
|
||||
|
||||
// Figure out the actual changes to the list of items; we iterate
|
||||
// over both the list of items currently in the taskbar and the list
|
||||
// of items expected there, and collect additions and removals.
|
||||
// Moves are both an addition and a removal, where the order of
|
||||
// the operations depends on whether we encounter the position
|
||||
// where the item has been added first or the one from where it
|
||||
// was removed.
|
||||
// There is an assumption that only one item is moved at a given
|
||||
// time; when moving several items at once, everything will still
|
||||
// end up at the right position, but there might be additional
|
||||
// additions/removals (e.g. it might remove all the launchers
|
||||
// and add them back in the new order even if a smaller set of
|
||||
// additions and removals is possible).
|
||||
// If above assumptions turns out to be a problem, we might need
|
||||
// to use a more sophisticated algorithm, e.g. Longest Common
|
||||
// Subsequence as used by diff.
|
||||
let addedItems = [];
|
||||
let removedActors = [];
|
||||
|
||||
let newIndex = 0;
|
||||
let oldIndex = 0;
|
||||
while (newIndex < newApps.length || oldIndex < oldApps.length) {
|
||||
// No change at oldIndex/newIndex
|
||||
if (oldApps[oldIndex] == newApps[newIndex]) {
|
||||
oldIndex++;
|
||||
newIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// App removed at oldIndex
|
||||
if (oldApps[oldIndex] &&
|
||||
newApps.indexOf(oldApps[oldIndex]) == -1) {
|
||||
removedActors.push(children[oldIndex]);
|
||||
oldIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// App added at newIndex
|
||||
if (newApps[newIndex] &&
|
||||
oldApps.indexOf(newApps[newIndex]) == -1) {
|
||||
addedItems.push({ app: newApps[newIndex],
|
||||
item: this._createAppItem(newApps[newIndex]),
|
||||
pos: newIndex });
|
||||
newIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// App moved
|
||||
let insertHere = newApps[newIndex + 1] &&
|
||||
newApps[newIndex + 1] == oldApps[oldIndex];
|
||||
let alreadyRemoved = removedActors.reduce(function(result, actor) {
|
||||
let removedApp = actor.child._delegate.app;
|
||||
return result || removedApp == newApps[newIndex];
|
||||
}, false);
|
||||
|
||||
if (insertHere || alreadyRemoved) {
|
||||
let newItem = this._createAppItem(newApps[newIndex]);
|
||||
addedItems.push({ app: newApps[newIndex],
|
||||
item: newItem,
|
||||
pos: newIndex + removedActors.length });
|
||||
newIndex++;
|
||||
if (!groupApps && this._dtpSettings.get_boolean('group-apps-use-launchers')) {
|
||||
expectedAppInfos = this._createAppInfos(favoriteApps, [], true)
|
||||
.concat(this._createAppInfos(runningApps)
|
||||
.filter(appInfo => appInfo.windows.length));
|
||||
} else {
|
||||
removedActors.push(children[oldIndex]);
|
||||
oldIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < addedItems.length; i++)
|
||||
this._box.insert_child_at_index(addedItems[i].item,
|
||||
addedItems[i].pos);
|
||||
|
||||
for (let i = 0; i < removedActors.length; i++) {
|
||||
let item = removedActors[i];
|
||||
item.animateOutAndDestroy();
|
||||
}
|
||||
|
||||
this._adjustIconSize();
|
||||
|
||||
for (let i = 0; i < addedItems.length; i++){
|
||||
// Emit a custom signal notifying that a new item has been added
|
||||
this.emit('item-added', addedItems[i]);
|
||||
expectedAppInfos = this._createAppInfos(favoriteApps.concat(runningApps.filter(app => favoriteApps.indexOf(app) < 0)))
|
||||
.filter(appInfo => appInfo.windows.length || favoriteApps.indexOf(appInfo.app) >= 0);
|
||||
}
|
||||
|
||||
// Skip animations on first run when adding the initial set
|
||||
// of items, to avoid all items zooming in at once
|
||||
|
||||
let animate = this._shownInitially;
|
||||
|
||||
if (!this._shownInitially)
|
||||
this._shownInitially = true;
|
||||
|
||||
for (let i = 0; i < addedItems.length; i++) {
|
||||
addedItems[i].item.show(animate);
|
||||
//remove the appIcons which are not in the expected apps list
|
||||
for (let i = currentAppIcons.length - 1; i > -1; --i) {
|
||||
let appIcon = currentAppIcons[i].child._delegate;
|
||||
let appIndex = expectedAppInfos.findIndex(appInfo => appInfo.app == appIcon.app &&
|
||||
appInfo.isLauncher == appIcon.isLauncher);
|
||||
|
||||
if (appIndex < 0 ||
|
||||
(appIcon.window && (groupApps || expectedAppInfos[appIndex].windows.indexOf(appIcon.window) < 0)) ||
|
||||
(!appIcon.window && !appIcon.isLauncher &&
|
||||
!groupApps && expectedAppInfos[appIndex].windows.length)) {
|
||||
currentAppIcons[i].animateOutAndDestroy();
|
||||
currentAppIcons.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//if needed, reorder the existing appIcons and create the missing ones
|
||||
let currentPosition = 0;
|
||||
for (let i = 0, l = expectedAppInfos.length; i < l; ++i) {
|
||||
let neededAppIcons = groupApps || !expectedAppInfos[i].windows.length ?
|
||||
[{ app: expectedAppInfos[i].app, window: null, isLauncher: expectedAppInfos[i].isLauncher }] :
|
||||
expectedAppInfos[i].windows.map(window => ({ app: expectedAppInfos[i].app, window: window, isLauncher: false }));
|
||||
|
||||
for (let j = 0, ll = neededAppIcons.length; j < ll; ++j) {
|
||||
//check if the icon already exists
|
||||
let matchingAppIconIndex = currentAppIcons.findIndex(appIcon => appIcon.child._delegate.app == neededAppIcons[j].app &&
|
||||
appIcon.child._delegate.window == neededAppIcons[j].window);
|
||||
|
||||
if (matchingAppIconIndex > 0 && matchingAppIconIndex != currentPosition) {
|
||||
//moved icon, reposition it
|
||||
this._box.remove_child(currentAppIcons[matchingAppIconIndex]);
|
||||
this._box.insert_child_at_index(currentAppIcons[matchingAppIconIndex], currentPosition);
|
||||
} else if (matchingAppIconIndex < 0) {
|
||||
//the icon doesn't exist yet, create a new one
|
||||
let newAppIcon = this._createAppItem(neededAppIcons[j].app, neededAppIcons[j].window, neededAppIcons[j].isLauncher);
|
||||
|
||||
this._box.insert_child_at_index(newAppIcon, currentPosition);
|
||||
currentAppIcons.splice(currentPosition, 0, newAppIcon);
|
||||
|
||||
// Emit a custom signal notifying that a new item has been added
|
||||
this.emit('item-added', newAppIcon);
|
||||
|
||||
newAppIcon.show(animate);
|
||||
}
|
||||
|
||||
++currentPosition;
|
||||
}
|
||||
}
|
||||
|
||||
this._adjustIconSize();
|
||||
|
||||
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
|
||||
// Without it, StBoxLayout may use a stale size cache
|
||||
@@ -836,6 +804,31 @@ var taskbar = new Lang.Class({
|
||||
this._toggleWindowPreview();
|
||||
},
|
||||
|
||||
_getRunningApps: function() {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let windows = global.get_window_actors();
|
||||
let apps = [];
|
||||
|
||||
for (let i = 0, l = windows.length; i < l; ++i) {
|
||||
let app = tracker.get_window_app(windows[i].metaWindow);
|
||||
|
||||
if (app && apps.indexOf(app) < 0) {
|
||||
apps.push(app);
|
||||
}
|
||||
}
|
||||
|
||||
return apps;
|
||||
},
|
||||
|
||||
_createAppInfos: function(apps, defaultWindows, defaultIsLauncher) {
|
||||
return apps.map(app => ({
|
||||
app: app,
|
||||
isLauncher: defaultIsLauncher || false,
|
||||
windows: defaultWindows || AppIcons.getInterestingWindows(app, this._dtpSettings)
|
||||
.sort(this.sortWindowsCompareFunction)
|
||||
}));
|
||||
},
|
||||
|
||||
// Reset the displayed apps icon to mantain the correct order
|
||||
resetAppIcons : function() {
|
||||
|
||||
@@ -1195,6 +1188,14 @@ function getAppInterestingWindows(app, settings) {
|
||||
return windows;
|
||||
}
|
||||
|
||||
function getAppStableSequence(app) {
|
||||
let windows = getAppInterestingWindows(app);
|
||||
|
||||
return windows.reduce((prevWindow, window) => {
|
||||
return Math.min(prevWindow, window.get_stable_sequence());
|
||||
}, Infinity);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a copy of the same function in utils.js, but also adjust horizontal scrolling
|
||||
* and perform few further cheks on the current value to avoid changing the values when
|
||||
|
||||
@@ -82,7 +82,7 @@ var thumbnailPreviewMenu = new Lang.Class({
|
||||
this._boxPointer._arrowSide = side;
|
||||
this._boxPointer._userArrowSide = side;
|
||||
|
||||
this._previewBox = new thumbnailPreviewList(this._app, this._dtpSettings);
|
||||
this._previewBox = new thumbnailPreviewList(this._app, source.window, this._dtpSettings);
|
||||
this.addMenuItem(this._previewBox);
|
||||
|
||||
this._peekMode = false;
|
||||
@@ -820,8 +820,11 @@ var thumbnailPreview = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
if (this._titleNotifyId) {
|
||||
this.window.disconnect(this._titleNotifyId);
|
||||
this._titleNotifyId = 0;
|
||||
}
|
||||
|
||||
if(this._resizeId) {
|
||||
let mutterWindow = this.window.get_compositor_private();
|
||||
if (mutterWindow) {
|
||||
@@ -836,7 +839,7 @@ var thumbnailPreviewList = new Lang.Class({
|
||||
Name: 'DashToPanel.ThumbnailPreviewList',
|
||||
Extends: PopupMenu.PopupMenuSection,
|
||||
|
||||
_init: function(app, settings) {
|
||||
_init: function(app, window, settings) {
|
||||
this._dtpSettings = settings;
|
||||
|
||||
this.parent();
|
||||
@@ -858,14 +861,15 @@ var thumbnailPreviewList = new Lang.Class({
|
||||
this._shownInitially = false;
|
||||
|
||||
this.app = app;
|
||||
this.window = window;
|
||||
|
||||
this._redisplayId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
|
||||
this._scrollbarId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._showHideScrollbar));
|
||||
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
this._stateChangedId = this.app.connect('windows-changed',
|
||||
Lang.bind(this,
|
||||
this._queueRedisplay));
|
||||
|
||||
this._stateChangedId = this.window ? 0 :
|
||||
this.app.connect('windows-changed', Lang.bind(this, this._queueRedisplay));
|
||||
},
|
||||
|
||||
_needsScrollbar: function() {
|
||||
@@ -953,8 +957,10 @@ var thumbnailPreviewList = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
if (this._stateChangedId) {
|
||||
this.app.disconnect(this._stateChangedId);
|
||||
this._stateChangedId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_createPreviewItem: function(window) {
|
||||
@@ -986,7 +992,8 @@ var thumbnailPreviewList = new Lang.Class({
|
||||
},
|
||||
|
||||
_redisplay: function () {
|
||||
let windows = AppIcons.getInterestingWindows(this.app, this._dtpSettings).sort(this.sortWindowsCompareFunction);
|
||||
let windows = this.window ? [this.window] :
|
||||
AppIcons.getInterestingWindows(this.app, this._dtpSettings).sort(this.sortWindowsCompareFunction);
|
||||
let children = this.box.get_children().filter(function(actor) {
|
||||
return actor._delegate.window && actor._delegate.preview;
|
||||
});
|
||||
@@ -1004,13 +1011,6 @@ var thumbnailPreviewList = new Lang.Class({
|
||||
let oldIndex = 0;
|
||||
|
||||
while (newIndex < newWin.length || oldIndex < oldWin.length) {
|
||||
// No change at oldIndex/newIndex
|
||||
if (oldWin[oldIndex] == newWin[newIndex]) {
|
||||
oldIndex++;
|
||||
newIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Window removed at oldIndex
|
||||
if (oldWin[oldIndex] &&
|
||||
newWin.indexOf(oldWin[oldIndex]) == -1) {
|
||||
@@ -1028,6 +1028,13 @@ var thumbnailPreviewList = new Lang.Class({
|
||||
continue;
|
||||
}
|
||||
|
||||
// No change at oldIndex/newIndex
|
||||
if (oldWin[oldIndex] == newWin[newIndex]) {
|
||||
oldIndex++;
|
||||
newIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Window moved
|
||||
let insertHere = newWin[newIndex + 1] &&
|
||||
newWin[newIndex + 1] == oldWin[oldIndex];
|
||||
|
||||
Reference in New Issue
Block a user