diff --git a/data/icons/mate-window-applets/Black/index.theme b/data/icons/mate-window-applets/Black/index.theme deleted file mode 100644 index 65b38ef..0000000 --- a/data/icons/mate-window-applets/Black/index.theme +++ /dev/null @@ -1,27 +0,0 @@ -[Icon Theme] -Name = Black -Comment = Black theme for WindowButtons - -# Directory list -Directories=close,minimize,maximize - -[close] -Context=close -Size=256 -MinSize=8 -MaxSize=512 -Type=fixed - -[minimize] -Context=minimize -Size=256 -MinSize=8 -MaxSize=512 -Type=Scalable - -[maximize] -Context=maximize -Size=256 -MinSize=8 -MaxSize=512 -Type=Scalable diff --git a/data/icons/mate-window-applets/White/close/close.png b/data/icons/mate-window-applets/White/close/close.png deleted file mode 100644 index 79c860f..0000000 Binary files a/data/icons/mate-window-applets/White/close/close.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/close/close_hovered.png b/data/icons/mate-window-applets/White/close/close_hovered.png deleted file mode 100644 index 57c1043..0000000 Binary files a/data/icons/mate-window-applets/White/close/close_hovered.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/index.theme b/data/icons/mate-window-applets/White/index.theme deleted file mode 100644 index 210f7f9..0000000 --- a/data/icons/mate-window-applets/White/index.theme +++ /dev/null @@ -1,27 +0,0 @@ -[Icon Theme] -Name = White -Comment = White theme for WindowButtons - -# Directory list -Directories=close,minimize,maximize - -[close] -Context=close -Size=256 -MinSize=8 -MaxSize=512 -Type=fixed - -[minimize] -Context=minimize -Size=256 -MinSize=8 -MaxSize=512 -Type=Scalable - -[maximize] -Context=maximize -Size=256 -MinSize=8 -MaxSize=512 -Type=Scalable diff --git a/data/icons/mate-window-applets/White/maximize/maximize.png b/data/icons/mate-window-applets/White/maximize/maximize.png deleted file mode 100644 index 1491704..0000000 Binary files a/data/icons/mate-window-applets/White/maximize/maximize.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/maximize/maximize_hovered.png b/data/icons/mate-window-applets/White/maximize/maximize_hovered.png deleted file mode 100644 index de70882..0000000 Binary files a/data/icons/mate-window-applets/White/maximize/maximize_hovered.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/maximize/unmaximize.png b/data/icons/mate-window-applets/White/maximize/unmaximize.png deleted file mode 100644 index 9ddafc4..0000000 Binary files a/data/icons/mate-window-applets/White/maximize/unmaximize.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/maximize/unmaximize_hovered.png b/data/icons/mate-window-applets/White/maximize/unmaximize_hovered.png deleted file mode 100644 index ad04cf8..0000000 Binary files a/data/icons/mate-window-applets/White/maximize/unmaximize_hovered.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/minimize/minimize.png b/data/icons/mate-window-applets/White/minimize/minimize.png deleted file mode 100644 index 9193380..0000000 Binary files a/data/icons/mate-window-applets/White/minimize/minimize.png and /dev/null differ diff --git a/data/icons/mate-window-applets/White/minimize/minimize_hovered.png b/data/icons/mate-window-applets/White/minimize/minimize_hovered.png deleted file mode 100644 index ca8e652..0000000 Binary files a/data/icons/mate-window-applets/White/minimize/minimize_hovered.png and /dev/null differ diff --git a/data/icons/mate-window-applets/Black/close/close.png b/data/pixmaps/mate-window-applets/close.png similarity index 100% rename from data/icons/mate-window-applets/Black/close/close.png rename to data/pixmaps/mate-window-applets/close.png diff --git a/data/icons/mate-window-applets/Black/close/close_hovered.png b/data/pixmaps/mate-window-applets/close_prelight.png similarity index 100% rename from data/icons/mate-window-applets/Black/close/close_hovered.png rename to data/pixmaps/mate-window-applets/close_prelight.png diff --git a/data/icons/mate-window-applets/Black/maximize/maximize.png b/data/pixmaps/mate-window-applets/maximize.png similarity index 100% rename from data/icons/mate-window-applets/Black/maximize/maximize.png rename to data/pixmaps/mate-window-applets/maximize.png diff --git a/data/icons/mate-window-applets/Black/maximize/maximize_hovered.png b/data/pixmaps/mate-window-applets/maximize_prelight.png similarity index 100% rename from data/icons/mate-window-applets/Black/maximize/maximize_hovered.png rename to data/pixmaps/mate-window-applets/maximize_prelight.png diff --git a/data/icons/mate-window-applets/Black/minimize/minimize.png b/data/pixmaps/mate-window-applets/minimize.png similarity index 100% rename from data/icons/mate-window-applets/Black/minimize/minimize.png rename to data/pixmaps/mate-window-applets/minimize.png diff --git a/data/icons/mate-window-applets/Black/minimize/minimize_hovered.png b/data/pixmaps/mate-window-applets/minimize_prelight.png similarity index 100% rename from data/icons/mate-window-applets/Black/minimize/minimize_hovered.png rename to data/pixmaps/mate-window-applets/minimize_prelight.png diff --git a/data/icons/mate-window-applets/Black/maximize/unmaximize.png b/data/pixmaps/mate-window-applets/unmaximize.png similarity index 100% rename from data/icons/mate-window-applets/Black/maximize/unmaximize.png rename to data/pixmaps/mate-window-applets/unmaximize.png diff --git a/data/icons/mate-window-applets/Black/maximize/unmaximize_hovered.png b/data/pixmaps/mate-window-applets/unmaximize_prelight.png similarity index 100% rename from data/icons/mate-window-applets/Black/maximize/unmaximize_hovered.png rename to data/pixmaps/mate-window-applets/unmaximize_prelight.png diff --git a/install-icons.sh b/install-icons.sh index 9b75d8d..8be6355 100755 --- a/install-icons.sh +++ b/install-icons.sh @@ -12,9 +12,9 @@ else echo "Installing icons in $DIR" if [[ $1 == "install" ]]; then - cp -v -r data/icons $DIR + cp -v -r data/pixmaps $DIR elif [[ $1 == "uninstall" ]]; then - rm -v -r $DIR"icons/mate-window-applets" + rm -v -r $DIR"pixmaps/mate-window-applets" fi else @@ -29,9 +29,9 @@ else if [[ "$2" == "install" || "$2" == uninstall ]]; then if [[ $2 == "install" ]]; then - cp -v -r data/icons $DIR + cp -v -r data/pixmaps $DIR elif [[ $2 == "uninstall" ]]; then - rm -v -r $DIR"icons/mate-window-applets" + rm -v -r $DIR"pixmaps/mate-window-applets" else echo "Usage: $0 {path}(optional) install/uninstall" fi diff --git a/window-buttons-applet/meson.build b/window-buttons-applet/meson.build index b7ab01b..5367b87 100644 --- a/window-buttons-applet/meson.build +++ b/window-buttons-applet/meson.build @@ -3,7 +3,7 @@ if get_option('build-window-buttons') == true message('Building with Window Buttons') target_name = 'window-buttons-applet' -target_files = ['window-buttons-applet.vala','window-button.vala'] +target_files = ['window-buttons-applet.vala','window-button.vala','window-buttons-theme.vala'] window_buttons_dir = applets_dir + 'window-buttons/' executable(target_name,target_files,dependencies: deps,install: true,install_dir: window_buttons_dir) diff --git a/window-buttons-applet/window-button.vala b/window-buttons-applet/window-button.vala index f965cf6..c95ad99 100644 --- a/window-buttons-applet/window-button.vala +++ b/window-buttons-applet/window-button.vala @@ -3,29 +3,19 @@ namespace WindowWidgets{ //Properties private Gtk.Image button_image = new Gtk.Image(); - private Gtk.IconTheme icon_theme = new Gtk.IconTheme(); private WindowButtonType _button_type; - private string _theme = "Black"; - private Gdk.Pixbuf _icon; private int _icon_size = 18; private Wnck.Window _window; + private IconAction _current_action; + + public WindowButtonsTheme theme; public WindowButtonType button_type{ get{return _button_type;} set{_button_type = value;} } - public string theme{ - get{return _theme;} - set{_theme = value;} - } - - public Gdk.Pixbuf icon{ - get{return _icon;} - set{_icon = value;} - } - public int icon_size{ get{return icon_size;} set{_icon_size = value;} @@ -46,17 +36,6 @@ namespace WindowWidgets{ this.add(button_image); this.button_image.show(); - icon_theme.set_screen(this.get_screen()); - - string[] global_path = { "/usr/share/icons/mate-window-applets/" , "/usr/local/share/icons/mate-window-applets/"}; - string local_path = Environment.get_home_dir() + "/.icons/mate-window-applets/" ; - - icon_theme.set_search_path(global_path); - icon_theme.append_search_path(local_path); - - icon_theme.set_custom_theme(_theme); - - this.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); // Time for connecting @@ -77,8 +56,10 @@ namespace WindowWidgets{ }); - this.enter_notify_event.connect( (object,event) => { this.icon_set(event); return false; } ); - this.leave_notify_event.connect( (object,event) => { this.icon_set(event); return false; } ); + this.enter_notify_event.connect( (object,event) => { this.event_set(event); return false; } ); + this.leave_notify_event.connect( (object,event) => { this.event_set(event); return false; } ); + this.button_press_event.connect( (object,event) => { this.event_set(event); return false; } ); + this.button_release_event.connect( (object,event) => { this.event_set(event); return false; } ); } //Helpers @@ -100,89 +81,52 @@ namespace WindowWidgets{ } } - public void icon_set(Gdk.Event *event){ - if(event->get_event_type() == Gdk.EventType.NOTHING || event->get_event_type() == Gdk.EventType.LEAVE_NOTIFY){ - if(_button_type == WindowButtonType.CLOSE){ - if(_window != null && !_window.is_active() && icon_theme.has_icon("close_unfocused")){ - set_icon_by_name("close_unfocused"); - } else if(icon_theme.has_icon("close")){ - set_icon_by_name("close"); - } - } - else if(_button_type == WindowButtonType.MINIMIZE){ - if(_window != null && !_window.is_active() && icon_theme.has_icon("minimize_unfocused")){ - set_icon_by_name("minimize_unfocused"); - } else if(icon_theme.has_icon("minimize")){ - set_icon_by_name("minimize"); - } - } - else if(_button_type == WindowButtonType.MAXIMIZE){ - if(_window != null && _window.is_maximized()){ - if(!_window.is_active() && icon_theme.has_icon("unmaximize_unfocused")){ - set_icon_by_name("unmaximize_unfocused"); - } else if(icon_theme.has_icon("unmaximize")){ - set_icon_by_name("unmaximize"); - } - } - else{ - if(!_window.is_active() && icon_theme.has_icon("maximize_unfocused")){ - set_icon_by_name("maximize_unfocused"); - } else if(icon_theme.has_icon("maximize")){ - set_icon_by_name("maximize"); - } - } - } - } - else if(event->get_event_type() == Gdk.EventType.ENTER_NOTIFY){ - if(_button_type == WindowButtonType.CLOSE){ - if(_window != null && !_window.is_active() && icon_theme.has_icon("close_unfocused_hovered")){ - set_icon_by_name("close_unfocused_hovered"); - } else if(icon_theme.has_icon("close_hovered")){ - set_icon_by_name("close_hovered"); - } - } - else if(_button_type == WindowButtonType.MINIMIZE){ - if(_window != null && !_window.is_active() && icon_theme.has_icon("minimize_unfocused_hovered")){ - set_icon_by_name("minimize_unfocused_hovered"); - } else if(icon_theme.has_icon("minimize_hovered")){ - set_icon_by_name("minimize_hovered"); - } - } - else if(_button_type == WindowButtonType.MAXIMIZE){ - if(_window != null && _window.is_maximized()){ - if(!_window.is_active() && icon_theme.has_icon("unmaximize_unfocused_hovered")){ - set_icon_by_name("unmaximize_unfocused_hovered"); - } else if(icon_theme.has_icon("unmaximize_hovered")){ - set_icon_by_name("unmaximize_hovered"); - } - } - else{ - if(!_window.is_active() && icon_theme.has_icon("maximize_unfocused_hovered")){ - set_icon_by_name("maximize_unfocused_hovered"); - } else if(icon_theme.has_icon("maximize_hovered")){ - set_icon_by_name("maximize_hovered"); - } - } - } - } + public void update(bool reset = false){ + + IconType type; + if(_button_type == WindowButtonType.MINIMIZE) + type = IconType.MINIMIZE; + else if(_button_type == WindowButtonType.MAXIMIZE){ + if(_window != null && _window.is_maximized()) + type = IconType.UNMAXIMIZE; + else + type = IconType.MAXIMIZE; + } else + type = IconType.CLOSE; + - if(_icon != null){ - button_image.set_from_pixbuf(_icon); + IconState state; + if(!reset && _window != null && !_window.is_active()) + state = IconState.UNFOCUSED; + else + state = IconState.FOCUSED; + + + Gdk.Pixbuf? icon = theme.get_icon(type, state, _current_action); + + + if(icon != null){ + icon = icon.scale_simple(_icon_size, _icon_size, Gdk.InterpType.HYPER); + button_image.set_from_pixbuf(icon); } + } - public void theme_set(string value){ - _theme = value; - icon_theme.set_custom_theme(_theme); + private void event_set(Gdk.Event *event){ + if(event->get_event_type() == Gdk.EventType.ENTER_NOTIFY || event->get_event_type() == Gdk.EventType.BUTTON_RELEASE) + _current_action = IconAction.HOVERED; + else if(event->get_event_type() == Gdk.EventType.BUTTON_PRESS) + _current_action = IconAction.PRESSED; + else + _current_action = IconAction.NORMAL; + + this.update(); } - private void set_icon_by_name(string name){ - try{ - _icon = icon_theme.load_icon(name,-1,Gtk.IconLookupFlags.FORCE_SIZE); - _icon = _icon.scale_simple(_icon_size,_icon_size,Gdk.InterpType.HYPER); - } catch (GLib.Error e){ - stdout.printf("Error: %s\n", e.message); - } + public void reload(){ + _current_action = IconAction.NORMAL; + + this.update(true); } } diff --git a/window-buttons-applet/window-buttons-applet.vala b/window-buttons-applet/window-buttons-applet.vala index cc5d8cc..5aa2290 100644 --- a/window-buttons-applet/window-buttons-applet.vala +++ b/window-buttons-applet/window-buttons-applet.vala @@ -29,14 +29,6 @@ namespace WindowButtonsApplet{ public ButtonsApplet(Gtk.Orientation orient){ Object(orientation: orient); - enabled_buttons.close = false; - enabled_buttons.minimize = false; - enabled_buttons.maximize = false; - - this.add(CLOSE); - this.add(MINIMIZE); - this.add(MAXIMIZE); - this.set_homogeneous(true); this.change_layout(); @@ -53,13 +45,18 @@ namespace WindowButtonsApplet{ // Helpers - private void reload_actions(Wnck.Window *window){ + private void reload_actions(){ + if( window == null ){ + CLOSE.set_visible(false); + MINIMIZE.set_visible(false); + MAXIMIZE.set_visible(false); + } else { Wnck.WindowActions actions = window->get_actions(); if(enabled_buttons.close == true){ if((Wnck.WindowActions.CLOSE & actions)>0){ CLOSE.set_visible(true); CLOSE.window = window; - CLOSE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); + CLOSE.reload(); } else CLOSE.set_visible(false); } @@ -67,7 +64,7 @@ namespace WindowButtonsApplet{ if((Wnck.WindowActions.MINIMIZE & actions)>0){ MINIMIZE.set_visible(true); MINIMIZE.window = window; - MINIMIZE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); + MINIMIZE.reload(); } else MINIMIZE.set_visible(false); } @@ -75,9 +72,10 @@ namespace WindowButtonsApplet{ if((Wnck.WindowActions.MAXIMIZE & actions)>0){ MAXIMIZE.set_visible(true); MAXIMIZE.window = window; - MAXIMIZE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); + MAXIMIZE.reload(); } else MAXIMIZE.set_visible(false); } + } } public void reload(){ @@ -94,17 +92,12 @@ namespace WindowButtonsApplet{ window = get_current_window(); + reload_actions(); + // Watch for changes to new controlled window if(window != null){ window->actions_changed.connect(reload); window->state_changed.connect(reload); - - reload_actions(window); - } - else { - CLOSE.set_visible(false); - MINIMIZE.set_visible(false); - MAXIMIZE.set_visible(false); } // When active window is not the controlled window (because it is unmaximized), @@ -150,43 +143,45 @@ namespace WindowButtonsApplet{ enabled_buttons.maximize = true; } } + + reload_actions(); } public void change_theme(){ - string theme = gsettings.get_string("theme"); + string theme_name = gsettings.get_string("theme"); - if(enabled_buttons.close){ - CLOSE.theme_set(theme); - CLOSE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); - } + WindowButtonsTheme theme = new WindowButtonsTheme(theme_name); - if(enabled_buttons.minimize){ - MINIMIZE.theme_set(theme); - MINIMIZE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); - } + CLOSE.theme = theme; + if(enabled_buttons.close) + CLOSE.reload(); + + MINIMIZE.theme = theme; + if(enabled_buttons.minimize) + MINIMIZE.reload(); + + MAXIMIZE.theme = theme; + if(enabled_buttons.maximize) + MAXIMIZE.reload(); - if(enabled_buttons.maximize){ - MAXIMIZE.theme_set(theme); - MAXIMIZE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); - } } public void change_size(int size){ int padding = gsettings.get_int("padding"); size -= padding; - if(this.enabled_buttons.close == true){ - CLOSE.icon_size = size; - CLOSE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); - } - if(this.enabled_buttons.minimize == true){ - MINIMIZE.icon_size = size; - MINIMIZE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); - } - if(this.enabled_buttons.close == true){ - MAXIMIZE.icon_size = size; - MAXIMIZE.icon_set(new Gdk.Event(Gdk.EventType.NOTHING)); - } + CLOSE.icon_size = size; + if(this.enabled_buttons.close == true) + CLOSE.reload(); + + MINIMIZE.icon_size = size; + if(this.enabled_buttons.minimize == true) + MINIMIZE.reload(); + + MAXIMIZE.icon_size = size; + if(this.enabled_buttons.maximize == true) + MAXIMIZE.reload(); + } public void change_orient(int orient){ diff --git a/window-buttons-applet/window-buttons-theme.vala b/window-buttons-applet/window-buttons-theme.vala new file mode 100644 index 0000000..8faa263 --- /dev/null +++ b/window-buttons-applet/window-buttons-theme.vala @@ -0,0 +1,189 @@ +namespace WindowWidgets { + public class WindowButtonsTheme { + + private string _theme_name; + private Gdk.Pixbuf[,,] _pixbufs; + private string[] _extensions; + private string[] _prefixes; + private string[,] _type_names; + private string[,] _state_names; + private string[,] _action_names; + + public WindowButtonsTheme(string name){ + _pixbufs = new Gdk.Pixbuf[ + IconType.TYPES, + IconState.STATES, + IconAction.ACTIONS + ]; + + _theme_name = name; + + _extensions = {"png", "svg"}; + + _prefixes = {null, "button", "icon"}; + + _type_names = { + {"close", null}, + {"minimize", null}, + {"maximize", null}, + {"unmaximize", "restore"} + }; + + _state_names = { + {"focused", ""}, + {"unfocused", null} + }; + + _action_names = { + {"normal", ""}, + {"prelight", null}, + {"pressed", null} + }; + + string[] paths = get_search_paths(); + + load_icons(paths); + + if( _pixbufs[IconType.CLOSE, IconState.FOCUSED, IconAction.NORMAL] == null + || _pixbufs[IconType.MINIMIZE, IconState.FOCUSED, IconAction.NORMAL] == null + || _pixbufs[IconType.MAXIMIZE, IconState.FOCUSED, IconAction.NORMAL] == null ) { + load_fallback_icons(); + } + } + + private string[] get_search_paths(){ + string[] paths = { + Environment.get_home_dir() + "/.icons/mate-window-applets/" + _theme_name, + Environment.get_home_dir() + "/.themes/" + _theme_name + "/metacity-1", + Environment.get_home_dir() + "/.themes/" + _theme_name + "/unity", + "/usr/share/themes/" + _theme_name + "/metacity-1", + "/usr/share/themes/" + _theme_name + "/unity" + }; + string[] result = {}; + foreach(string path in paths){ + if( FileUtils.test(path, FileTest.IS_DIR) ) + result += path; + } + return result; + } + + private void load_icons(string[] paths){ + + for(int type = 0; type < IconType.TYPES; type++){ + for(int state = 0; state < IconState.STATES; state++){ + for(int action = 0; action < IconAction.ACTIONS; action++){ + + var icon_names = get_icon_aliases(type, state, action); + Gdk.Pixbuf icon = find_icon(paths, icon_names); + + if( icon != null ){ + _pixbufs[type, state, action] = icon; + } + + } + } + } + } + + private List get_icon_aliases(int type, int state, int action){ + var aliases = new List (); + for(int i = 0; i < _type_names.length[1]; i++){ + if(_type_names[type,i] == null) + break; + + for(int j = 0; j < _state_names.length[1]; j++){ + if(_state_names[state,j] == null) + break; + + for(int k = 0; k < _action_names.length[1]; k++){ + if(_action_names[action,k] == null) + break; + + string[] parts = {_type_names[type,i]}; + + if(_state_names[state,j] != "") + parts += _state_names[state,j]; + + if(_action_names[action,k] != "") + parts += _action_names[action,k]; + + aliases.append( string.joinv("_", parts) ); + + } + } + } + return aliases; + } + + private Gdk.Pixbuf? find_icon(string[] paths, List icon_names){ + string file_path = find_icon_filepath(paths, icon_names); + if( file_path != null ){ + try { + return new Gdk.Pixbuf.from_file(file_path); + } catch (GLib.Error e){ + stdout.printf("Error: %s\n", e.message); + } + } + return null; + } + + private string? find_icon_filepath(string[] paths, List icon_names){ + foreach(string prefix in _prefixes){ + foreach(string ext in _extensions){ + foreach(string path in paths){ + string result = find_icon_filepath_with(path, ext, prefix, icon_names); + if(result != null) + return result; + } + } + } + return null; + } + + private string? find_icon_filepath_with(string path, string extension, string? prefix, List icon_names){ + foreach(string icon_name in icon_names){ + if(prefix != null) + icon_name = prefix + "_" + icon_name; + + string file_path = path + "/" + icon_name + "." + extension; + if( FileUtils.test(file_path, FileTest.EXISTS) ) + return file_path; + } + return null; + } + + public Gdk.Pixbuf? get_icon(IconType type, IconState state, IconAction action){ + return _pixbufs[type, state, action]; + } + + private void load_fallback_icons(){ + string[] paths = {"/usr/share/pixmaps/mate-window-applets"}; + load_icons(paths); + } + + } + + public enum IconType { + CLOSE = 0, + MINIMIZE, + MAXIMIZE, + UNMAXIMIZE, + + TYPES + } + + public enum IconState { + FOCUSED = 0, + UNFOCUSED, + + STATES + } + + public enum IconAction { + NORMAL = 0, + HOVERED, + PRESSED, + + ACTIONS + } +} \ No newline at end of file