#!/usr/bin/env python2

# Copyright (C) 2007-2014 by Clement Lefebvre <root@linuxmint.com>
# Copyright (C) 2015 Martin Wimpress <code@ubuntu-mate.org>
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

import errno
import gettext
import getpass
import gi
import glob
import os
import shutil
import subprocess
import string

from gi.repository import Gdk, GdkPixbuf, Gio, GObject, Gtk, Notify

__VERSION__="3.4.9"

# i18n
gettext.install("mate-tweak", "/usr/share/locale")

class SidePage:
    def __init__(self, notebook_index, name, icon):
        self.notebook_index = notebook_index
        self.name = name
        self.icon = icon

class MateTweak:

    def set_string(self, schema, key, value):
        settings = Gio.Settings.new(schema)
        settings.set_string(key, value)

    def get_string(self, schema, key):
        settings = Gio.Settings.new(schema)
        return settings.get_string(key)

    def set_bool(self, schema, key, value):
        settings = Gio.Settings.new(schema)
        settings.set_boolean(key, value.get_active())

        # If Maximus is being tweaked, replace it to make the settings effective.
        if schema == "org.mate.maximus" and (key == "undecorate" or key == "no-maximize"):
            devnull = open(os.devnull, 'wb')
            subprocess.Popen(['mate-maximus', '--replace'], stdout=devnull, stderr=devnull)
            devnull.close()

    def get_bool(self, schema, key):
        settings = Gio.Settings.new(schema)
        return settings.get_boolean(key)

    def init_checkbox(self, schema, key, name):
        source = Gio.SettingsSchemaSource.get_default()
        if source.lookup(schema, True) != None:
            widget = self.builder.get_object(name)
            value = self.get_bool(schema, key)
            widget.set_active(value)
            widget.connect("clicked", lambda x: self.set_bool(schema, key, x))

    def init_combobox(self, schema, key, name):
        source = Gio.SettingsSchemaSource.get_default()
        if source.lookup(schema, True) != None:
            widget = self.builder.get_object(name)
            conf = self.get_string(schema, key)
            index = 0
            for row in widget.get_model():
                if(conf == row[1]):
                    widget.set_active(index)
                    break
                index = index +1
            widget.connect("changed", lambda x: self.combo_fallback(schema, key, x))

    def update_combobox(self, schema, key, name):
        source = Gio.SettingsSchemaSource.get_default()
        if source.lookup(schema, True) != None:
            widget = self.builder.get_object(name)
            conf = self.get_string(schema, key)
            index = 0
            for row in widget.get_model():
                if(conf == row[1]):
                    widget.set_active(index)
                    break
                index = index +1

    def find_on_path(self, command):
        """Is command on the executable search path?"""
        if 'PATH' not in os.environ:
            return False
        path = os.environ['PATH']
        for element in path.split(os.pathsep):
            if not element:
                continue
            filename = os.path.join(element, command)
            if os.path.isfile(filename) and os.access(filename, os.X_OK):
                return True
        return False

    def mkdir_p(self, path):
        try:
            os.makedirs(path)
        except OSError as exc: # Python >2.5
            if exc.errno == errno.EEXIST and os.path.isdir(path):
                pass
            else:
                raise

    def get_current_wm(self):
        process = subprocess.Popen(['wmctrl', '-m'], stdout=subprocess.PIPE)
        out, err = process.communicate()
        return out

    def replace_windowmanager(self, wm, notify):
        # Use this in python < 3.3. Python >= 3.3 has subprocess.DEVNULL
        devnull = open(os.devnull, 'wb')
        if wm == 'compiz' or wm == 'mutter':
            # Make sure Metacity is uses the same theme as Marco. This ensures
            # gtk-window-decorator does not incorrectly change theme when
            # switching from Marco to Compiz.
            mate_theme = self.get_string('org.mate.interface', 'gtk-theme')
            self.set_string('org.gnome.desktop.wm.preferences', 'theme', mate_theme)

            # mate-panel needs to be replaced when switching to Compiz to avoid
            # rendering screw ups.
            subprocess.call(['killall', 'mate-panel'], stdout=devnull, stderr=devnull)
            subprocess.Popen([wm, '--replace', 'ccp'], stdout=devnull, stderr=devnull)
            subprocess.Popen(['mate-panel', '--replace'], stdout=devnull, stderr=devnull)
        else:
            subprocess.Popen([wm, '--replace'], stdout=devnull, stderr=devnull)
        devnull.close()

        if notify:
            Notify.init(_('Window Manager Replaced'))
            replace_windowmanager_notify=Notify.Notification.new (_('Window Manager Replaced'),_('Your window manager has been replaced with ' + wm),'dialog-information')
            replace_windowmanager_notify.show()

    def enable_dock(self, dock):
        self.mkdir_p(os.path.expanduser('~/.config/autostart/'))
        shutil.copy2('/usr/share/applications/' + dock + '.desktop', os.path.expanduser('~/.config/autostart/'))

        devnull = open(os.devnull, 'wb')
        # Docks require compositing
        current_wm = self.get_current_wm()
        if 'Marco' in current_wm:
            settings = Gio.Settings.new('org.mate.Marco.general')
            settings.set_boolean('compositing-manager', True)
            subprocess.Popen(['marco', '--replace'], stdout=devnull, stderr=devnull)
        elif 'Metacity' in current_wm:
            settings = Gio.Settings.new('org.gnome.metacity')
            settings.set_boolean('compositing-manager', True)
            subprocess.Popen(['metacity', '--replace'], stdout=devnull, stderr=devnull)

        subprocess.Popen([dock], stdout=devnull, stderr=devnull)
        devnull.close()

    def disable_dock(self, dock):
        if os.path.exists(os.path.expanduser('~/.config/autostart/') + dock + '.desktop'):
            os.remove(os.path.expanduser('~/.config/autostart/') + dock + '.desktop')
        devnull = open(os.devnull, 'wb')
        subprocess.call(['killall', dock], stdout=devnull, stderr=devnull)
        devnull.close()

    def enable_mate_volume_applet(self):
        devnull = open(os.devnull, 'wb')
        subprocess.Popen(['mate-volume-control-applet'], stdout=devnull, stderr=devnull)
        devnull.close()

        # If the system autostart is missing create a user autostart.
        if not os.path.exists('/etc/xdg/autostart/mate-volume-control-applet.desktop'):
            self.mkdir_p(os.path.expanduser('~/.config/autostart/'))
            shutil.copy2('/usr/share/mate-tweak/mate-volume-control-applet.desktop', os.path.expanduser('~/.config/autostart/'))

    def disable_mate_volume_applet(self):
        devnull = open(os.devnull, 'wb')
        subprocess.call(['killall', 'mate-volume-control-applet'], stdout=devnull, stderr=devnull)

        # If a system or user autostart exists, remove it.
        if os.path.exists(os.path.expanduser('~/.config/autostart/') + 'mate-volume-control-applet.desktop'):
            os.remove(os.path.expanduser('~/.config/autostart/') + 'mate-volume-control-applet.desktop')
        if os.path.exists('/etc/xdg/autostart/mate-volume-control-applet.desktop'):
            subprocess.call(['pkexec', '/usr/lib/mate-tweak/disable-mate-volume-applet'], stdout=devnull, stderr=devnull)
        devnull.close()

    def replace_panel_layout(self, panel_layout):
        # Use this in python < 3.3. Python >= 3.3 has subprocess.DEVNULL
        devnull = open(os.devnull, 'wb')
        subprocess.call(['killall', 'mate-panel'], stdout=devnull, stderr=devnull)
        subprocess.call(['dconf', 'reset', '-f', '/org/mate/panel/objects/'], stdout=devnull, stderr=devnull)
        subprocess.call(['dconf', 'reset', '-f', '/org/mate/panel/toplevels/'], stdout=devnull, stderr=devnull)
        subprocess.call(['mate-panel', '--layout', panel_layout, '--reset'], stdout=devnull, stderr=devnull)
        subprocess.Popen(['mate-panel', '--replace'], stdout=devnull, stderr=devnull)
        devnull.close()

        # Indicator enabled layouts auto-load the sound-indicator.
        # Therefore, make mate-volume-control-applet is killed or
        # started accordingly.
        if 'indicators' in panel_layout:
            self.disable_mate_volume_applet()
        else:
            self.enable_mate_volume_applet()

        # Enable/disable the appropriate dock if one of the dock ready
        # panel layouts is selected.
        dock = None
        if self.find_on_path('docky'):
            dock = 'docky'
        elif self.find_on_path('plank'):
            dock = 'plank'

        current_wm = self.get_current_wm()
        if panel_layout.startswith('eleven') and dock is not None:
            if 'Compiz' in current_wm:
                # https://bugs.launchpad.net/ubuntu-mate/+bug/1437611
                devnull = open(os.devnull, 'wb')
                subprocess.call(['dconf', 'write', '/org/compiz/profiles/mate/plugins/thumbnail/current-viewport', 'false'], stdout=devnull, stderr=devnull)
                devnull.close()

            if dock is 'docky':
                self.disable_dock('plank')
            elif dock is 'plank':
                self.disable_dock('docky')
            self.enable_dock(dock)
        else:
            if 'Compiz' in current_wm:
                # https://bugs.launchpad.net/ubuntu-mate/+bug/1437611
                devnull = open(os.devnull, 'wb')
                subprocess.call(['dconf', 'write', '/org/compiz/profiles/mate/plugins/thumbnail/current-viewport', 'true'], stdout=devnull, stderr=devnull)
                devnull.close()

            self.disable_dock('docky')
            self.disable_dock('plank')

    def panel_layout_exists(self, panel_layout):
        if os.path.exists('/usr/share/mate-panel/layouts/' + panel_layout + '.layout'):
            return True
        return False

    def compiz_capable(self):
        if self.find_on_path('compiz') and self.find_on_path('glxinfo'):
            process = subprocess.Popen(['glxinfo'], stdout=subprocess.PIPE)
            out, err = process.communicate()
            software_rasterizer = out.count("Software Rasterizer")
            texture_from_pixmap = out.count("texture_from_pixmap")
            if software_rasterizer == 0 and texture_from_pixmap > 2:
                return True

        return False

    def marco_capable(self):
        return self.find_on_path('marco')

    def metacity_capable(self):
        return self.find_on_path('metacity')

    def mutter_capable(self):
        if self.find_on_path('mutter') and self.find_on_path('glxinfo'):
            process = subprocess.Popen(['glxinfo'], stdout=subprocess.PIPE)
            out, err = process.communicate()
            software_rasterizer = out.count("Software Rasterizer")
            texture_from_pixmap = out.count("texture_from_pixmap")
            if software_rasterizer == 0 and texture_from_pixmap > 2:
                return True
        return False

    def additional_tweaks(self, schema, key, value):
        if schema == "org.mate.Marco.general" and key == "button-layout":
            # If the button-layout is changed in MATE reflect that change
            # for GTK3 and GNOME.
            self.set_string("org.mate.interface", "gtk-decoration-layout", value)
            self.set_string("org.gnome.desktop.wm.preferences", "button-layout", value)
        elif schema == "org.mate.session.required-components" and key == "windowmanager":
            wm = value
            # Sanity check
            if wm not in ['compiz', 'marco', 'metacity', 'mutter']:
                wm = 'marco'

            # If the window manager is being changed, replace it now!
            self.replace_windowmanager(wm, True)

            # Update the widget based on the selected window manager.
            if wm == 'marco' or  wm == 'metacity':
                self.builder.get_object('frame_marco').show()
                if wm == 'marco':
                    self.init_checkbox('org.mate.Marco.general', 'reduced-resources', 'checkbox_resources')
                    self.init_checkbox('org.mate.Marco.general', 'compositing-manager', 'checkbox_compositing')
                elif wm == 'metacity':
                    self.init_checkbox('org.gnome.metacity', 'reduced-resources', 'checkbox_resources')
                    self.init_checkbox('org.gnome.metacity', 'compositing-manager', 'checkbox_compositing')
            else:
                self.builder.get_object('frame_marco').hide()

            if wm == 'compiz':
               self.builder.get_object('button_compiz_reset').show()
            else:
               self.builder.get_object('button_compiz_reset').hide()

        elif schema == "org.mate.panel" and key == "default-layout":
            panel_layout = value
            # If the panel layout is being changed, replace it now!
            self.replace_panel_layout(panel_layout)

    def combo_fallback(self, schema, key, widget):
        act = widget.get_active()
        value = widget.get_model()[act]
        self.set_string(schema, key, value[1])

        # Process any additional changes required for the schema and key
        self.additional_tweaks(schema, key, value[1])

    # Change pages
    def side_view_nav(self, param):
        treePaths = param.get_selected_items()
        if (len(treePaths) > 0):
            treePath = treePaths[0]
            index = int("%s" % treePath) #Hack to turn treePath into an int
            target = self.sidePages[index].notebook_index
            self.builder.get_object("notebook1").set_current_page(target)

    def maximus_available(self):
        available = False
        if os.path.exists('/usr/bin/mate-maximus') and \
           os.path.exists('/usr/lib/mate-netbook/mate-window-picker-applet'):
            available = True
        return available

    def make_list_of_panel_layouts(self):
        # Determine what capabilities are available
        indicators_available = False
        if os.path.exists('/usr/lib/indicators/7/libapplication.so') and \
           os.path.exists('/usr/lib/indicator-sound-gtk2/indicator-sound-service') and \
           os.path.exists('/usr/lib/mate-indicator-applet/mate-indicator-applet'):
            indicators_available = True

        mate_menu_available = False
        if os.path.exists('/usr/lib/mate-menu/mate-menu.py'):
            mate_menu_available = True

        mint_menu_available = False
        if os.path.exists('usr/lib/linuxmint/mintMenu/mintMenu.py'):
            mint_menu_available = True

        gnome_menu_available = False
        if os.path.exists('/usr/lib/gnome-main-menu/main-menu'):
            gnome_menu_available = True

        dock = False
        if os.path.exists('/usr/bin/docky') or os.path.exists('/usr/bin/plank'):
            dock = True

        # Panel layouts
        panels = Gtk.ListStore(str, str)

        # Add any saved panel layouts first.
        layouts = os.path.join('/','usr','share','mate-panel','layouts','*-tweak.layout')
        for layout in glob.glob(layouts):
            current_layout = layout.replace('.layout', '').replace('/usr/share/mate-panel/layouts/', '');
            panels.append([_('Custom: ') + current_layout, current_layout])

        if self.panel_layout_exists('default'):
            panels.append([_("GNOME2"), "default"])

        if self.panel_layout_exists('ubuntu-mate'):
            panels.append([_("Ubuntu MATE"), "ubuntu-mate"])

        if self.panel_layout_exists('ubuntu-mate-fresh') \
            and mate_menu_available:
            panels.append([_("Ubuntu MATE with MATE Menu"), "ubuntu-mate-fresh"])

        if self.panel_layout_exists('ubuntu-mate-indicators') \
            and indicators_available:
            panels.append([_("Ubuntu MATE with Indicators"), "ubuntu-mate-indicators"])

        if self.panel_layout_exists('ubuntu-mate-indicators-fresh') \
            and indicators_available \
            and mate_menu_available:
            panels.append([_("Ubuntu MATE with Indicators and MATE Menu"), "ubuntu-mate-indicators-fresh"])

        if self.panel_layout_exists('redmond'):
            panels.append([_("Redmond"), "redmond"])

        if self.panel_layout_exists('redmond-fresh') \
            and mate_menu_available:
            panels.append([_("Redmond with MATE Menu"), "redmond-fresh"])

        if self.panel_layout_exists('redmond-indicators') \
            and indicators_available:
            panels.append([_("Redmond with Indicators"), "redmond-indicators"])

        if self.panel_layout_exists('redmond-indicators-fresh') \
            and indicators_available \
            and mate_menu_available:
            panels.append([_("Redmond with Indicators and MATE Menu"), "redmond-indicators-fresh"])

        if self.maximus_available():
            if self.panel_layout_exists('netbook'):
                panels.append([_("Netbook"), "netbook"])

            if self.panel_layout_exists('netbook-fresh') \
                and mate_menu_available:
                panels.append([_("Netbook with MATE Menu"), "netbook-fresh"])

            if self.panel_layout_exists('netbook-indicators') and \
               indicators_available:
                panels.append([_("Netbook with Indicators"), "netbook-indicators"])

            if self.panel_layout_exists('netbook-indicators-fresh') and \
               indicators_available and \
               mate_menu_available:
                panels.append([_("Netbook with Indicators and MATE Menu"), "netbook-indicators-fresh"])

        if dock:
            if self.panel_layout_exists('eleven'):
                panels.append([_("Cupertino"), "eleven"])

            if self.panel_layout_exists('eleven-fresh') and \
               mate_menu_available:
                panels.append([_("Cupertino with MATE Menu"), "eleven-fresh"])

            if self.panel_layout_exists('eleven-indicators') and \
               indicators_available:
                panels.append([_("Cupertino with Indicators"), "eleven-indicators"])

            if self.panel_layout_exists('eleven-indicators-fresh') and \
                indicators_available and \
                mate_menu_available:
                panels.append([_("Cupertino with Indicators and MATE Menu"), "eleven-indicators-fresh"])

        if self.panel_layout_exists('linuxmint') and \
           mint_menu_available:
            panels.append([_("Linux Mint"), "linuxmint"])

        if self.panel_layout_exists('opensuse') and \
           gnome_menu_available:
            panels.append([_("openSUSE"), "opensuse"])

        self.builder.get_object("combobox_panels").set_model(panels)

    def save_panels(self, widget):
        layoutname = getpass.getuser()
        devnull = open(os.devnull, 'wb')
        subprocess.call(['/usr/lib/mate-tweak/mate-panel-backup', layoutname], stdout=devnull, stderr=devnull)
        subprocess.call(['pkexec', '/usr/lib/mate-tweak/install-mate-panel-layout', layoutname], stdout=devnull, stderr=devnull)
        devnull.close()
        Notify.init(_('Panel Layout Saved'))
        save_panels_notify=Notify.Notification.new (_('Panel Layout Saved'),_('Your panel layout has been saved as /usr/share/mate-panel/layouts/' + layoutname +'-tweak.layout'),'dialog-information')
        save_panels_notify.show()
        Gtk.main_quit()
        
    def compiz_reset(self, widget):
        # Switch to Marco. Purge all Compiz config and cache. Switch to Compiz.
        self.replace_windowmanager('marco', False)
        devnull = open(os.devnull, 'wb')
        subprocess.call(['dconf', 'reset', '-f', '/org/compiz/'], stdout=devnull, stderr=devnull)
        devnull.close()
        config_compiz = os.path.join(os.path.expanduser('~'),'.config','compiz-1')
        cache_compiz = os.path.join(os.path.expanduser('~'),'.cache','compizconfg1')
        if os.path.exists(config_compiz):
            shutil.rmtree(config_compiz)
        if os.path.exists(cache_compiz):
            shutil.rmtree(cache_compiz)
        self.replace_windowmanager('compiz', False)
        Notify.init(_('Compiz Reset'))
        compiz_reset_notify=Notify.Notification.new (_('Compiz Reset'),_('Your Compiz configuration has been reset to factory defaults.'),'dialog-information')
        compiz_reset_notify.show()

    ''' Create the UI '''
    def __init__(self):
        # Load the Glade UI file
        self.builder = Gtk.Builder()
        self.builder.add_from_file('/usr/lib/mate-tweak/mate-tweak.ui')

        self.window = self.builder.get_object( "main_window" )
        self.builder.get_object("main_window").connect("destroy", Gtk.main_quit)
        self.builder.get_object("button_save_panels").connect("clicked", self.save_panels)
        self.builder.get_object("button_compiz_reset").connect("clicked", self.compiz_reset)

        side_desktop_options = SidePage(0, _("Desktop"), "user-desktop")
        side_windows = SidePage(1, _("Windows"), "preferences-system-windows")
        side_interface = SidePage(2, _("Interface"), "preferences-desktop")
        self.sidePages = [side_desktop_options, side_windows, side_interface]

        # create the backing store for the side nav-view.
        theme = Gtk.IconTheme.get_default()
        self.store = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
        for sidePage in self.sidePages:
            img = theme.load_icon(sidePage.icon, 36, 0)
            self.store.append([sidePage.name, img])

        target = self.sidePages[0].notebook_index
        self.builder.get_object("notebook1").set_current_page(target)

        # Determine the currently active window manager
        marco_mode = False
        metacity_mode = False
        mutter_mode = False
        compiz_mode = False

        current_wm = self.get_current_wm()
        if 'Marco' in current_wm:
            marco_mode = True
        elif 'Metacity' in current_wm:
            metacity_mode = True
        elif 'Mutter' in current_wm:
            mutter_mode = True
        elif 'Compiz' in current_wm:
            compiz_mode = True

        # Do not show Marco configuration options because Marco is not
        # currently running.
        if not marco_mode and not metacity_mode:
            self.builder.get_object('frame_marco').hide()

        if not compiz_mode:
            self.builder.get_object('button_compiz_reset').hide()

        if not self.maximus_available():
            self.builder.get_object('frame_maximus').hide()

        # set up the side view - navigation.
        self.builder.get_object("side_view").set_text_column(0)
        self.builder.get_object("side_view").set_pixbuf_column(1)
        self.builder.get_object("side_view").set_model(self.store)
        self.builder.get_object("side_view").select_path(Gtk.TreePath.new_first())
        self.builder.get_object("side_view").connect("selection_changed", self.side_view_nav)

        # set up larger components.
        self.builder.get_object("main_window").set_title("MATE Tweak")

        # i18n
        self.builder.get_object("label_desktop_icons").set_markup("<b>" + _("Desktop icons") + "</b>")
        self.builder.get_object("label_performance").set_markup("<b>" + _("Performance") + "</b>")
        self.builder.get_object("label_maximus").set_markup("<b>" + _("Maximus") + "</b>")
        self.builder.get_object("label_appearance").set_markup("<b>" + _("Appearance") + "</b>")
        self.builder.get_object("label_icons").set_markup("<b>" + _("Icons") + "</b>")
        self.builder.get_object("label_context_menus").set_markup("<b>" + _("Context menus") + "</b>")
        self.builder.get_object("label_toolbars").set_markup("<b>" + _("Toolbars") + "</b>")
        self.builder.get_object("label_window_manager").set_markup("<b>" + _("Window manager") + "</b>")

        self.builder.get_object("caption_desktop_icons").set_markup("<small>" + _("Select the items you want to see on the desktop:") + "</small>")

        self.builder.get_object("checkbox_computer").set_label(_("Computer"))
        self.builder.get_object("checkbox_home").set_label(_("Home"))
        self.builder.get_object("checkbox_network").set_label(_("Network"))
        self.builder.get_object("checkbox_trash").set_label(_("Trash"))
        self.builder.get_object("checkbox_volumes").set_label(_("Mounted Volumes"))

        self.builder.get_object("checkbox_resources").set_label(_("Don't show window content while dragging them"))
        self.builder.get_object("checkbox_compositing").set_label(_("Use compositing"))

        self.builder.get_object("checkbox_undecorate").set_label(_("Undecorate maximized windows"))
        self.builder.get_object("checkbox_always_maximize").set_label(_("Do not auto-maximize new windows"))

        self.builder.get_object("label_window_control").set_markup("<small>" + _("Window control placement.") + "</small>")

        self.builder.get_object("checkbutton_menuicon").set_label(_("Show icons on menus"))
        self.builder.get_object("checkbutton_button_icons").set_label(_("Show icons on buttons"))
        self.builder.get_object("checkbutton_im_menu").set_label(_("Show Input Methods menu in context menus"))
        self.builder.get_object("checkbutton_unicode").set_label(_("Show Unicode Control Character menu in context menus"))

        self.builder.get_object("label_toolbar_style").set_text(_("Style:"))
        self.builder.get_object("label_toolbar_icon_size").set_text(_("Icon size:"))

        # Desktop page
        self.init_checkbox("org.mate.caja.desktop", "computer-icon-visible", "checkbox_computer")
        self.init_checkbox("org.mate.caja.desktop", "home-icon-visible", "checkbox_home")
        self.init_checkbox("org.mate.caja.desktop", "network-icon-visible", "checkbox_network")
        self.init_checkbox("org.mate.caja.desktop", "trash-icon-visible", "checkbox_trash")
        self.init_checkbox("org.mate.caja.desktop", "volumes-visible", "checkbox_volumes")

        # Window Manager page
        if marco_mode:
            self.init_checkbox('org.mate.Marco.general', 'reduced-resources', 'checkbox_resources')
            self.init_checkbox('org.mate.Marco.general', 'compositing-manager', 'checkbox_compositing')
        elif metacity_mode:
            self.init_checkbox('org.gnome.metacity', 'reduced-resources', 'checkbox_resources')
            self.init_checkbox('org.gnome.metacity', 'compositing-manager', 'checkbox_compositing')

        self.init_checkbox("org.mate.maximus", "undecorate", "checkbox_undecorate")
        self.init_checkbox("org.mate.maximus", "no-maximize", "checkbox_always_maximize")

        # interface page
        self.init_checkbox("org.mate.interface", "menus-have-icons", "checkbutton_menuicon")
        self.init_checkbox("org.mate.interface", "show-input-method-menu","checkbutton_im_menu")
        self.init_checkbox("org.mate.interface", "show-unicode-menu", "checkbutton_unicode")
        self.init_checkbox("org.mate.interface", "buttons-have-icons", "checkbutton_button_icons")

        iconSizes = Gtk.ListStore(str, str)
        iconSizes.append([_("Small"), "small-toolbar"])
        iconSizes.append([_("Large"), "large-toolbar"])
        self.builder.get_object("combobox_toolbar_icon_size").set_model(iconSizes)
        self.init_combobox("org.mate.interface", "toolbar-icons-size", "combobox_toolbar_icon_size")

        # Window control button
        layouts = Gtk.ListStore(str, str)
        layouts.append([_("Traditional (Right)"), "menu:minimize,maximize,close"])
        layouts.append([_("Contemporary (Left)"), "close,minimize,maximize:"])
        self.builder.get_object("combobox_window_control").set_model(layouts)
        self.init_combobox("org.mate.Marco.general", "button-layout", "combobox_window_control")

        # Window manager
        wms = Gtk.ListStore(str, str)

        if self.marco_capable():
            wms.append([_("Marco (Simple desktop effects)"), 'marco'])
        if self.metacity_capable():
            wms.append([_("Metacity (Simple desktop effects)"), 'metacity'])
        if self.mutter_capable():
            wms.append([_("Mutter (Elegant GPU accelerated desktop effects)"), 'mutter'])
        if self.compiz_capable():
            wms.append([_("Compiz (Advanced GPU accelerated desktop effects)"), 'compiz'])
        
        self.builder.get_object("combobox_window_manager").set_model(wms)
        self.builder.get_object("combobox_window_manager").set_tooltip_text(_("The new window manager will be activated upon selection."))
        self.builder.get_object("caption_window_manager").set_markup("<small>" + _("Select a window manager.") + "</small>")
        self.init_combobox("org.mate.session.required-components", "windowmanager", "combobox_window_manager")

        # Panel layouts
        self.make_list_of_panel_layouts()
        self.builder.get_object("caption_panels").set_markup("<small>" + _("Select a panel layout to change the user interface.") + "</small>")
        self.builder.get_object("combobox_panels").set_tooltip_text(_("The new panel layout will be activated on selection and destroy any customisations you might have made."))
        self.init_combobox("org.mate.panel", "default-layout", "combobox_panels")

        # toolbar icon styles
        iconStyles = Gtk.ListStore(str, str)
        iconStyles.append([_("Text below items"), "both"])
        iconStyles.append([_("Text beside items"), "both-horiz"])
        iconStyles.append([_("Icons only"), "icons"])
        iconStyles.append([_("Text only"), "text"])
        self.builder.get_object("combobox_toolbar_style").set_model(iconStyles)
        self.init_combobox("org.mate.interface", "toolbar-style", "combobox_toolbar_style")
        self.builder.get_object("main_window").show()

if __name__ == "__main__":
    MateTweak()
    Gtk.main()
