2006-08-20 22:43:09 +04:00
|
|
|
/*
|
|
|
|
* $Id$
|
|
|
|
*
|
2008-10-02 13:42:19 +04:00
|
|
|
* ede-desktop, desktop and icon manager
|
2006-08-20 22:43:09 +04:00
|
|
|
* Part of Equinox Desktop Environment (EDE).
|
2012-04-23 16:43:20 +04:00
|
|
|
* Copyright (c) 2006-2012 EDE Authors.
|
2006-08-20 22:43:09 +04:00
|
|
|
*
|
2008-10-02 13:42:19 +04:00
|
|
|
* This program is licensed under terms of the
|
|
|
|
* GNU General Public License version 2 or newer.
|
2006-08-20 22:43:09 +04:00
|
|
|
* See COPYING for details.
|
|
|
|
*/
|
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2008-10-02 13:42:19 +04:00
|
|
|
#include <unistd.h> // sleep
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdlib.h> // rand, srand
|
|
|
|
#include <time.h> // time
|
2011-11-09 18:08:11 +04:00
|
|
|
#include <limits.h>
|
2008-10-02 13:42:19 +04:00
|
|
|
|
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include <FL/x.H>
|
|
|
|
#include <FL/fl_draw.H>
|
|
|
|
#include <FL/Fl_Box.H>
|
|
|
|
#include <FL/Fl_Shared_Image.H>
|
2012-05-10 15:19:19 +04:00
|
|
|
#include <FL/Fl_Button.H>
|
|
|
|
#include <FL/Fl_Box.H>
|
|
|
|
#include <FL/Fl_Output.H>
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
#include <edelib/Debug.h>
|
2009-04-16 15:24:52 +04:00
|
|
|
#include <edelib/FileTest.h>
|
2012-05-10 15:19:19 +04:00
|
|
|
#include <edelib/File.h>
|
2007-05-22 18:53:17 +04:00
|
|
|
#include <edelib/Directory.h>
|
2009-04-16 15:24:52 +04:00
|
|
|
#include <edelib/DesktopFile.h>
|
2007-09-03 16:26:58 +04:00
|
|
|
#include <edelib/DirWatch.h>
|
2007-06-18 18:18:35 +04:00
|
|
|
#include <edelib/MimeType.h>
|
2007-05-22 18:53:17 +04:00
|
|
|
#include <edelib/StrUtil.h>
|
2009-03-25 14:13:12 +03:00
|
|
|
#include <edelib/IconLoader.h>
|
2007-11-06 17:33:19 +03:00
|
|
|
#include <edelib/Run.h>
|
2007-11-28 15:42:52 +03:00
|
|
|
#include <edelib/Util.h>
|
2009-03-26 20:05:44 +03:00
|
|
|
#include <edelib/MessageBox.h>
|
2009-07-09 17:26:59 +04:00
|
|
|
#include <edelib/MenuButton.h>
|
2009-11-10 14:10:34 +03:00
|
|
|
#include <edelib/ForeignCallback.h>
|
2009-12-24 18:47:29 +03:00
|
|
|
#include <edelib/Netwm.h>
|
|
|
|
#include <edelib/WindowXid.h>
|
2011-11-09 18:08:11 +04:00
|
|
|
#include <edelib/FontCache.h>
|
2012-04-23 16:43:20 +04:00
|
|
|
#include <edelib/Nls.h>
|
2010-03-28 16:54:45 +04:00
|
|
|
#include <edelib/Ede.h>
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2008-10-02 13:42:19 +04:00
|
|
|
#include "ede-desktop.h"
|
|
|
|
#include "DesktopIcon.h"
|
|
|
|
#include "Utils.h"
|
|
|
|
#include "Wallpaper.h"
|
2012-04-25 20:28:09 +04:00
|
|
|
#include "IconDialog.h"
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-02-25 16:15:16 +03:00
|
|
|
#define CONFIG_NAME "ede-desktop"
|
|
|
|
#define ICONS_CONFIG_NAME "ede-desktop-icons"
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2008-10-02 13:42:19 +04:00
|
|
|
#define EDE_DESKTOP_INTERFACE "org.equinoxproject.Desktop"
|
|
|
|
#define EDE_DESKTOP_OBJECT "/org/equinoxproject/Desktop"
|
2008-04-07 19:35:02 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
#define SELECTION_SINGLE (Fl::event_button() == 1)
|
2007-06-29 15:22:29 +04:00
|
|
|
#define SELECTION_MULTI (Fl::event_button() == 1 && (Fl::event_key(FL_Shift_L) || Fl::event_key(FL_Shift_R)))
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
#undef MIN
|
2007-05-23 16:43:50 +04:00
|
|
|
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
2007-11-06 17:33:19 +03:00
|
|
|
#undef MAX
|
2007-05-23 16:43:50 +04:00
|
|
|
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
|
|
|
|
2009-12-24 18:47:29 +03:00
|
|
|
/*
|
|
|
|
* Which widgets Fl::belowmouse() should skip.
|
|
|
|
* This should be updated when new non-icon child is added to Desktop window
|
2007-06-19 13:59:15 +04:00
|
|
|
*/
|
2007-07-02 14:28:18 +04:00
|
|
|
#define NOT_SELECTABLE(widget) ((widget == this) || (widget == wallpaper) || (widget == dmenu))
|
|
|
|
|
2011-10-24 19:30:31 +04:00
|
|
|
EDELIB_NS_USING(MenuItem)
|
|
|
|
EDELIB_NS_USING(String)
|
|
|
|
EDELIB_NS_USING(DesktopFile)
|
2012-05-07 12:53:13 +04:00
|
|
|
EDELIB_NS_USING(DirWatch)
|
|
|
|
EDELIB_NS_USING(Resource)
|
2011-10-24 19:30:31 +04:00
|
|
|
EDELIB_NS_USING(run_async)
|
2012-04-23 16:43:20 +04:00
|
|
|
EDELIB_NS_USING(input)
|
|
|
|
EDELIB_NS_USING(alert)
|
|
|
|
EDELIB_NS_USING(dir_create)
|
2011-10-24 19:30:31 +04:00
|
|
|
EDELIB_NS_USING(foreign_callback_add)
|
|
|
|
EDELIB_NS_USING(foreign_callback_remove)
|
2009-12-24 18:47:29 +03:00
|
|
|
EDELIB_NS_USING(window_xid_create)
|
|
|
|
EDELIB_NS_USING(netwm_workspace_get_names)
|
|
|
|
EDELIB_NS_USING(netwm_workspace_free_names)
|
|
|
|
EDELIB_NS_USING(netwm_workspace_get_current)
|
|
|
|
EDELIB_NS_USING(netwm_workarea_get_size)
|
|
|
|
EDELIB_NS_USING(netwm_window_set_type)
|
|
|
|
EDELIB_NS_USING(netwm_callback_add)
|
|
|
|
EDELIB_NS_USING(netwm_callback_remove)
|
2011-11-09 18:08:11 +04:00
|
|
|
EDELIB_NS_USING(font_cache_find)
|
2012-05-07 12:53:13 +04:00
|
|
|
EDELIB_NS_USING(file_test)
|
2012-05-10 15:19:19 +04:00
|
|
|
EDELIB_NS_USING(file_remove)
|
2012-05-07 12:53:13 +04:00
|
|
|
EDELIB_NS_USING(dir_home)
|
|
|
|
EDELIB_NS_USING(build_filename)
|
|
|
|
EDELIB_NS_USING(FILE_TEST_IS_DIR)
|
|
|
|
EDELIB_NS_USING(FILE_TEST_IS_REGULAR)
|
2009-12-24 18:47:29 +03:00
|
|
|
EDELIB_NS_USING(NETWM_WINDOW_TYPE_DESKTOP)
|
|
|
|
EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKAREA)
|
|
|
|
EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKSPACE)
|
2012-05-07 12:53:13 +04:00
|
|
|
EDELIB_NS_USING(DW_CREATE)
|
|
|
|
EDELIB_NS_USING(DW_MODIFY)
|
|
|
|
EDELIB_NS_USING(DW_RENAME)
|
|
|
|
EDELIB_NS_USING(DW_DELETE)
|
2009-12-24 18:47:29 +03:00
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
static void background_conf_cb(Fl_Widget*, void*);
|
|
|
|
static void icons_conf_cb(Fl_Widget*, void*);
|
2012-04-23 16:43:20 +04:00
|
|
|
static void folder_create_cb(Fl_Widget*, void*);
|
2012-04-25 20:28:09 +04:00
|
|
|
static void launcher_create_cb(Fl_Widget*, void*);
|
2007-11-06 17:33:19 +03:00
|
|
|
|
2012-07-19 12:23:42 +04:00
|
|
|
static MenuItem desktop_menu[] = {
|
2012-04-25 20:28:09 +04:00
|
|
|
{_("Create &launcher..."), 0, launcher_create_cb},
|
2012-04-23 16:43:20 +04:00
|
|
|
{_("Create &folder..."), 0, folder_create_cb, 0, FL_MENU_DIVIDER},
|
2009-07-09 17:26:59 +04:00
|
|
|
{_("&Icons settings..."), 0, icons_conf_cb, 0},
|
|
|
|
{_("&Background..."), 0, background_conf_cb, 0},
|
2007-07-02 14:28:18 +04:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2007-05-24 16:53:03 +04:00
|
|
|
Desktop* Desktop::pinstance = NULL;
|
2008-08-07 18:22:05 +04:00
|
|
|
static bool running = false;
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
inline unsigned int random_pos(int max) {
|
|
|
|
return (rand() % max);
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-23 16:43:50 +04:00
|
|
|
inline bool intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
|
|
|
|
return (MAX(x1, x2) <= MIN(w1, w2) &&
|
|
|
|
MAX(y1, y2) <= MIN(h1, h2));
|
|
|
|
}
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
static void exit_signal(int signum) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": Exiting (got signal %d)\n", signum);
|
2007-05-22 18:53:17 +04:00
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
|
2009-12-24 18:47:29 +03:00
|
|
|
static void make_me_desktop(Fl_Window *win) {
|
|
|
|
netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DESKTOP);
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
static void dir_watch_cb(const char* dir, const char* changed, int flags, void* data) {
|
2007-09-03 16:26:58 +04:00
|
|
|
Desktop::instance()->dir_watch(dir, changed, flags);
|
|
|
|
}
|
|
|
|
|
2009-11-13 14:53:02 +03:00
|
|
|
static void settings_changed_cb(Fl_Window *win, void *data) {
|
2007-11-06 17:33:19 +03:00
|
|
|
Desktop::instance()->read_config();
|
|
|
|
Desktop::instance()->redraw();
|
|
|
|
}
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
static void background_conf_cb(Fl_Widget*, void*) {
|
2011-10-24 19:30:31 +04:00
|
|
|
run_async("ede-launch ede-desktop-conf");
|
2007-11-06 17:33:19 +03:00
|
|
|
}
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
static void icons_conf_cb(Fl_Widget*, void*) {
|
2011-10-24 19:30:31 +04:00
|
|
|
run_async("ede-launch ede-desktop-conf --icons");
|
2007-11-06 17:33:19 +03:00
|
|
|
}
|
|
|
|
|
2012-04-23 16:43:20 +04:00
|
|
|
static void folder_create_cb(Fl_Widget*, void*) {
|
|
|
|
const char *n = input(_("New folder with name"));
|
|
|
|
if(!n) return;
|
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
String h = dir_home();
|
|
|
|
String dp = build_filename(h.c_str(), "Desktop", n);
|
2012-04-23 16:43:20 +04:00
|
|
|
|
|
|
|
if(!dir_create(dp.c_str()))
|
|
|
|
alert(_("Unable to create directory '%s'! Please check if directory already exists or you have enough permissions to create it"), dp.c_str());
|
|
|
|
}
|
|
|
|
|
2012-04-25 20:28:09 +04:00
|
|
|
static void launcher_create_cb(Fl_Widget*, void*) {
|
|
|
|
icon_dialog_icon_create();
|
|
|
|
}
|
|
|
|
|
2009-12-24 18:47:29 +03:00
|
|
|
static void desktop_message_handler(int action, Window xid, void *data) {
|
|
|
|
switch(action) {
|
|
|
|
case NETWM_CHANGED_CURRENT_WORKSPACE:
|
2007-06-19 13:59:15 +04:00
|
|
|
Desktop::instance()->notify_desktop_changed();
|
2009-12-24 18:47:29 +03:00
|
|
|
break;
|
|
|
|
case NETWM_CHANGED_CURRENT_WORKAREA:
|
2007-06-20 14:58:07 +04:00
|
|
|
Desktop::instance()->update_workarea();
|
2009-12-24 18:47:29 +03:00
|
|
|
break;
|
2007-06-19 13:59:15 +04:00
|
|
|
}
|
|
|
|
}
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2011-10-18 12:45:55 +04:00
|
|
|
Desktop::Desktop() : EDE_DESKTOP_WINDOW(0, 0, 100, 100, "") {
|
2007-06-18 18:18:35 +04:00
|
|
|
selection_x = selection_y = 0;
|
2012-04-23 16:43:20 +04:00
|
|
|
last_px = last_py = -1;
|
2007-06-18 18:18:35 +04:00
|
|
|
moving = false;
|
2007-09-03 16:26:58 +04:00
|
|
|
do_dirwatch = true;
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
#ifdef USE_EDELIB_WINDOW
|
2011-10-24 19:30:31 +04:00
|
|
|
foreign_callback_add(this, "ede-desktop", settings_changed_cb);
|
2011-10-18 12:45:55 +04:00
|
|
|
/* EDE_DESKTOP_WINDOW::single_bufer(true); */
|
2007-11-06 17:33:19 +03:00
|
|
|
#endif
|
|
|
|
|
2007-06-25 13:20:49 +04:00
|
|
|
selbox = new SelectionOverlay;
|
|
|
|
selbox->x = selbox->y = selbox->w = selbox->h = 0;
|
|
|
|
selbox->show = false;
|
|
|
|
|
2008-10-02 13:42:19 +04:00
|
|
|
gisett = new GlobalIconSettings;
|
2009-03-26 20:05:44 +03:00
|
|
|
/* gnome light blue */
|
2008-10-02 13:42:19 +04:00
|
|
|
gisett->label_background = 138;
|
|
|
|
gisett->label_foreground = FL_WHITE;
|
2011-11-09 18:08:11 +04:00
|
|
|
gisett->label_font = FL_HELVETICA;
|
2008-10-02 13:42:19 +04:00
|
|
|
gisett->label_fontsize = 12;
|
|
|
|
gisett->label_maxwidth = 75;
|
2009-10-08 16:46:45 +04:00
|
|
|
gisett->label_transparent = true;
|
2008-10-02 13:42:19 +04:00
|
|
|
gisett->label_draw = true;
|
|
|
|
gisett->one_click_exec = false;
|
|
|
|
gisett->auto_arrange = true;
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* default background color */
|
2009-10-08 16:46:45 +04:00
|
|
|
color(fl_rgb_color(73, 64, 102));
|
2007-06-29 15:22:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Desktop::~Desktop() {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG("Desktop::~Desktop()\n");
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2008-08-10 21:49:38 +04:00
|
|
|
save_icons_positions();
|
2007-11-06 17:33:19 +03:00
|
|
|
|
2008-10-02 13:42:19 +04:00
|
|
|
delete gisett;
|
2007-06-29 15:22:29 +04:00
|
|
|
delete selbox;
|
2008-04-07 19:35:02 +04:00
|
|
|
delete dbus;
|
2007-09-03 16:26:58 +04:00
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
DirWatch::shutdown();
|
2011-10-24 19:30:31 +04:00
|
|
|
foreign_callback_remove(settings_changed_cb);
|
2007-06-29 15:22:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void Desktop::init_internals(void) {
|
2007-05-22 18:53:17 +04:00
|
|
|
update_workarea();
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
/*
|
2008-10-03 14:14:57 +04:00
|
|
|
* NOTE: order how childs are added is important. First non iconable ones should be
|
|
|
|
* added (wallpaper, menu, ...) then icons, so they can be drawn at top of them.
|
2007-06-18 18:18:35 +04:00
|
|
|
*/
|
2007-05-22 18:53:17 +04:00
|
|
|
begin();
|
2009-07-09 17:26:59 +04:00
|
|
|
dmenu = new edelib::MenuButton(0, 0, 500, 0);
|
2007-07-02 14:28:18 +04:00
|
|
|
dmenu->menu(desktop_menu);
|
2009-07-09 17:26:59 +04:00
|
|
|
desktop_menu[1].image(edelib::IconLoader::get("folder", edelib::ICON_SIZE_TINY));
|
2007-06-18 18:18:35 +04:00
|
|
|
wallpaper = new Wallpaper(0, 0, w(), h());
|
2007-05-22 18:53:17 +04:00
|
|
|
end();
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2008-04-07 19:35:02 +04:00
|
|
|
dbus = new edelib::EdbusConnection();
|
|
|
|
if(!dbus->connect(edelib::EDBUS_SESSION)) {
|
2009-03-26 20:05:44 +03:00
|
|
|
E_WARNING(E_STRLOC ": Unable to connect to session bus. Disabling dbus interface...\n");
|
2008-04-07 19:35:02 +04:00
|
|
|
delete dbus;
|
|
|
|
dbus = NULL;
|
|
|
|
}
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* read main config */
|
2007-06-18 18:18:35 +04:00
|
|
|
read_config();
|
2012-05-07 12:53:13 +04:00
|
|
|
/* location of Desktop folder */
|
|
|
|
desktop_dir_path = build_filename(dir_home().c_str(), "Desktop");
|
2007-07-02 14:28:18 +04:00
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
if(file_test(desktop_dir_path.c_str(), FILE_TEST_IS_DIR)) {
|
|
|
|
/* now try load icons from "Desktop" directory */
|
|
|
|
load_icons(desktop_dir_path.c_str());
|
2007-11-28 15:42:52 +03:00
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
/* setup watcher used for Desktop directory */
|
|
|
|
DirWatch::init();
|
2007-11-28 15:42:52 +03:00
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
if(!DirWatch::add(desktop_dir_path.c_str(), DW_CREATE | DW_MODIFY | DW_RENAME | DW_DELETE))
|
|
|
|
E_WARNING(E_STRLOC ": Unable to watch %s\n", desktop_dir_path.c_str());
|
|
|
|
else
|
|
|
|
DirWatch::callback(dir_watch_cb);
|
2007-11-28 15:42:52 +03:00
|
|
|
}
|
2007-11-06 17:33:19 +03:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
running = true;
|
|
|
|
}
|
2007-05-25 21:45:17 +04:00
|
|
|
|
2007-05-24 16:53:03 +04:00
|
|
|
void Desktop::init(void) {
|
|
|
|
if(Desktop::pinstance != NULL)
|
|
|
|
return;
|
2007-11-06 17:33:19 +03:00
|
|
|
|
2007-05-24 16:53:03 +04:00
|
|
|
Desktop::pinstance = new Desktop();
|
2007-06-29 15:22:29 +04:00
|
|
|
Desktop::pinstance->init_internals();
|
2007-05-24 16:53:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void Desktop::shutdown(void) {
|
|
|
|
if(Desktop::pinstance == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
delete Desktop::pinstance;
|
|
|
|
Desktop::pinstance = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Desktop* Desktop::instance(void) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(Desktop::pinstance != NULL && "Desktop::init() should be run first");
|
2007-05-24 16:53:03 +04:00
|
|
|
return Desktop::pinstance;
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
void Desktop::show(void) {
|
2009-12-24 18:47:29 +03:00
|
|
|
if(shown())
|
2011-10-18 12:45:55 +04:00
|
|
|
return EDE_DESKTOP_WINDOW::show();
|
2009-12-24 18:47:29 +03:00
|
|
|
|
|
|
|
window_xid_create(this, make_me_desktop);
|
2007-05-22 18:53:17 +04:00
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* If someone intentionaly hide desktop then quit from it */
|
2007-06-18 18:18:35 +04:00
|
|
|
void Desktop::hide(void) {
|
|
|
|
running = false;
|
2007-05-24 16:53:03 +04:00
|
|
|
}
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
void Desktop::update_workarea(void) {
|
|
|
|
int X, Y, W, H;
|
2009-12-24 18:47:29 +03:00
|
|
|
|
|
|
|
if(!netwm_workarea_get_size(X, Y, W, H)) {
|
2009-03-26 20:05:44 +03:00
|
|
|
E_DEBUG(E_STRLOC ": wm does not support _NET_WM_WORKAREA; using screen sizes...\n");
|
2012-04-23 16:43:20 +04:00
|
|
|
Fl::screen_xywh(X, Y, W, H);
|
2007-06-18 18:18:35 +04:00
|
|
|
}
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
resize(X, Y, W, H);
|
2007-05-24 16:53:03 +04:00
|
|
|
}
|
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
void Desktop::read_config(void) {
|
2012-05-07 12:53:13 +04:00
|
|
|
Resource conf;
|
2009-03-26 20:05:44 +03:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
if(!conf.load(CONFIG_NAME)) {
|
2009-03-26 20:05:44 +03:00
|
|
|
E_WARNING(E_STRLOC ": Can't load %s, using default values\n", CONFIG_NAME);
|
2007-05-22 18:53:17 +04:00
|
|
|
return;
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
bool wuse;
|
2011-11-09 18:08:11 +04:00
|
|
|
char wpath[PATH_MAX], font_name[64];
|
2009-03-26 20:05:44 +03:00
|
|
|
int bcolor, wmode;
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2009-10-08 16:46:45 +04:00
|
|
|
/* use nice darker blue color as default for background */
|
|
|
|
conf.get("Desktop", "color", bcolor, fl_rgb_color(73, 64, 102));
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
conf.get("Desktop", "wallpaper_use", wuse, false);
|
2008-10-02 13:42:19 +04:00
|
|
|
conf.get("Desktop", "wallpaper", wpath, sizeof(wpath));
|
2009-03-26 20:05:44 +03:00
|
|
|
conf.get("Desktop", "wallpaper_mode", wmode, WALLPAPER_CENTER);
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* '138' is gnome light blue */
|
2008-10-02 13:42:19 +04:00
|
|
|
conf.get("Icons", "label_background", gisett->label_background, 138);
|
|
|
|
conf.get("Icons", "label_foreground", gisett->label_foreground, FL_WHITE);
|
|
|
|
conf.get("Icons", "label_maxwidth", gisett->label_maxwidth, 75);
|
2009-10-08 16:46:45 +04:00
|
|
|
conf.get("Icons", "label_transparent",gisett->label_transparent, true);
|
2008-10-02 13:42:19 +04:00
|
|
|
conf.get("Icons", "label_visible", gisett->label_draw, true);
|
|
|
|
conf.get("Icons", "one_click_exec", gisett->one_click_exec, false);
|
|
|
|
conf.get("Icons", "auto_arrange", gisett->auto_arrange, true);
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2011-11-09 18:08:11 +04:00
|
|
|
/* try to get font */
|
|
|
|
if(conf.get("Icons", "label_font", font_name, sizeof(font_name))) {
|
2011-11-10 18:20:58 +04:00
|
|
|
font_cache_find(font_name, (Fl_Font&)gisett->label_font,
|
2011-11-10 13:17:40 +04:00
|
|
|
gisett->label_fontsize,
|
|
|
|
(Fl_Font)gisett->label_font,
|
|
|
|
gisett->label_fontsize);
|
2011-11-09 18:08:11 +04:00
|
|
|
}
|
|
|
|
|
2009-11-28 01:26:25 +03:00
|
|
|
/* minimal allowed font size */
|
|
|
|
if(gisett->label_fontsize < 8)
|
|
|
|
gisett->label_fontsize = 12;
|
|
|
|
|
|
|
|
/* minimal allowed maxwidth size */
|
|
|
|
if(gisett->label_maxwidth < 30)
|
|
|
|
gisett->label_maxwidth = 75;
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* prevent wild values */
|
|
|
|
if(wmode != WALLPAPER_CENTER && wmode != WALLPAPER_TILE && wmode != WALLPAPER_STRETCH)
|
|
|
|
wmode = WALLPAPER_CENTER;
|
|
|
|
|
2009-03-26 21:20:56 +03:00
|
|
|
if(wuse) {
|
|
|
|
if(!wallpaper->load(wpath, (WallpaperState)wmode))
|
|
|
|
E_WARNING(E_STRLOC ": unable to load wallpaper '%s'\n", wpath);
|
|
|
|
else
|
|
|
|
wallpaper->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!wuse && wallpaper->visible())
|
|
|
|
wallpaper->hide();
|
2009-03-26 20:05:44 +03:00
|
|
|
|
|
|
|
/* change background color too */
|
|
|
|
color(bcolor);
|
2007-11-06 17:33:19 +03:00
|
|
|
}
|
2007-09-03 16:26:58 +04:00
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
void Desktop::load_icons(const char* path) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(path != NULL);
|
2012-05-07 12:53:13 +04:00
|
|
|
Resource conf, *conf_ptr = NULL;
|
2007-11-06 17:33:19 +03:00
|
|
|
|
|
|
|
if(!conf.load(ICONS_CONFIG_NAME))
|
2009-10-07 18:38:48 +04:00
|
|
|
E_WARNING(E_STRLOC ": Can't load icons positions; arranging them somehow...\n");
|
2007-11-06 17:33:19 +03:00
|
|
|
else
|
|
|
|
conf_ptr = &conf;
|
|
|
|
|
|
|
|
StringList lst;
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* list with full path; icon basename is extracted in add_icon_by_path() */
|
2007-09-03 16:26:58 +04:00
|
|
|
if(!dir_list(path, lst, true)) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": Can't read %s\n", path);
|
2007-05-22 18:53:17 +04:00
|
|
|
return;
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
StringListIter it, it_end;
|
2007-09-03 16:26:58 +04:00
|
|
|
for(it = lst.begin(), it_end = lst.end(); it != it_end; ++it)
|
2008-08-10 21:49:38 +04:00
|
|
|
add_icon_by_path((*it).c_str(), conf_ptr);
|
2009-10-07 18:38:48 +04:00
|
|
|
|
|
|
|
/* if stored locations wasn't found */
|
|
|
|
if(!conf_ptr)
|
|
|
|
auto_arrange();
|
2007-09-03 16:26:58 +04:00
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
void Desktop::save_icons_positions(void) {
|
2012-05-07 12:53:13 +04:00
|
|
|
Resource conf;
|
2009-03-27 12:40:03 +03:00
|
|
|
char* icon_base;
|
|
|
|
DesktopIconListIter it = icons.begin(), it_end = icons.end();
|
|
|
|
|
|
|
|
for(; it != it_end; ++it) {
|
|
|
|
if((*it)->path().empty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
icon_base = get_basename((*it)->path().c_str());
|
|
|
|
conf.set(icon_base, "X", (*it)->x());
|
|
|
|
conf.set(icon_base, "Y", (*it)->y());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!conf.save(ICONS_CONFIG_NAME))
|
|
|
|
E_WARNING(E_STRLOC ": Unable to store icons positions\n");
|
|
|
|
}
|
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
IconSettings* Desktop::read_desktop_file(const char* path) {
|
2009-03-27 12:40:03 +03:00
|
|
|
E_ASSERT(path != NULL);
|
|
|
|
|
2011-10-24 19:30:31 +04:00
|
|
|
DesktopFile dconf;
|
2009-03-27 12:40:03 +03:00
|
|
|
if(!dconf.load(path)) {
|
|
|
|
E_WARNING(E_STRLOC ": Can't read %s (%s)\n", path, dconf.strerror());
|
2009-05-19 15:10:23 +04:00
|
|
|
return NULL;
|
2009-03-27 12:40:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
char buf[128];
|
2009-05-19 15:10:23 +04:00
|
|
|
int bufsz = sizeof(buf);
|
|
|
|
|
|
|
|
IconSettings* is = new IconSettings;
|
2009-03-27 12:40:03 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for 'EmptyIcon' key since via it is determined is icon trash type or not
|
|
|
|
* (in case of trash, 'Icon' key is used for full trash).
|
|
|
|
*
|
|
|
|
* FIXME: any other way to check for trash icons ???
|
|
|
|
*/
|
|
|
|
if(dconf.get("Desktop Entry", "EmptyIcon", buf, bufsz)) {
|
2009-05-19 15:10:23 +04:00
|
|
|
is->type = ICON_TRASH;
|
|
|
|
is->icon = buf;
|
2009-03-27 12:40:03 +03:00
|
|
|
} else
|
2009-05-19 15:10:23 +04:00
|
|
|
is->type = ICON_NORMAL;
|
2009-03-27 12:40:03 +03:00
|
|
|
|
|
|
|
if(!dconf.icon(buf, bufsz)) {
|
|
|
|
E_WARNING(E_STRLOC ": No Icon key, balling out\n");
|
2009-05-19 15:10:23 +04:00
|
|
|
|
|
|
|
delete is;
|
|
|
|
return NULL;
|
2009-03-27 12:40:03 +03:00
|
|
|
}
|
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
if(is->type == ICON_TRASH)
|
|
|
|
is->icon2 = buf;
|
2009-03-27 12:40:03 +03:00
|
|
|
else
|
2009-05-19 15:10:23 +04:00
|
|
|
is->icon = buf;
|
2009-03-27 12:40:03 +03:00
|
|
|
|
2009-05-20 19:04:32 +04:00
|
|
|
if(dconf.type() == edelib::DESK_FILE_TYPE_LINK) {
|
2009-05-19 15:10:23 +04:00
|
|
|
is->cmd_is_url = true;
|
2009-03-27 12:40:03 +03:00
|
|
|
dconf.url(buf, bufsz);
|
|
|
|
}
|
|
|
|
else {
|
2009-05-19 15:10:23 +04:00
|
|
|
is->cmd_is_url = false;
|
2009-03-27 12:40:03 +03:00
|
|
|
dconf.exec(buf, bufsz);
|
|
|
|
}
|
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
is->cmd = buf;
|
2009-03-27 12:40:03 +03:00
|
|
|
|
|
|
|
if(!dconf.name(buf, bufsz)) {
|
|
|
|
E_DEBUG(E_STRLOC ": No Name key\n");
|
2009-05-20 19:04:32 +04:00
|
|
|
is->name = _("(none)");
|
2009-03-27 12:40:03 +03:00
|
|
|
} else
|
2009-05-19 15:10:23 +04:00
|
|
|
is->name = buf;
|
2009-03-27 12:40:03 +03:00
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
return is;
|
2009-03-27 12:40:03 +03:00
|
|
|
}
|
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
bool Desktop::add_icon_by_path(const char* path, Resource* conf) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(path != NULL);
|
2007-09-03 16:26:58 +04:00
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
IconSettings* is = NULL;
|
2007-09-03 16:26:58 +04:00
|
|
|
const char* base = get_basename(path);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
/*
|
|
|
|
* see is possible .desktop file; icon, name fields are filled from read_desktop_file()
|
|
|
|
*
|
2009-03-26 20:05:44 +03:00
|
|
|
* FIXME: maybe the good thing is to use MimeType to check .desktop; extension does not have
|
|
|
|
* to be always present, or .desktop does not have to be Desktop File at all
|
2007-09-03 16:26:58 +04:00
|
|
|
*/
|
|
|
|
if(edelib::str_ends(path, ".desktop")) {
|
2009-05-19 15:10:23 +04:00
|
|
|
is = read_desktop_file(path);
|
2007-09-03 16:26:58 +04:00
|
|
|
} else {
|
|
|
|
edelib::MimeType mt;
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* then try to figure out it's mime; if fails, ignore it */
|
2007-09-03 16:26:58 +04:00
|
|
|
if(mt.set(path)) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": Loading icon as mime-type %s\n", mt.icon_name().c_str());
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
is = new IconSettings;
|
|
|
|
is->icon = mt.icon_name();
|
|
|
|
/* icon label path's basename */
|
|
|
|
is->name = base;
|
|
|
|
is->type = ICON_FILE;
|
2007-09-03 16:26:58 +04:00
|
|
|
}
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
if(!is)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* key_name is section in config file with icon X/Y values
|
|
|
|
* FIXME: this should be named 'section_name'
|
|
|
|
*/
|
|
|
|
is->key_name = base;
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
/* random_pos() is used if X/Y keys are not found */
|
|
|
|
int icon_x = random_pos(w() - 10);
|
|
|
|
int icon_y = random_pos(w() - 10);
|
2007-09-03 16:26:58 +04:00
|
|
|
|
2012-04-23 16:43:20 +04:00
|
|
|
/* assign if we have it */
|
|
|
|
if(last_px != -1 && last_py != -1) {
|
|
|
|
icon_x = last_px;
|
|
|
|
icon_y = last_py;
|
|
|
|
|
|
|
|
last_px = last_py = -1;
|
|
|
|
}
|
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
if(conf) {
|
2012-04-23 16:43:20 +04:00
|
|
|
/* we load positions from used ede-desktop-icons.conf only */
|
2009-05-19 15:10:23 +04:00
|
|
|
conf->get(base, "X", icon_x, icon_x, edelib::RES_USER_ONLY);
|
|
|
|
conf->get(base, "Y", icon_y, icon_y, edelib::RES_USER_ONLY);
|
2007-09-03 16:26:58 +04:00
|
|
|
}
|
|
|
|
|
2009-05-19 15:10:23 +04:00
|
|
|
E_DEBUG(E_STRLOC ": %s found with: %i %i\n", base, icon_x, icon_y);
|
|
|
|
is->x = icon_x;
|
|
|
|
is->y = icon_y;
|
|
|
|
is->full_path = path;
|
|
|
|
|
|
|
|
DesktopIcon* dic = new DesktopIcon(gisett, is, color());
|
|
|
|
add_icon(dic);
|
|
|
|
|
|
|
|
return true;
|
2007-09-03 16:26:58 +04:00
|
|
|
}
|
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
DesktopIcon* Desktop::find_icon_by_path(const char* path, DesktopIconListIter* ret) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(path != NULL);
|
2007-09-03 16:26:58 +04:00
|
|
|
|
|
|
|
if(icons.empty())
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
DesktopIconListIter it, it_end;
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
|
|
|
if((*it)->path() == path) {
|
2009-03-27 12:40:03 +03:00
|
|
|
/* store iterator */
|
|
|
|
if(ret)
|
|
|
|
*ret = it;
|
2007-09-03 16:26:58 +04:00
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
/* return iterator value */
|
|
|
|
return (*it);
|
|
|
|
}
|
2007-09-03 16:26:58 +04:00
|
|
|
}
|
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
return NULL;
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
bool Desktop::remove_icon(DesktopIcon *d, bool real_delete) {
|
2012-05-10 15:19:19 +04:00
|
|
|
bool ret = true;
|
|
|
|
|
2012-05-15 16:49:16 +04:00
|
|
|
if(real_delete) {
|
|
|
|
dir_watch_off();
|
2012-05-10 15:19:19 +04:00
|
|
|
ret = file_remove(d->path().c_str());
|
2012-05-15 16:49:16 +04:00
|
|
|
Fl::wait(1);
|
|
|
|
dir_watch_on();
|
|
|
|
}
|
2012-05-10 15:19:19 +04:00
|
|
|
|
|
|
|
remove_icon_by_path(d->path().c_str());
|
2012-05-15 16:49:16 +04:00
|
|
|
/* TODO: reimplement as 'fast_redraw()' from DesktopIcon */
|
|
|
|
redraw();
|
2012-05-07 12:53:13 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-05-15 15:10:40 +04:00
|
|
|
bool Desktop::rename_icon(DesktopIcon *d, const char *n) {
|
|
|
|
DesktopFile f;
|
|
|
|
const char *p = d->path().c_str();
|
|
|
|
|
|
|
|
E_RETURN_VAL_IF_FAIL(f.load(p), false);
|
|
|
|
|
|
|
|
dir_watch_off();
|
|
|
|
f.set_name(n);
|
|
|
|
bool ret = f.save(p);
|
|
|
|
dir_watch_on();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
bool Desktop::remove_icon_by_path(const char* path) {
|
|
|
|
DesktopIconListIter pos;
|
|
|
|
DesktopIcon* ic = find_icon_by_path(path, &pos);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
if(!ic) {
|
2012-05-07 12:53:13 +04:00
|
|
|
E_DEBUG(E_STRLOC ": Didn't find '%s' as path marked for removal\n", path);
|
2007-05-22 18:53:17 +04:00
|
|
|
return false;
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
icons.erase(pos);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
/* Fl_Group::remove() does not delete child, just pops it out */
|
|
|
|
remove(ic);
|
|
|
|
delete ic;
|
|
|
|
return true;
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-10-07 18:38:48 +04:00
|
|
|
void Desktop::auto_arrange(void) {
|
|
|
|
DesktopIcon* ic;
|
|
|
|
DesktopIconListIter it, it_end;
|
|
|
|
|
|
|
|
int X = (gisett->label_maxwidth / 5) + 10;
|
|
|
|
int Y = 10;
|
|
|
|
int H = h();
|
|
|
|
|
|
|
|
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
|
|
|
ic = (*it);
|
|
|
|
|
|
|
|
ic->position(X, Y);
|
|
|
|
Y += ic->h() + (ic->h() / 2);
|
|
|
|
|
|
|
|
if(Y + (ic->h() / 2) > H) {
|
|
|
|
Y = 10;
|
|
|
|
X += gisett->label_maxwidth + (ic->w() / 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
void Desktop::add_icon(DesktopIcon* ic) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(ic != NULL);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
icons.push_back(ic);
|
2007-06-18 18:18:35 +04:00
|
|
|
add((Fl_Widget*)ic);
|
2007-05-22 18:53:17 +04:00
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
void Desktop::unfocus_all(void) {
|
|
|
|
DesktopIcon* ic;
|
2007-09-03 16:26:58 +04:00
|
|
|
DesktopIconListIter it, it_end;
|
|
|
|
|
|
|
|
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
|
|
|
ic = (*it);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
if(ic->is_focused()) {
|
|
|
|
ic->do_unfocus();
|
|
|
|
ic->fast_redraw();
|
2007-05-22 18:53:17 +04:00
|
|
|
}
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
void Desktop::select(DesktopIcon* ic, bool do_redraw) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(ic != NULL);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
if(in_selection(ic))
|
|
|
|
return;
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2009-03-26 21:09:20 +03:00
|
|
|
selectionbuf.push_back(ic);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
if(!ic->is_focused()) {
|
|
|
|
ic->do_focus();
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
if(do_redraw)
|
|
|
|
ic->fast_redraw();
|
2007-05-22 18:53:17 +04:00
|
|
|
}
|
2007-05-23 16:43:50 +04:00
|
|
|
}
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
void Desktop::select_only(DesktopIcon* ic) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(ic != NULL);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
unfocus_all();
|
2009-03-26 21:09:20 +03:00
|
|
|
selectionbuf.clear();
|
|
|
|
selectionbuf.push_back(ic);
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
ic->do_focus();
|
2007-06-18 18:18:35 +04:00
|
|
|
ic->fast_redraw();
|
|
|
|
}
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
bool Desktop::in_selection(const DesktopIcon* ic) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(ic != NULL);
|
2007-06-18 18:18:35 +04:00
|
|
|
|
2009-03-26 21:09:20 +03:00
|
|
|
if(selectionbuf.empty())
|
2007-09-03 16:26:58 +04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
DesktopIconListIter it, it_end;
|
|
|
|
|
2009-03-26 21:09:20 +03:00
|
|
|
for(it = selectionbuf.begin(), it_end = selectionbuf.end(); it != it_end; ++it) {
|
2007-09-03 16:26:58 +04:00
|
|
|
if((*it) == ic)
|
2007-06-18 18:18:35 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
void Desktop::move_selection(int x, int y, bool apply) {
|
2009-03-26 21:09:20 +03:00
|
|
|
if(selectionbuf.empty())
|
2007-05-23 16:43:50 +04:00
|
|
|
return;
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
int prev_x, prev_y, tmp_x, tmp_y;
|
|
|
|
DesktopIcon* ic;
|
2007-05-23 16:43:50 +04:00
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
DesktopIconListIter it, it_end;
|
|
|
|
|
2009-03-26 21:09:20 +03:00
|
|
|
for(it = selectionbuf.begin(), it_end = selectionbuf.end(); it != it_end; ++it) {
|
2007-09-03 16:26:58 +04:00
|
|
|
ic = (*it);
|
2007-05-23 16:43:50 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
prev_x = ic->drag_icon_x();
|
|
|
|
prev_y = ic->drag_icon_y();
|
2007-05-23 16:43:50 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
tmp_x = x - selection_x;
|
|
|
|
tmp_y = y - selection_y;
|
2007-05-23 16:43:50 +04:00
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
ic->drag(prev_x + tmp_x, prev_y + tmp_y, apply);
|
2009-03-26 20:05:44 +03:00
|
|
|
#if 0
|
2007-06-18 18:18:35 +04:00
|
|
|
// very slow if not checked
|
2009-03-26 20:05:44 +03:00
|
|
|
if(apply == true)
|
|
|
|
ic->fast_redraw();
|
|
|
|
#endif
|
2007-05-23 16:43:50 +04:00
|
|
|
}
|
2007-06-18 18:18:35 +04:00
|
|
|
|
|
|
|
selection_x = x;
|
|
|
|
selection_y = y;
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* Redraw whole screen so it reflects new icon position */
|
2007-06-18 18:18:35 +04:00
|
|
|
if(apply)
|
|
|
|
redraw();
|
2007-05-23 16:43:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-03-27 12:40:03 +03:00
|
|
|
* Tries to figure out icon below mouse. It is alternative to Fl::belowmouse() since with this we hunt
|
|
|
|
* only icons, not other childs (wallpaper, menu), which can be returned by Fl::belowmouse() and bad
|
|
|
|
* things be hapened.
|
2007-05-23 16:43:50 +04:00
|
|
|
*/
|
|
|
|
DesktopIcon* Desktop::below_mouse(int px, int py) {
|
|
|
|
DesktopIcon* ic = NULL;
|
2007-09-03 16:26:58 +04:00
|
|
|
DesktopIconListIter it, it_end;
|
|
|
|
|
|
|
|
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
|
|
|
ic = (*it);
|
2007-05-23 16:43:50 +04:00
|
|
|
if(ic->x() < px && ic->y() < py && px < (ic->x() + ic->h()) && py < (ic->y() + ic->h()))
|
|
|
|
return ic;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2007-06-25 13:20:49 +04:00
|
|
|
void Desktop::select_in_area(void) {
|
|
|
|
if(!selbox->show)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int ax = selbox->x;
|
|
|
|
int ay = selbox->y;
|
|
|
|
int aw = selbox->w;
|
|
|
|
int ah = selbox->h;
|
|
|
|
|
|
|
|
if(aw < 0) {
|
|
|
|
ax += aw;
|
|
|
|
aw = -aw;
|
|
|
|
} else if(!aw)
|
|
|
|
aw = 1;
|
|
|
|
|
|
|
|
if(ah < 0) {
|
|
|
|
ay += ah;
|
|
|
|
ah = -ah;
|
|
|
|
} else if(!ah)
|
|
|
|
ah = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX: This function can fail since icon coordinates are absolute (event_x_root)
|
|
|
|
* but selbox use relative (event_root). It will work as expected if desktop is at x=0 y=0.
|
|
|
|
* This should be checked further.
|
|
|
|
*/
|
|
|
|
DesktopIcon* ic = NULL;
|
2007-09-03 16:26:58 +04:00
|
|
|
DesktopIconListIter it, it_end;
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
|
|
|
ic = (*it);
|
2008-08-07 18:22:05 +04:00
|
|
|
E_ASSERT(ic != NULL && "Impossible to happen");
|
2007-06-25 13:20:49 +04:00
|
|
|
|
|
|
|
if(intersects(ax, ay, ax+aw, ay+ah, ic->x(), ic->y(), ic->w()+ic->x(), ic->h()+ic->y())) {
|
|
|
|
if(!ic->is_focused()) {
|
|
|
|
ic->do_focus();
|
2012-05-07 12:53:13 +04:00
|
|
|
/* updated from Desktop::draw() */
|
2007-06-26 20:33:25 +04:00
|
|
|
ic->damage(EDAMAGE_CHILD_LABEL);
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(ic->is_focused()) {
|
|
|
|
ic->do_unfocus();
|
2012-05-07 12:53:13 +04:00
|
|
|
/* updated from Desktop::draw() */
|
2007-07-02 14:28:18 +04:00
|
|
|
ic->fast_redraw();
|
|
|
|
//ic->damage(EDAMAGE_CHILD_LABEL);
|
|
|
|
//ic->redraw();
|
|
|
|
//ic->damage(EDAMAGE_CHILD_LABEL);
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-19 13:59:15 +04:00
|
|
|
void Desktop::notify_desktop_changed(void) {
|
2009-12-24 18:47:29 +03:00
|
|
|
int num = netwm_workspace_get_current();
|
2007-06-19 13:59:15 +04:00
|
|
|
if(num == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
char** names;
|
2009-12-24 18:47:29 +03:00
|
|
|
int ret = netwm_workspace_get_names(names);
|
2007-11-06 17:33:19 +03:00
|
|
|
if(!ret)
|
|
|
|
return;
|
|
|
|
|
2007-06-19 13:59:15 +04:00
|
|
|
if(num >= ret) {
|
2009-12-24 18:47:29 +03:00
|
|
|
netwm_workspace_free_names(names);
|
2007-06-19 13:59:15 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-04-07 19:35:02 +04:00
|
|
|
if(dbus) {
|
|
|
|
edelib::EdbusMessage msg;
|
2009-03-27 12:40:03 +03:00
|
|
|
/* send org.equinoxproject.Desktop.DesktopChanged(int32, string) signal */
|
2008-10-02 13:42:19 +04:00
|
|
|
msg.create_signal(EDE_DESKTOP_OBJECT, EDE_DESKTOP_INTERFACE, "DesktopChanged");
|
2008-04-07 19:35:02 +04:00
|
|
|
msg << num << names[num];
|
|
|
|
dbus->send(msg);
|
|
|
|
}
|
|
|
|
|
2007-06-19 13:59:15 +04:00
|
|
|
XFreeStringList(names);
|
|
|
|
}
|
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
/* leaving for the future */
|
|
|
|
#if 0
|
2008-08-10 21:49:38 +04:00
|
|
|
void Desktop::dnd_drop_source(const char* src, int src_len, int x, int y) {
|
2007-06-23 15:31:36 +04:00
|
|
|
if(!src)
|
|
|
|
return;
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
if(src_len < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
char* src_copy = new char[src_len + 1];
|
|
|
|
int real_len = 0;
|
|
|
|
|
2008-08-10 21:49:38 +04:00
|
|
|
// mozilla sends UTF-16 form; for now use this hack untill some utf8 code is ready
|
2007-07-02 14:28:18 +04:00
|
|
|
for(int i = 0, j = 0; i < src_len; i++) {
|
|
|
|
if(src[i] != 0) {
|
|
|
|
src_copy[j++] = src[i];
|
|
|
|
real_len++;
|
|
|
|
}
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
2007-07-02 14:28:18 +04:00
|
|
|
src_copy[real_len] = '\0';
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
if(real_len < 1) {
|
|
|
|
delete [] src_copy;
|
|
|
|
return;
|
|
|
|
}
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": DND on Desktop, got: %s\n", src_copy);
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
// valid url's (if got) ends with \r\n, clean that
|
|
|
|
char* pp = strstr(src_copy, "\r\n");
|
|
|
|
if(pp)
|
|
|
|
*pp = '\0';
|
|
|
|
|
|
|
|
char* sptr = 0;
|
|
|
|
if((real_len > 7) && (strncmp(src_copy, "file://", 7) == 0))
|
|
|
|
sptr = src_copy + 7;
|
|
|
|
else
|
|
|
|
sptr = src_copy;
|
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
if(!file_test(sptr, FILE_TEST_IS_REGULAR) || !file_test(sptr, FILE_TEST_IS_DIR)) {
|
2009-10-07 18:40:56 +04:00
|
|
|
edelib::message("Droping file content is not implemented yet ;)");
|
2007-07-02 14:28:18 +04:00
|
|
|
delete [] src_copy;
|
|
|
|
return;
|
|
|
|
}
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2007-06-23 15:31:36 +04:00
|
|
|
IconSettings is;
|
|
|
|
is.x = x;
|
|
|
|
is.y = y;
|
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
bool is_read = false;
|
2007-06-23 15:31:36 +04:00
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
if(edelib::str_ends(src_copy, ".desktop")) {
|
2011-10-24 19:30:31 +04:00
|
|
|
DesktopFile dconf;
|
2007-06-23 15:31:36 +04:00
|
|
|
|
2011-10-24 19:30:31 +04:00
|
|
|
String path = sptr;
|
|
|
|
DesktopFile dfile;
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
if(dfile.load(path.c_str())) {
|
2009-03-27 12:40:03 +03:00
|
|
|
char buf[256];
|
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
if(dfile.type() == edelib::DESK_FILE_TYPE_LINK) {
|
2009-03-27 12:40:03 +03:00
|
|
|
dfile.url(buf, 256);
|
2007-07-02 14:28:18 +04:00
|
|
|
is.cmd_is_url = true;
|
|
|
|
}
|
|
|
|
else {
|
2009-03-27 12:40:03 +03:00
|
|
|
dfile.exec(buf, 256);
|
2007-07-02 14:28:18 +04:00
|
|
|
is.cmd_is_url = false;
|
|
|
|
}
|
2009-03-27 12:40:03 +03:00
|
|
|
is.cmd = buf;
|
2007-07-02 14:28:18 +04:00
|
|
|
is.type = ICON_NORMAL;
|
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
dfile.name(buf, 256);
|
|
|
|
is.name = buf;
|
|
|
|
dfile.icon(buf, 256);
|
|
|
|
is.icon = buf;
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
is_read = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!is_read) {
|
2009-03-26 20:05:44 +03:00
|
|
|
/* absolute path is (for now) seen as non-url */
|
2007-07-02 14:28:18 +04:00
|
|
|
if(sptr[0] == '/')
|
|
|
|
is.cmd_is_url = false;
|
|
|
|
else
|
|
|
|
is.cmd_is_url = true;
|
|
|
|
|
|
|
|
is.cmd = "(none)";
|
|
|
|
is.type = ICON_NORMAL;
|
|
|
|
|
|
|
|
edelib::MimeType mt;
|
|
|
|
if(!mt.set(sptr)) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_WARNING(E_STRLOC ": MimeType for %s (%s) failed, not dropping icon\n", sptr, src_copy);
|
2007-07-02 14:28:18 +04:00
|
|
|
delete [] src_copy;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
is.name = get_basename(sptr);
|
|
|
|
is.icon = mt.icon_name();
|
2007-06-23 15:31:36 +04:00
|
|
|
}
|
|
|
|
|
2008-10-02 13:42:19 +04:00
|
|
|
DesktopIcon* dic = new DesktopIcon(gisett, &is, color());
|
2007-06-23 15:31:36 +04:00
|
|
|
add_icon(dic);
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
delete [] src_copy;
|
|
|
|
|
|
|
|
redraw();
|
2007-06-23 15:31:36 +04:00
|
|
|
}
|
2012-05-07 12:53:13 +04:00
|
|
|
#endif
|
2007-06-23 15:31:36 +04:00
|
|
|
|
2007-06-25 13:20:49 +04:00
|
|
|
void Desktop::draw(void) {
|
2007-07-02 14:28:18 +04:00
|
|
|
if(!damage())
|
|
|
|
return;
|
|
|
|
|
2007-06-25 13:20:49 +04:00
|
|
|
if(damage() & (FL_DAMAGE_ALL | FL_DAMAGE_EXPOSE)) {
|
2007-06-26 20:33:25 +04:00
|
|
|
/*
|
2009-03-26 20:05:44 +03:00
|
|
|
* If any overlay was previously visible during full redraw, it will not be cleared because of fast flip.
|
2007-06-26 20:33:25 +04:00
|
|
|
* This will assure that does not happened.
|
|
|
|
*/
|
|
|
|
clear_xoverlay();
|
|
|
|
|
2011-10-18 12:45:55 +04:00
|
|
|
EDE_DESKTOP_WINDOW::draw();
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": REDRAW ALL\n");
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
|
|
|
|
2007-07-02 14:28:18 +04:00
|
|
|
if(damage() & EDAMAGE_OVERLAY) {
|
|
|
|
if(selbox->show)
|
2007-06-25 13:20:49 +04:00
|
|
|
draw_xoverlay(selbox->x, selbox->y, selbox->w, selbox->h);
|
2007-07-02 14:28:18 +04:00
|
|
|
else
|
2007-06-26 20:33:25 +04:00
|
|
|
clear_xoverlay();
|
2007-06-25 13:20:49 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* now scan all icons and see if they needs redraw, and if do
|
|
|
|
* just update their label since it is indicator of selection
|
|
|
|
*/
|
|
|
|
for(int i = 0; i < children(); i++) {
|
2007-07-02 14:28:18 +04:00
|
|
|
if(child(i)->damage() == EDAMAGE_CHILD_LABEL) {
|
2007-06-25 13:20:49 +04:00
|
|
|
update_child(*child(i));
|
2007-07-02 14:28:18 +04:00
|
|
|
child(i)->clear_damage();
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": ICON REDRAW \n");
|
2007-07-02 14:28:18 +04:00
|
|
|
}
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
|
|
|
}
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
clear_damage();
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
void Desktop::dir_watch(const char* dir, const char* changed, int flags) {
|
|
|
|
if(!do_dirwatch || !changed || flags == edelib::DW_REPORT_NONE)
|
|
|
|
return;
|
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
/* skip temporary files */
|
2008-10-02 16:16:04 +04:00
|
|
|
if(is_temp_filename(changed))
|
|
|
|
return;
|
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
if(flags == edelib::DW_REPORT_CREATE) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": adding %s\n", changed);
|
2007-09-03 16:26:58 +04:00
|
|
|
|
2009-03-27 12:40:03 +03:00
|
|
|
if(find_icon_by_path(changed, 0)) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": %s already registered; skipping...\n", changed);
|
2007-09-03 16:26:58 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-08-10 21:49:38 +04:00
|
|
|
if(add_icon_by_path(changed, 0))
|
2007-09-03 16:26:58 +04:00
|
|
|
redraw();
|
|
|
|
|
|
|
|
} else if(flags == edelib::DW_REPORT_MODIFY) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": modified %s\n", changed);
|
2007-09-03 16:26:58 +04:00
|
|
|
} else if(flags == edelib::DW_REPORT_DELETE) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": deleted %s\n", changed);
|
2008-08-10 21:49:38 +04:00
|
|
|
if(remove_icon_by_path(changed))
|
2007-09-03 16:26:58 +04:00
|
|
|
redraw();
|
|
|
|
} else
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": %s changed with %i\n", changed, flags);
|
2007-09-03 16:26:58 +04:00
|
|
|
}
|
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
int Desktop::handle(int event) {
|
|
|
|
switch(event) {
|
2007-06-18 18:18:35 +04:00
|
|
|
case FL_FOCUS:
|
|
|
|
case FL_UNFOCUS:
|
2007-06-19 14:10:42 +04:00
|
|
|
case FL_SHORTCUT:
|
2007-05-23 16:43:50 +04:00
|
|
|
return 1;
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
case FL_PUSH: {
|
2007-05-22 18:53:17 +04:00
|
|
|
/*
|
2009-03-26 20:05:44 +03:00
|
|
|
* First check where we clicked. If we do it on desktop unfocus any possible focused childs, and handle
|
2007-05-22 18:53:17 +04:00
|
|
|
* specific clicks. Otherwise, do rest for childs.
|
|
|
|
*/
|
2007-06-18 18:18:35 +04:00
|
|
|
Fl_Widget* clicked = Fl::belowmouse();
|
|
|
|
|
|
|
|
if(NOT_SELECTABLE(clicked)) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": DESKTOP CLICK !!!\n");
|
2009-03-26 21:09:20 +03:00
|
|
|
if(!selectionbuf.empty()) {
|
2007-06-18 18:18:35 +04:00
|
|
|
/*
|
2009-03-26 21:09:20 +03:00
|
|
|
* Only focused are in selectionbuf, so this is fine to do; also will prevent
|
2009-03-26 20:05:44 +03:00
|
|
|
* full redraw when is clicked on desktop
|
2007-06-18 18:18:35 +04:00
|
|
|
*/
|
|
|
|
unfocus_all();
|
2009-03-26 21:09:20 +03:00
|
|
|
selectionbuf.clear();
|
2007-05-22 18:53:17 +04:00
|
|
|
}
|
2007-06-25 13:20:49 +04:00
|
|
|
|
|
|
|
// track position so moving can be deduced
|
|
|
|
if(Fl::event_button() == 1) {
|
|
|
|
selbox->x = Fl::event_x();
|
|
|
|
selbox->y = Fl::event_y();
|
2007-07-02 14:28:18 +04:00
|
|
|
} else if(Fl::event_button() == 3) {
|
2012-04-23 16:43:20 +04:00
|
|
|
last_px = Fl::event_x();
|
|
|
|
last_py = Fl::event_y();
|
|
|
|
|
2009-07-09 17:26:59 +04:00
|
|
|
const edelib::MenuItem* item = dmenu->menu()->popup(Fl::event_x(), Fl::event_y());
|
2007-11-06 17:33:19 +03:00
|
|
|
dmenu->picked(item);
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
2007-07-02 14:28:18 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
return 1;
|
|
|
|
}
|
2007-05-24 16:53:03 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
// from here, all events are managed for icons
|
|
|
|
DesktopIcon* tmp_icon = (DesktopIcon*)clicked;
|
|
|
|
|
2011-10-18 12:17:35 +04:00
|
|
|
/* do no use assertion on this, since fltk::belowmouse() can miss our icon */
|
2007-05-22 18:53:17 +04:00
|
|
|
if(!tmp_icon)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if(SELECTION_MULTI) {
|
2007-06-18 18:18:35 +04:00
|
|
|
Fl::event_is_click(0);
|
2007-05-22 18:53:17 +04:00
|
|
|
select(tmp_icon);
|
|
|
|
return 1;
|
2007-06-18 18:18:35 +04:00
|
|
|
} else if(SELECTION_SINGLE) {
|
2007-06-18 20:46:27 +04:00
|
|
|
if(!in_selection(tmp_icon)) {
|
2007-05-22 18:53:17 +04:00
|
|
|
select_only(tmp_icon);
|
2007-06-18 20:46:27 +04:00
|
|
|
}
|
|
|
|
} else if(Fl::event_button() == 3) {
|
2007-05-22 18:53:17 +04:00
|
|
|
select_only(tmp_icon);
|
2007-06-18 20:46:27 +04:00
|
|
|
}
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Let child handle the rest.
|
|
|
|
* Also prevent click on other mouse buttons during move.
|
|
|
|
*/
|
|
|
|
if(!moving)
|
2007-06-18 18:18:35 +04:00
|
|
|
tmp_icon->handle(FL_PUSH);
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": FL_PUSH from desktop\n");
|
2007-06-18 18:18:35 +04:00
|
|
|
selection_x = Fl::event_x_root();
|
|
|
|
selection_y = Fl::event_y_root();
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
case FL_DRAG:
|
2007-05-22 18:53:17 +04:00
|
|
|
moving = true;
|
2009-03-26 21:09:20 +03:00
|
|
|
if(!selectionbuf.empty()) {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": DRAG icon from desktop\n");
|
2007-06-18 18:18:35 +04:00
|
|
|
move_selection(Fl::event_x_root(), Fl::event_y_root(), false);
|
2007-05-22 18:53:17 +04:00
|
|
|
} else {
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": DRAG from desktop\n");
|
2007-06-25 13:20:49 +04:00
|
|
|
/*
|
|
|
|
* Moving is started with pushed button.
|
|
|
|
* From this point selection box is created and is rolled until release
|
|
|
|
*/
|
|
|
|
if(selbox->x != 0 || selbox->y != 0) {
|
|
|
|
selbox->w = Fl::event_x() - selbox->x;
|
|
|
|
selbox->h = Fl::event_y() - selbox->y;
|
|
|
|
|
|
|
|
selbox->show = true;
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* see if there some icons inside selection area */
|
2007-06-25 13:20:49 +04:00
|
|
|
select_in_area();
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* redraw selection box */
|
2007-06-25 13:20:49 +04:00
|
|
|
damage(EDAMAGE_OVERLAY);
|
|
|
|
}
|
2007-05-22 18:53:17 +04:00
|
|
|
}
|
2007-06-18 18:18:35 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
return 1;
|
|
|
|
|
2007-06-18 18:18:35 +04:00
|
|
|
case FL_RELEASE:
|
2008-08-07 18:22:05 +04:00
|
|
|
E_DEBUG(E_STRLOC ": RELEASE from desktop\n");
|
|
|
|
E_DEBUG(E_STRLOC ": clicks: %i\n", Fl::event_is_click());
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2007-06-25 13:20:49 +04:00
|
|
|
if(selbox->show) {
|
|
|
|
selbox->x = selbox->y = selbox->w = selbox->h = 0;
|
|
|
|
selbox->show = false;
|
|
|
|
damage(EDAMAGE_OVERLAY);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now pickup those who are in is_focused() state.
|
|
|
|
*
|
2009-03-26 20:05:44 +03:00
|
|
|
* Possible flickers due overlay will be later removed when is called move_selection(), which
|
|
|
|
* will in turn redraw icons again after position them.
|
2007-06-25 13:20:49 +04:00
|
|
|
*/
|
2009-03-26 21:09:20 +03:00
|
|
|
if(!selectionbuf.empty())
|
|
|
|
selectionbuf.clear();
|
2007-06-25 13:20:49 +04:00
|
|
|
|
2007-09-03 16:26:58 +04:00
|
|
|
DesktopIconListIter it, it_end;
|
|
|
|
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
|
|
|
if((*it)->is_focused())
|
|
|
|
select((*it), false);
|
2007-06-25 13:20:49 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-03-26 21:09:20 +03:00
|
|
|
if(!selectionbuf.empty() && moving)
|
2007-06-18 18:18:35 +04:00
|
|
|
move_selection(Fl::event_x_root(), Fl::event_y_root(), true);
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
/*
|
2007-06-18 18:18:35 +04:00
|
|
|
* Do not send FL_RELEASE during move
|
2009-03-26 20:05:44 +03:00
|
|
|
* TODO: should be alowed FL_RELEASE to multiple icons? (aka. run command for all selected icons)?
|
2007-05-22 18:53:17 +04:00
|
|
|
*/
|
2009-03-26 21:09:20 +03:00
|
|
|
if(selectionbuf.size() == 1 && !moving)
|
|
|
|
(*selectionbuf.begin())->handle(FL_RELEASE);
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
moving = false;
|
|
|
|
return 1;
|
2007-07-02 14:28:18 +04:00
|
|
|
|
2007-06-23 15:31:36 +04:00
|
|
|
case FL_DND_ENTER:
|
|
|
|
case FL_DND_DRAG:
|
|
|
|
case FL_DND_LEAVE:
|
|
|
|
return 1;
|
2007-07-02 14:28:18 +04:00
|
|
|
|
|
|
|
case FL_DND_RELEASE: {
|
|
|
|
DesktopIcon* di = below_mouse(Fl::event_x(), Fl::event_y());
|
|
|
|
if(di)
|
|
|
|
return di->handle(event);
|
2007-06-23 15:31:36 +04:00
|
|
|
return 1;
|
2007-07-02 14:28:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
case FL_PASTE: {
|
|
|
|
DesktopIcon* di = below_mouse(Fl::event_x(), Fl::event_y());
|
|
|
|
if(di)
|
|
|
|
return di->handle(event);
|
2007-06-23 15:31:36 +04:00
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
//dnd_drop_source(Fl::event_text(), Fl::event_length(), Fl::event_x(), Fl::event_y());
|
2007-06-23 15:31:36 +04:00
|
|
|
return 1;
|
2007-07-02 14:28:18 +04:00
|
|
|
}
|
2007-06-27 18:42:47 +04:00
|
|
|
|
|
|
|
case FL_ENTER:
|
|
|
|
case FL_LEAVE:
|
|
|
|
case FL_MOVE:
|
2011-10-18 12:45:55 +04:00
|
|
|
return EDE_DESKTOP_WINDOW::handle(event);
|
2007-06-27 18:42:47 +04:00
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2006-08-20 22:43:09 +04:00
|
|
|
|
2007-06-27 18:42:47 +04:00
|
|
|
return 0;
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
int main() {
|
2010-03-28 16:54:45 +04:00
|
|
|
EDE_APPLICATION("ede-desktop");
|
|
|
|
|
2007-05-22 18:53:17 +04:00
|
|
|
signal(SIGTERM, exit_signal);
|
|
|
|
signal(SIGKILL, exit_signal);
|
2007-06-18 18:18:35 +04:00
|
|
|
signal(SIGINT, exit_signal);
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
srand(time(NULL));
|
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* a lot of preparing code depends on this */
|
2007-06-18 18:18:35 +04:00
|
|
|
fl_open_display();
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
#ifndef USE_EDELIB_WINDOW
|
2007-06-18 18:18:35 +04:00
|
|
|
fl_register_images();
|
2009-03-25 14:13:12 +03:00
|
|
|
edelib::IconLoader::init();
|
2007-11-06 17:33:19 +03:00
|
|
|
#endif
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2007-05-24 16:53:03 +04:00
|
|
|
Desktop::init();
|
|
|
|
Desktop::instance()->show();
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2009-03-26 20:05:44 +03:00
|
|
|
/* XSelectInput will redirect PropertyNotify messages, which are listened for */
|
2007-06-19 13:59:15 +04:00
|
|
|
XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask | ClientMessage);
|
|
|
|
|
2009-12-24 18:47:29 +03:00
|
|
|
netwm_callback_add(desktop_message_handler);
|
2007-05-22 18:53:17 +04:00
|
|
|
|
|
|
|
while(running)
|
2007-06-18 18:18:35 +04:00
|
|
|
Fl::wait();
|
2007-05-22 18:53:17 +04:00
|
|
|
|
2007-05-24 16:53:03 +04:00
|
|
|
Desktop::shutdown();
|
2007-07-02 14:28:18 +04:00
|
|
|
|
2007-11-06 17:33:19 +03:00
|
|
|
#ifndef USE_EDELIB_WINDOW
|
2009-03-25 14:13:12 +03:00
|
|
|
edelib::IconLoader::shutdown();
|
2007-11-06 17:33:19 +03:00
|
|
|
#endif
|
2007-05-22 18:53:17 +04:00
|
|
|
return 0;
|
2006-08-20 22:43:09 +04:00
|
|
|
}
|