diff --git a/eiconman/DesktopIcon.cpp b/eiconman/DesktopIcon.cpp index b36fa99..466a6fa 100644 --- a/eiconman/DesktopIcon.cpp +++ b/eiconman/DesktopIcon.cpp @@ -89,6 +89,7 @@ DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) : settings->name = is->name; settings->cmd = is->cmd; settings->icon = is->icon; + settings->icon2 = is->icon2; settings->type = is->type; settings->key_name= is->key_name; settings->full_path = is->full_path; @@ -109,6 +110,9 @@ DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) : else imenu->menu(icon_menu); + load_icon(ICON_FACE_ONE); + +#if 0 if(!settings->icon.empty()) { const char* nn = settings->icon.c_str(); @@ -130,6 +134,7 @@ DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) : } else EDEBUG(ESTRLOC ": Got empty icon name ?!?\n"); } +#endif fix_position(x(), y()); @@ -151,6 +156,42 @@ DesktopIcon::~DesktopIcon() { delete imenu; } +void DesktopIcon::load_icon(int face) { + const char* ic = NULL; + + if(face != ICON_FACE_TWO) { + if(!settings->icon.empty()) + ic = settings->icon.c_str(); + } else { + if(!settings->icon2.empty()) + ic = settings->icon2.c_str(); + } + + if(!ic) + return; + + edelib::String ipath = edelib::IconTheme::get(ic, edelib::ICON_SIZE_HUGE); + if(ipath.empty()) { + EDEBUG(ESTRLOC ": Got empty icon name ?!?\n"); + return; + } + + Fl_Image* img = Fl_Shared_Image::get(ipath.c_str()); + if(!img) { + EDEBUG(ESTRLOC ": Unable to load %s\n", ipath.c_str()); + return; + } + + int img_w = img->w(); + int img_h = img->h(); + + // resize box if icon is larger + if(img_w > ICONSIZE || img_h > ICONSIZE) + size(img_w + OFFSET_W, img_h + OFFSET_H); + + image(img); +} + void DesktopIcon::update_label_size(void) { labelsize(globals->label_fontsize); lwidth = globals->label_maxwidth; @@ -264,6 +305,20 @@ const edelib::String& DesktopIcon::path(void) { return settings->full_path; } +int DesktopIcon::icon_type(void) { + return settings->type; +} + +void DesktopIcon::icon1(void) { + load_icon(ICON_FACE_ONE); + fast_redraw(); +} + +void DesktopIcon::icon2(void) { + load_icon(ICON_FACE_TWO); + fast_redraw(); +} + void DesktopIcon::fast_redraw(void) { EASSERT(parent() != NULL && "Impossible !"); diff --git a/eiconman/DesktopIcon.h b/eiconman/DesktopIcon.h index bec45c4..faefd92 100644 --- a/eiconman/DesktopIcon.h +++ b/eiconman/DesktopIcon.h @@ -42,6 +42,7 @@ class DesktopIcon : public Fl_Widget { Fl_Menu_Button* imenu; + void load_icon(int face); void update_label_size(void); void fix_position(int X, int Y); @@ -85,6 +86,10 @@ class DesktopIcon : public Fl_Widget { * further used, especially in Desktop */ const edelib::String& path(void); + + int icon_type(void); + void icon1(void); + void icon2(void); }; class MovableIcon : public Fl_Window { diff --git a/eiconman/Jamfile b/eiconman/Jamfile index 8f9cb75..50a2295 100644 --- a/eiconman/Jamfile +++ b/eiconman/Jamfile @@ -15,7 +15,10 @@ ObjectC++Flags eiconman.cpp : -DUSE_EDELIB_WINDOW ; SOURCE = eiconman.cpp Utils.cpp Wallpaper.cpp DesktopIcon.cpp NotifyBox.cpp ; +# LinkAgainst eiconman : -lXfixes -lXdamage ; + EdeProgram eiconman : $(SOURCE) ; TranslationStrings locale : $(SOURCE) ; + FltkProgramBare test/notify : test/notify.cpp : noinstall ; diff --git a/eiconman/eiconman.cpp b/eiconman/eiconman.cpp index 1f99949..f12f239 100644 --- a/eiconman/eiconman.cpp +++ b/eiconman/eiconman.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -87,7 +88,6 @@ Fl_Menu_Item desktop_menu[] = { {0} }; - #if 0 XserverRegion xregion; XserverRegion xpart; @@ -147,7 +147,7 @@ int desktop_xmessage_handler(int event) { EDEBUG(ESTRLOC ": Damaged region %i %i %i %i on 0x%lx\n", xdev->area.x, xdev->area.y, xdev->area.width, xdev->area.height, xdev->drawable); - //XDamageSubtract(fl_display, xdev->damage, None, None); + XDamageSubtract(fl_display, xdev->damage, None, None); XFixesSetRegion(fl_display, xpart, &xdev->area, 1); XFixesUnionRegion(fl_display, xregion, xregion, xpart); } @@ -238,20 +238,44 @@ void Desktop::init_internals(void) { /* * Now try to load icons, first looking inside ~/Desktop directory - * FIXME: dir_exists() can't handle '~/desktop' ??? + * FIXME: dir_exists() can't handle '~/Desktop' ??? */ - edelib::String dd = edelib::dir_home(); - if(dd.empty()) { + edelib::String desktop_path = edelib::dir_home(); + if(desktop_path.empty()) { EWARNING(ESTRLOC ": can't read home directory; icons will not be loaded\n"); return; } - dd += "/Desktop"; + desktop_path += "/Desktop"; - if(edelib::dir_exists(dd.c_str())) { - load_icons(dd.c_str()); - install_watch(dd.c_str()); + // setup watcher on ~/Desktop and Trash directories + edelib::DirWatch::init(); + + if(edelib::dir_exists(desktop_path.c_str())) { + load_icons(desktop_path.c_str()); + + if(!edelib::DirWatch::add(desktop_path.c_str(), + edelib::DW_CREATE | edelib::DW_MODIFY | edelib::DW_RENAME | edelib::DW_DELETE)) { + + EWARNING(ESTRLOC ": Unable to watch %s\n", desktop_path.c_str()); + } } + /* + * For watching Trash, we will check Trash/files only with create/delete flags and + * in callback will be checked if directory is empty (trash empty) or not (trash full). + * + * FIXME: at startup it should be checked is Trash empty and update icons for that + */ + trash_path = edelib::user_data_dir(); + trash_path += "/Trash/files"; + + if(edelib::dir_exists(trash_path.c_str())) { + if(!edelib::DirWatch::add(trash_path.c_str(), edelib::DW_CREATE | edelib::DW_DELETE)) + EWARNING(ESTRLOC ": Unable to watch %s\n", trash_path.c_str()); + } + + edelib::DirWatch::callback(dir_watch_cb); + running = true; } @@ -369,18 +393,6 @@ void Desktop::read_config(void) { wallpaper->set(wpath); } -void Desktop::install_watch(const char* path) { - edelib::DirWatch::init(); - edelib::DirWatch::callback(dir_watch_cb); - - if(!edelib::DirWatch::add(path, - edelib::DW_CREATE | edelib::DW_MODIFY | edelib::DW_RENAME | edelib::DW_DELETE)) { - - EWARNING(ESTRLOC ": Can't setup watch on %s\n", path); - edelib::DirWatch::shutdown(); - } -} - void Desktop::load_icons(const char* path) { EASSERT(path != NULL); edelib::Config conf, *conf_ptr = NULL; @@ -941,6 +953,22 @@ void Desktop::dir_watch(const char* dir, const char* changed, int flags) { if(!do_dirwatch || !changed || flags == edelib::DW_REPORT_NONE) return; + if(trash_path == dir) { + bool trash_dir_empty = edelib::dir_empty(trash_path.c_str()); + + DesktopIconListIter it, it_end; + for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) { + if((*it)->icon_type() == ICON_TRASH) { + if(trash_dir_empty) + (*it)->icon1(); + else + (*it)->icon2(); + } + } + + return; + } + /* * Check first we don't get any temporary files (starting with '.' * or ending with '~', like vim does when editing file). For now these diff --git a/eiconman/eiconman.h b/eiconman/eiconman.h index 08fdf46..cedf051 100644 --- a/eiconman/eiconman.h +++ b/eiconman/eiconman.h @@ -51,6 +51,9 @@ struct GlobalIconSettings { #define ICON_FILE 3 // real file #define ICON_SYMLINK 4 // symbolic link +#define ICON_FACE_ONE 1 // use icon +#define ICON_FACE_TWO 2 // use icon2 + /* * Settings representing related to icon on desktop. To complicate our lives * (and to, at least, simplify code) it can be: @@ -114,11 +117,12 @@ class Desktop : public DESKTOP_WINDOW { DesktopIconList icons; DesktopIconList selectionbuff; + edelib::String trash_path; + void init_internals(void); void load_icons(const char* path); void save_icons(void); - void install_watch(const char* path); bool read_desktop_file(const char* path, IconSettings& is); void add_icon(DesktopIcon* ic);