Changed icon create/edit dialog, so working path can be set, including startup options like running in terminal or starting with startup nofication hints.

Changed how icons are started. Previously, ede-desktop would extract content from .desktop Exec key and explicitly run it. This would not correctly handle other .desktop details, like startup notification or running in terminal. Now, full .desktop path is sent directly to ede-launch which will take care about named startup details.

These changes also fixes bug #235: "Working directory and startup notification for desktop icons".
This commit is contained in:
Sanel Zukan 2014-02-25 18:16:10 +00:00
parent 30d0261cd3
commit f1a37cefd2
5 changed files with 156 additions and 98 deletions

View File

@ -378,18 +378,9 @@ DesktopIcon *Desktop::read_desktop_file(const char *path, const char *base, Desk
ret = new DesktopIcon(_("No Name")); ret = new DesktopIcon(_("No Name"));
ret->set_icon_type(DESKTOP_ICON_TYPE_NORMAL); ret->set_icon_type(DESKTOP_ICON_TYPE_NORMAL);
if(df.name(buf, sizeof(buf))) if(df.name(buf, sizeof(buf))) ret->copy_label(buf);
ret->copy_label(buf); ret->set_image(df.icon(buf, sizeof(buf)) ? buf : NULL);
if(df.comment(buf, sizeof(buf))) ret->set_tooltip(buf);
if(df.icon(buf, sizeof(buf)))
ret->set_image(buf);
else
ret->set_image(NULL);
if(df.comment(buf, sizeof(buf)))
ret->set_tooltip(buf);
if(df.exec(buf, sizeof(buf))) ret->set_cmd(buf);
} }
/* try to put random icon position in the middle of the desktop, so it is easier to notice */ /* try to put random icon position in the middle of the desktop, so it is easier to notice */

View File

@ -81,7 +81,8 @@ static MenuItem icon_trash_menu[] = {
static void open_cb(Fl_Widget*, void* d) { static void open_cb(Fl_Widget*, void* d) {
DesktopIcon *o = (DesktopIcon*)d; DesktopIcon *o = (DesktopIcon*)d;
run_async("ede-launch %s", o->get_cmd()); /* run .desktop file directly, since it can contain startup details */
run_async("ede-launch %s", o->get_path());
} }
static void edit_cb(Fl_Widget*, void* d) { static void edit_cb(Fl_Widget*, void* d) {
@ -391,8 +392,8 @@ int DesktopIcon::handle(int event) {
return 1; return 1;
case FL_RELEASE: case FL_RELEASE:
if(Fl::event_clicks() > 0 && !cmd.empty()) if(Fl::event_clicks() > 0 && !path.empty())
run_async("ede-launch %s", cmd.c_str()); run_async("ede-launch %s", path.c_str());
return 1; return 1;
case FL_DND_ENTER: case FL_DND_ENTER:

View File

@ -86,8 +86,8 @@ private:
IconOptions *opts; IconOptions *opts;
MovableIcon *micon; MovableIcon *micon;
/* location of .desktop file and command to be executed */ /* location of .desktop file */
EDELIB_NS_PREPEND(String) path, cmd; EDELIB_NS_PREPEND(String) path;
EDELIB_NS_PREPEND(MenuButton) *imenu; EDELIB_NS_PREPEND(MenuButton) *imenu;
#if !((FL_MAJOR_VERSION >= 1) && (FL_MINOR_VERSION >= 3)) #if !((FL_MAJOR_VERSION >= 1) && (FL_MINOR_VERSION >= 3))
@ -118,9 +118,6 @@ public:
void set_path(const char *p) { path = p; } void set_path(const char *p) { path = p; }
const char *get_path(void) { return path.c_str(); } const char *get_path(void) { return path.c_str(); }
void set_cmd(const char *c) { cmd = c; }
const char *get_cmd(void) { return cmd.c_str(); }
void fix_position(int X, int Y); void fix_position(int X, int Y);
void drag(int x, int y, bool apply); void drag(int x, int y, bool apply);
int drag_icon_x(void); int drag_icon_x(void);

View File

@ -1,7 +1,7 @@
/* /*
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $ * $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
* *
* Copyright (C) 2006-2013 Sanel Zukan * Copyright (C) 2006-2014 Sanel Zukan
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -29,6 +29,9 @@
#include <FL/Fl_Menu_Item.H> #include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Shared_Image.H> #include <FL/Fl_Shared_Image.H>
#include <FL/Fl_File_Chooser.H> #include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Check_Button.H>
#include <edelib/Nls.h> #include <edelib/Nls.h>
#include <edelib/String.h> #include <edelib/String.h>
@ -53,12 +56,13 @@ EDELIB_NS_USING_LIST(12, (str_tolower, icon_chooser, dir_home, build_filename, a
#define DEFAULT_ICON "empty" #define DEFAULT_ICON "empty"
/* it is safe to be globals */ /* it is safe to be globals */
static Fl_Window *win; static Fl_Window *win;
static Fl_Button *img, *browse, *ok, *cancel; static Fl_Button *img, *browse, *ok, *cancel;
static Fl_Input *name, *comment, *execute; static Fl_Input *name, *comment, *execute, *workdir;
static Fl_Choice *icon_type; static Fl_Choice *icon_type;
static String img_path, old_desktop_path; static Fl_Check_Button *run_in_terminal, *start_notify;
static DesktopIcon *curr_icon; static String img_path, old_desktop_path;
static DesktopIcon *curr_icon;
/* the only supported type for now is application */ /* the only supported type for now is application */
static Fl_Menu_Item menu_items[] = { static Fl_Menu_Item menu_items[] = {
@ -70,8 +74,9 @@ static bool is_empty(const char *str) {
if(!str) return true; if(!str) return true;
const char *p = str; const char *p = str;
while(*p++) while(*p++) {
if(!isspace(*p)) return false; if(!isspace(*p)) return false;
}
return true; return true;
} }
@ -103,6 +108,12 @@ static void ok_cb(Fl_Widget*, void *d) {
df.set_icon((img_path.length() > 1) ? img_path.c_str() : DEFAULT_ICON); df.set_icon((img_path.length() > 1) ? img_path.c_str() : DEFAULT_ICON);
df.set_exec(execute->value()); df.set_exec(execute->value());
if(!is_empty_input(workdir))
df.set_path(workdir->value());
df.set_startup_notify(start_notify->value());
df.set_terminal(run_in_terminal->value());
/* determine filename and save it */ /* determine filename and save it */
String file = name->value(); String file = name->value();
const char *fp = file.c_str(); const char *fp = file.c_str();
@ -157,6 +168,11 @@ static void file_browse_cb(Fl_Widget*, void*) {
if(p) execute->value(p); if(p) execute->value(p);
} }
static void dir_browse_cb(Fl_Widget*, void*) {
const char *p = fl_dir_chooser(_("Choose directory"), "*", 0);
if(p) workdir->value(p);
}
#define BUFSIZE PATH_MAX #define BUFSIZE PATH_MAX
void icon_dialog_icon_edit(Desktop *self, DesktopIcon *d) { void icon_dialog_icon_edit(Desktop *self, DesktopIcon *d) {
@ -170,8 +186,9 @@ void icon_dialog_icon_edit(Desktop *self, DesktopIcon *d) {
df = new DesktopFile(); df = new DesktopFile();
if(!df->load(d->get_path())) { if(!df->load(d->get_path())) {
delete df; delete df;
df = NULL;
int ret = ask(_("Unable to load .desktop file for this icon. Would you like to create new icon instead?")); int ret = ask(_("Unable to load .desktop file for this icon. Would you like to create a new icon instead?"));
if(!ret) return; if(!ret) return;
/* force NULL on icon, so we can run dialog in 'create' mode */ /* force NULL on icon, so we can run dialog in 'create' mode */
@ -182,48 +199,70 @@ void icon_dialog_icon_edit(Desktop *self, DesktopIcon *d) {
old_desktop_path = d->get_path(); old_desktop_path = d->get_path();
} }
win = new Fl_Window(430, 170, lbl); win = new Fl_Window(450, 220, lbl);
img = new Fl_Button(10, 10, 75, 75); Fl_Tabs *tabs = new Fl_Tabs(10, 10, 430, 165);
img->callback(img_browse_cb); tabs->begin();
img->tooltip(_("Click to select icon")); Fl_Group *g1 = new Fl_Group(15, 30, 415, 140, _("Basic"));
g1->begin();
img = new Fl_Button(20, 45, 80, 75);
img->callback(img_browse_cb);
img->tooltip(_("Click to select icon"));
if(d) { if(d) {
E_ASSERT(df != NULL); E_ASSERT(df != NULL);
if(df->icon(buf, BUFSIZE)) { if(df->icon(buf, BUFSIZE)) {
IconLoader::set(img, buf, ICON_SIZE_HUGE); IconLoader::set(img, buf, ICON_SIZE_HUGE);
img_path = buf; img_path = buf;
}
} }
}
/* handles even the case when we are creating the new icon */ /* handles even the case when we are creating the new icon */
if(!img->image()) { if(!img->image()) {
IconLoader::set(img, DEFAULT_ICON, ICON_SIZE_HUGE); IconLoader::set(img, DEFAULT_ICON, ICON_SIZE_HUGE);
img_path = DEFAULT_ICON; img_path = DEFAULT_ICON;
} }
name = new Fl_Input(205, 10, 215, 25, _("Name:")); name = new Fl_Input(210, 45, 215, 25, _("Name:"));
if(d && df->name(buf, BUFSIZE)) if(d && df->name(buf, BUFSIZE)) name->value(buf);
name->value(buf);
comment = new Fl_Input(205, 40, 215, 25, _("Comment:")); comment = new Fl_Input(210, 75, 215, 25, _("Comment:"));
if(d && df->comment(buf, BUFSIZE)) if(d && df->comment(buf, BUFSIZE)) comment->value(buf);
comment->value(buf);
execute = new Fl_Input(205, 70, 185, 25, _("Execute:")); execute = new Fl_Input(210, 105, 185, 25, _("Execute:"));
if(d && df->exec(buf, BUFSIZE)) if(d && df->exec(buf, BUFSIZE)) execute->value(buf);
execute->value(buf);
browse = new Fl_Button(395, 70, 25, 25, "..."); browse = new Fl_Button(400, 105, 25, 25, "...");
browse->callback(file_browse_cb); browse->callback(file_browse_cb);
icon_type = new Fl_Choice(205, 100, 215, 25, _("Type:")); icon_type = new Fl_Choice(210, 135, 215, 25, _("Type:"));
icon_type->down_box(FL_BORDER_BOX); icon_type->down_box(FL_BORDER_BOX);
icon_type->menu(menu_items); icon_type->menu(menu_items);
g1->end();
Fl_Group *g2 = new Fl_Group(15, 30, 420, 140, _("Details"));
g2->hide();
g2->begin();
run_in_terminal = new Fl_Check_Button(195, 80, 235, 25, _("Run in terminal"));
run_in_terminal->down_box(FL_DOWN_BOX);
if(df) run_in_terminal->value(df->terminal());
workdir = new Fl_Input(195, 45, 205, 25, _("Working directory:"));
if(df && df->path(buf, BUFSIZE)) workdir->value(buf);
Fl_Button *browsedir = new Fl_Button(405, 45, 25, 25, "...");
browsedir->callback(dir_browse_cb);
start_notify = new Fl_Check_Button(195, 110, 235, 25, _("Use startup notification"));
start_notify->down_box(FL_DOWN_BOX);
if(df) start_notify->value(df->startup_notify());
g2->end();
tabs->end();
ok = new Fl_Button(255, 185, 90, 25, _("&OK"));
ok->callback(ok_cb, self);
cancel = new Fl_Button(350, 185, 90, 25, _("&Cancel"));
cancel->callback(cancel_cb);
ok = new Fl_Button(235, 135, 90, 25, _("&OK"));
ok->callback(ok_cb, self);
cancel = new Fl_Button(330, 135, 90, 25, _("&Cancel"));
cancel->callback(cancel_cb);
win->end(); win->end();
win->set_modal(); win->set_modal();

View File

@ -1,42 +1,72 @@
# data file for the Fltk User Interface Designer (fluid) # data file for the Fltk User Interface Designer (fluid)
version 1.0300 version 1.0302
header_name {.h} header_name {.h}
code_name {.cxx} code_name {.cxx}
Function {} {open Function {} {open
} { } {
Fl_Window {} {open Fl_Window {} {open
xywh {474 344 430 170} type Double visible xywh {426 288 450 220} type Double visible
} { } {
Fl_Button {} { Fl_Tabs {} {open
xywh {10 10 75 75} xywh {10 10 430 165}
} } {
Fl_Input {} { Fl_Group {} {
label {Name:} label Basic open
xywh {205 10 215 25} xywh {15 30 415 140}
} } {
Fl_Input {} { Fl_Button {} {selected
label {Comment:} xywh {20 45 80 75}
xywh {205 40 215 25} }
} Fl_Input {} {
Fl_Input {} { label {Name:}
label {Execute:} selected xywh {210 45 215 25}
xywh {205 70 185 25} }
} Fl_Input {} {
Fl_Button {} { label {Comment:}
label {...} xywh {210 75 215 25}
xywh {395 70 25 25} }
} Fl_Input {} {
Fl_Choice {} { label {Execute:}
label {Type:} open xywh {210 105 185 25}
xywh {205 100 215 25} down_box BORDER_BOX }
} {} Fl_Button {} {
Fl_Button {} { label {...}
label {&OK} xywh {400 105 25 25}
xywh {235 135 90 25} }
Fl_Choice {} {
label {Type:} open
xywh {210 135 215 25} down_box BORDER_BOX
} {}
}
Fl_Group {} {
label Details open
xywh {15 30 420 140} hide
} {
Fl_Check_Button {} {
label {Run in terminal}
xywh {195 80 235 25} down_box DOWN_BOX
}
Fl_Input {} {
label {Working directory:}
xywh {195 45 205 25}
}
Fl_Button {} {
label {...}
xywh {405 45 25 25}
}
Fl_Check_Button {} {
label {Use startup notification}
xywh {195 110 235 25} down_box DOWN_BOX
}
}
} }
Fl_Button {} { Fl_Button {} {
label {&Cancel} label {&Cancel}
xywh {330 135 90 25} xywh {350 185 90 25}
}
Fl_Button {} {
label {&OK}
xywh {255 185 90 25}
} }
} }
} }