123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781 |
- /*
- * Copyright 2020 Mihai Bazon
- *
- * Permission to use, copy, modify, and/or distribute this software
- * for any purpose with or without fee is hereby granted, provided that
- * the above copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
- * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
- #include <X11/Xlib.h>
- #include <gtk/gtk.h>
- #include <gdk/gdkkeysyms.h>
- #include <gdk/gdkx.h>
- #ifdef MTRACE
- #include <mcheck.h>
- #endif
- #include <unistd.h>
- #include <errno.h>
- #include "gtkcompletionline.h"
- #include "config_prefs.h"
- #define CMD_LENGTH 1024
- enum
- {
- W_TEXT_STYLE_NORMAL,
- W_TEXT_STYLE_NOTFOUND,
- W_TEXT_STYLE_NOTUNIQUE,
- W_TEXT_STYLE_UNIQUE,
- };
- GtkApplication * gmrun_app;
- char * gmrun_text = NULL;
- static void gmrun_exit (void);
- GtkAllocation window_geom = { -1, -1, -1, -1 };
- /* widgets that are used in several functions */
- GtkWidget * compline;
- GtkWidget * wlabel;
- GtkWidget * wlabel_search;
- /* preferences */
- int USE_GLIB_XDG = 0;
- int SHELL_RUN = 1;
- /// BEGIN: TIMEOUT MANAGEMENT
- static gboolean search_off_timeout ();
- static guint g_search_off_timeout_id = 0;
- static void remove_search_off_timeout (void)
- {
- if (g_search_off_timeout_id) {
- g_source_remove(g_search_off_timeout_id);
- g_search_off_timeout_id = 0;
- }
- }
- static void add_search_off_timeout (guint32 timeout, GSourceFunc func)
- {
- remove_search_off_timeout();
- if (!func)
- func = (GSourceFunc) search_off_timeout;
- g_search_off_timeout_id = g_timeout_add (timeout, func, NULL);
- }
- /// END: TIMEOUT MANAGEMENT
- // https://unix.stackexchange.com/questions/457584/gtk3-change-text-color-in-a-label-raspberry-pi
- static void set_info_text_color (GtkWidget *w, const char *text, int spec)
- {
- char *markup = NULL;
- static const char * colors[] = {
- "black", /* W_TEXT_STYLE_NORMAL */
- "red", /* W_TEXT_STYLE_NOTFOUND */
- "blue", /* W_TEXT_STYLE_NOTUNIQUE */
- "green", /* W_TEXT_STYLE_UNIQUE */
- };
- markup = g_markup_printf_escaped ("<span foreground=\"%s\">%s</span>",
- colors[spec], text);
- if (markup) {
- gtk_label_set_markup (GTK_LABEL (w), markup);
- g_free(markup);
- }
- }
- static void run_the_command (char * cmd)
- {
- #if DEBUG
- fprintf (stderr, "command: %s\n", cmd);
- #endif
- if (SHELL_RUN)
- {
- // need to add extra &
- if (strlen (cmd) < (CMD_LENGTH-10)) {
- strcat (cmd, " &"); /* safe to use in this case */
- }
- int ret = system (cmd);
- if (ret != -1) {
- gmrun_exit ();
- } else {
- char errmsg[256];
- snprintf (errmsg, sizeof(errmsg)-1, "ERROR: %s", strerror (errno));
- set_info_text_color (wlabel, errmsg, W_TEXT_STYLE_NOTFOUND);
- add_search_off_timeout (3000, NULL);
- }
- }
- else // glib - more conservative approach and robust error reporting
- {
- GError * error = NULL;
- gboolean success;
- int argc;
- char ** argv;
- success = g_shell_parse_argv (cmd, &argc, &argv, &error);
- if (!success) {
- set_info_text_color (wlabel, error->message, W_TEXT_STYLE_NOTFOUND);
- g_error_free (error);
- add_search_off_timeout (3000, NULL);
- return;
- }
- success = g_spawn_async (NULL, argv, NULL,
- G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
- if (argv) {
- g_strfreev (argv);
- }
- if (success) {
- gmrun_exit ();
- } else {
- set_info_text_color (wlabel, error->message, W_TEXT_STYLE_NOTFOUND);
- g_error_free (error);
- add_search_off_timeout (3000, NULL);
- }
- }
- }
- static void
- on_ext_handler (GtkCompletionLine *cl, const char * filename)
- {
- if (USE_GLIB_XDG) // GLib XDG handling (freedesktop specification)
- {
- gchar * content_type, * mime_type, * msg;
- const gchar * handler;
- GAppInfo * app_info;
- if (filename) {
- content_type = g_content_type_guess (filename, NULL, 0, NULL);
- if (content_type) {
- mime_type = g_content_type_get_mime_type (content_type);
- g_free (content_type);
- app_info = g_app_info_get_default_for_type (mime_type, FALSE);
- g_free (mime_type);
- if (app_info) {
- handler = g_app_info_get_commandline (app_info);
- msg = g_strconcat("Handler: ", handler, NULL);
- gtk_label_set_text (GTK_LABEL (wlabel_search), msg);
- gtk_widget_show (wlabel_search);
- g_object_unref(app_info);
- g_free(msg);
- return;
- }
- }
- }
- search_off_timeout();
- }
- else // custom EXT handlers
- {
- const char * ext = strrchr (filename, '.');
- if (!ext) {
- search_off_timeout ();
- return;
- }
- const char * handler = config_get_handler_for_extension (ext);
- if (handler) {
- char * tmp = g_strconcat ("Handler: ", handler, NULL);
- gtk_label_set_text (GTK_LABEL (wlabel_search), tmp);
- gtk_widget_show (wlabel_search);
- g_free (tmp);
- }
- }
- }
- static void on_compline_runwithterm (GtkCompletionLine *cl)
- {
- char cmd[CMD_LENGTH];
- char * term;
- char * entry_text = g_strdup (gtk_entry_get_text (GTK_ENTRY(cl)));
- g_strstrip (entry_text);
- if (*entry_text) {
- if (config_get_string_expanded ("TermExec", &term)) {
- snprintf (cmd, sizeof (cmd), "%s %s", term, entry_text);
- g_free (term);
- } else {
- snprintf (cmd, sizeof (cmd), "xterm -e %s", entry_text);
- }
- } else {
- if (config_get_string ("Terminal", &term)) {
- strncpy (cmd, term, sizeof (cmd) - 1);
- } else {
- strncpy (cmd, "xterm", sizeof (cmd) - 1);
- }
- }
- history_append (cl->hist, cmd);
- run_the_command (cmd);
- g_free (entry_text);
- }
- static gboolean search_off_timeout ()
- {
- set_info_text_color (wlabel, "Program çalıştır:", W_TEXT_STYLE_NORMAL);
- gtk_widget_hide (wlabel_search);
- g_search_off_timeout_id = 0;
- return G_SOURCE_REMOVE;
- }
- static void
- on_compline_unique (GtkCompletionLine *cl)
- {
- set_info_text_color (wlabel, "benzersiz", W_TEXT_STYLE_UNIQUE);
- add_search_off_timeout (1000, NULL);
- }
- static void
- on_compline_notunique (GtkCompletionLine *cl)
- {
- set_info_text_color (wlabel, "benzersiz değil", W_TEXT_STYLE_NOTUNIQUE);
- add_search_off_timeout (1000, NULL);
- }
- static void
- on_compline_incomplete (GtkCompletionLine *cl)
- {
- set_info_text_color (wlabel, "bulunamadı", W_TEXT_STYLE_NOTFOUND);
- add_search_off_timeout (1000, NULL);
- }
- static void
- on_search_mode (GtkCompletionLine *cl)
- {
- if (cl->hist_search_mode == TRUE) {
- gtk_widget_show (wlabel_search);
- gtk_label_set_text (GTK_LABEL (wlabel), "Ara:");
- gtk_label_set_text (GTK_LABEL (wlabel_search), cl->hist_word);
- } else {
- gtk_widget_hide (wlabel_search);
- gtk_label_set_text (GTK_LABEL (wlabel), "Arama Kapalı");
- add_search_off_timeout (1000, NULL);
- }
- }
- static void
- on_search_letter(GtkCompletionLine *cl, GtkWidget *label)
- {
- gtk_label_set_text (GTK_LABEL(label), cl->hist_word);
- }
- static gboolean search_fail_timeout (gpointer user_data)
- {
- set_info_text_color (wlabel, "Ara:", W_TEXT_STYLE_NOTUNIQUE);
- g_search_off_timeout_id = 0;
- return G_SOURCE_REMOVE;
- }
- static void
- on_search_not_found(GtkCompletionLine *cl)
- {
- set_info_text_color (wlabel, "Bulunamadı!", W_TEXT_STYLE_NOTFOUND);
- add_search_off_timeout (1000, (GSourceFunc) search_fail_timeout);
- }
- // =============================================================
- static void xdg_app_run_command (GAppInfo *app, const gchar *args)
- {
- // get
- char * cmd, * exe;
- GRegex * regex;
- regex = g_regex_new (".%[fFuUdDnNickvm]", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, NULL);
- exe = g_regex_replace_literal (regex, // Remove xdg desktop files fields from app
- g_app_info_get_commandline (app),
- -1, 0, "", G_REGEX_MATCH_NOTEMPTY, NULL);
- cmd = g_strconcat (exe, " ", args, NULL);
- run_the_command (cmd); /* Launch the command */
- g_regex_unref (regex);
- g_free (exe);
- g_free (cmd);
- }
- /* Handler for URLs */
- static gboolean url_check (GtkCompletionLine *cl, char * entry_text)
- {
- if (USE_GLIB_XDG) // GLib XDG handling (freedesktop specification)
- {
- char * delim;
- const char * url, * protocol;
- GAppInfo * app;
- delim = strchr (entry_text, ':');
- if (!delim || !*(delim+1)) {
- return FALSE;
- }
- protocol = entry_text;
- url = delim + 1;
- *delim = 0;
- if (url[0] == '/' && url[1] == '/')
- {
- app = g_app_info_get_default_for_uri_scheme (protocol);
- if (app) { // found known uri handler for protocol
- *delim = ':';
- xdg_app_run_command (app, entry_text);
- history_append (cl->hist, entry_text);
- g_object_unref (app);
- } else {
- char *tmp = g_strconcat ("No URL handler for [", protocol, "]", NULL);
- set_info_text_color (wlabel, tmp, W_TEXT_STYLE_NOTFOUND);
- add_search_off_timeout (1000, NULL);
- g_free (tmp);
- }
- return TRUE;
- }
- *delim = ':';
- return FALSE;
- }
- else //-------- custom URL handlers
- {
- // <url_type> <delim> <url>
- // http : //www.fsf.org
- // <f u l l u r l>
- // config: URL_<url_type>
- // handler %s (format 1) = run handler with <url>
- // handler %u (format 2) = run handler with <full url>
- char * cmd;
- char * tmp, * delim, * p;
- char * url, * url_type, * full_url, * chosen_url;
- char * url_handler;
- char * config_key;
- cmd = tmp = delim = p = url_handler = config_key = NULL;
- delim = strchr (entry_text, ':');
- if (!delim || !*(delim+1)) {
- return FALSE;
- }
- tmp = g_strdup (entry_text);
- delim = strchr (tmp, ':');
- *delim = 0;
- url_type = tmp; // http
- url = delim + 1; // //www.fsf.org
- full_url = entry_text;
- config_key = g_strconcat ("URL_", url_type, NULL);
- if (config_get_string_expanded (config_key, &url_handler))
- {
- chosen_url = url;
- p = strchr (url_handler, '%');
- if (p) { // handler %s
- p++;
- if (*p == 'u') { // handler %u
- *p = 's'; // convert %u to %s (for printf)
- chosen_url = full_url;
- }
- cmd = g_strdup_printf (url_handler, chosen_url);
- } else {
- cmd = g_strconcat (url_handler, " ", url, NULL);
- }
- g_free (url_handler);
- }
- if (cmd) {
- history_append (cl->hist, entry_text);
- run_the_command (cmd);
- g_free (cmd);
- } else {
- g_free (tmp);
- tmp = g_strconcat (" [", config_key, "] için URL işleyici yok", NULL);
- set_info_text_color (wlabel, tmp, W_TEXT_STYLE_NOTFOUND);
- add_search_off_timeout (1000, NULL);
- }
- g_free (config_key);
- g_free (tmp);
- return TRUE;
- }
- }
- static char * escape_spaces (char * entry_text)
- { // run file with glib: replace " " with "\ "
- GRegex * regex;
- char * quoted;
- if (!strstr (entry_text, "\\ ")) {
- regex = g_regex_new (" ", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, NULL);
- quoted = g_regex_replace_literal (regex, entry_text, -1, 0, "\\ ", G_REGEX_MATCH_NOTEMPTY, NULL);
- g_regex_unref (regex);
- } else {
- quoted = strdup (entry_text); // already scaped, just duplicate text
- }
- return (quoted);
- }
- /* Handler for extensions */
- static gboolean ext_check (GtkCompletionLine *cl, char * entry_text)
- {
- if (USE_GLIB_XDG) // GLib XDG handling (freedesktop specification)
- {
- char *quoted, *content_type, *mime_type;
- GAppInfo *app_info;
- gboolean sure;
- quoted = escape_spaces (entry_text);
- /* File is executable: launch it (fail silently if file isn't really executable) */
- if (g_file_test (quoted, G_FILE_TEST_IS_EXECUTABLE)) {
- run_the_command (quoted);
- history_append (cl->hist, entry_text);
- g_free (quoted);
- return TRUE;
- }
- /* Check mime type through extension */
- if (quoted[0] == '/' && strchr (quoted, '.')) {
- content_type = g_content_type_guess (quoted, NULL, 0, &sure);
- if (content_type) {
- mime_type = g_content_type_get_mime_type (content_type);
- g_free (content_type);
- app_info = g_app_info_get_default_for_type (mime_type, FALSE);
- g_free (mime_type);
- if (app_info) { // found mime
- xdg_app_run_command (app_info, quoted);
- history_append (cl->hist, entry_text);
- g_free (quoted);
- g_object_unref(app_info);
- return TRUE;
- }
- }
- }
- g_free (quoted);
- return FALSE;
- }
- else //-------- custom EXTension handlers
- {
- // example: file.html | xdg-open '%s' -> xdg-open 'file.html'
- char * cmd, * quoted;
- char * ext = strrchr (entry_text, '.');
- char * handler_format = NULL;
- if (ext) {
- handler_format = config_get_handler_for_extension (ext);
- }
- if (handler_format) {
- quoted = g_strcompress (entry_text); /* unescape chars */
- if (strstr (handler_format, "%s")) {
- cmd = g_strdup_printf (handler_format, quoted);
- }
- else { // xdg-open
- cmd = g_strconcat (handler_format, " '", quoted, "'", NULL);
- }
- history_append (cl->hist, entry_text);
- run_the_command (cmd);
- g_free (cmd);
- g_free (quoted);
- return TRUE;
- }
- return FALSE;
- }
- }
- // =============================================================
- static void on_compline_activated (GtkCompletionLine *cl)
- {
- char * entry_text = g_strdup (gtk_entry_get_text (GTK_ENTRY(cl)));
- g_strstrip (entry_text);
- if (url_check (cl, entry_text) == TRUE
- || ext_check (cl, entry_text) == TRUE) {
- g_free (entry_text);
- return;
- }
- char cmd[CMD_LENGTH];
- char * AlwaysInTerm = NULL;
- char ** term_progs = NULL;
- char * selected_term_prog = NULL;
- if (config_get_string ("AlwaysInTerm", &AlwaysInTerm))
- {
- term_progs = g_strsplit (AlwaysInTerm, " ", 0);
- int i;
- for (i = 0; term_progs[i]; i++) {
- if (strcmp (term_progs[i], entry_text) == 0) {
- selected_term_prog = g_strdup (term_progs[i]);
- break;
- }
- }
- g_strfreev (term_progs);
- }
- if (selected_term_prog) {
- char * TermExec;
- config_get_string_expanded ("TermExec", &TermExec);
- snprintf (cmd, sizeof (cmd), "%s %s", TermExec, selected_term_prog);
- g_free (selected_term_prog);
- g_free (TermExec);
- } else {
- strncpy (cmd, entry_text, sizeof (cmd) - 1);
- }
- g_free (entry_text);
- history_append (cl->hist, cmd);
- run_the_command (cmd);
- }
- // =============================================================
- static void gmrun_activate(void)
- {
- GtkWidget *dialog, * main_vbox;
- GtkWidget *label_search;
- GtkWidget * window = gtk_application_window_new (gmrun_app);
- dialog = gtk_dialog_new();
- gtk_window_set_transient_for( (GtkWindow*)dialog, (GtkWindow*)window );
- gtk_widget_realize(dialog);
- main_vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
- // this removes the title bar..
- GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET(dialog));
- gdk_window_set_decorations (gwin, GDK_DECOR_BORDER);
- gtk_widget_set_name (GTK_WIDGET (dialog), "gmrun");
- gtk_window_set_title (GTK_WINDOW(window), "Tamamlanmış basit bir başlatıcı");
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 4);
- g_signal_connect(G_OBJECT(dialog), "destroy",
- G_CALLBACK(gmrun_exit), NULL);
- GtkWidget *hhbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
- gtk_box_pack_start (GTK_BOX (main_vbox), hhbox, FALSE, FALSE, 0);
- GtkWidget *label = gtk_label_new("Program çalıştır:");
- gtk_box_pack_start (GTK_BOX(hhbox), label, FALSE, FALSE, 10);
- gtkcompat_widget_set_halign_left (GTK_WIDGET (label));
- wlabel = label;
- label_search = gtk_label_new("");
- gtk_box_pack_start (GTK_BOX (hhbox), label_search, FALSE, TRUE, 0);
- wlabel_search = label_search;
- compline = gtk_completion_line_new();
- gtk_widget_set_name (compline, "gmrun_compline");
- gtk_box_pack_start (GTK_BOX (main_vbox), compline, TRUE, TRUE, 0);
- if (!config_get_int ("SHELL_RUN", &SHELL_RUN)) {
- SHELL_RUN = 1;
- }
- // don't show files starting with "." by default
- if (!config_get_int ("ShowDotFiles", &(GTK_COMPLETION_LINE(compline)->show_dot_files))) {
- GTK_COMPLETION_LINE(compline)->show_dot_files = 0;
- }
- int tmp;
- if (!config_get_int ("TabTimeout", &tmp)) {
- ((GtkCompletionLine*)compline)->tabtimeout = tmp;
- }
- if (!config_get_int ("USE_GLIB_XDG", &USE_GLIB_XDG)) {
- USE_GLIB_XDG = 0;
- }
- g_signal_connect(G_OBJECT(compline), "cancel",
- G_CALLBACK(gmrun_exit), NULL);
- g_signal_connect(G_OBJECT(compline), "activate",
- G_CALLBACK (on_compline_activated), NULL);
- g_signal_connect(G_OBJECT(compline), "runwithterm",
- G_CALLBACK (on_compline_runwithterm), NULL);
- g_signal_connect(G_OBJECT(compline), "unique",
- G_CALLBACK (on_compline_unique), NULL);
- g_signal_connect(G_OBJECT(compline), "notunique",
- G_CALLBACK (on_compline_notunique), NULL);
- g_signal_connect(G_OBJECT(compline), "incomplete",
- G_CALLBACK (on_compline_incomplete), NULL);
- g_signal_connect(G_OBJECT(compline), "search_mode",
- G_CALLBACK (on_search_mode), NULL);
- g_signal_connect(G_OBJECT(compline), "search_not_found",
- G_CALLBACK (on_search_not_found), NULL);
- g_signal_connect(G_OBJECT(compline), "search_letter",
- G_CALLBACK(on_search_letter), label_search);
- g_signal_connect(G_OBJECT(compline), "ext_handler",
- G_CALLBACK (on_ext_handler), NULL);
- int shows_last_history_item;
- if (!config_get_int ("ShowLast", &shows_last_history_item)) {
- shows_last_history_item = 0;
- }
- if (gmrun_text) {
- gtk_entry_set_text (GTK_ENTRY(compline), gmrun_text);
- } else if (shows_last_history_item) {
- gtk_completion_line_last_history_item (GTK_COMPLETION_LINE(compline));
- }
- // geometry: window position
- if (window_geom.x > -1 || window_geom.y > -1) {
- gtk_window_move (GTK_WINDOW (dialog), window_geom.x, window_geom.y);
- } else {
- /* default: centered */
- gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ALWAYS);
- }
- // geometry: window size
- if (window_geom.height > -1 || window_geom.width > -1) {
- gtk_window_set_default_size (GTK_WINDOW (dialog), window_geom.width,
- window_geom.height);
- } else {
- /* default width = 450 */
- gtk_window_set_default_size (GTK_WINDOW (dialog), 450, -1);
- }
- // window icon
- GError * error = NULL;
- GtkIconTheme * theme = gtk_icon_theme_get_default ();
- GdkPixbuf * icon = gtk_icon_theme_load_icon (theme, "gmrun", 48, GTK_ICON_LOOKUP_USE_BUILTIN, &error);
- if (error) {
- g_object_set (dialog, "icon-name", "gtk-execute", NULL);
- g_error_free (error);
- } else {
- gtk_window_set_icon (GTK_WINDOW (dialog), icon);
- g_object_unref (icon);
- }
- gtk_widget_show_all (dialog);
- gtk_window_set_focus(GTK_WINDOW(dialog), compline);
- }
- // =============================================================
- static void parse_command_line (int argc, char ** argv)
- {
- // --geometry / parse commandline options
- static char *geometry_str = NULL;
- GError *error = NULL;
- GOptionContext *context = NULL;
- static GOptionEntry entries[] =
- {
- { "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry_str, "Bu seçenek, pencerenin başlangıç boyutunu ve konumunu belirtir.", NULL, },
- { NULL },
- };
- context = g_option_context_new (NULL);
- g_option_context_add_main_entries (context, entries, NULL);
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
- if (!g_option_context_parse (context, &argc, &argv, &error))
- {
- g_print ("seçenek ayrıştırılamadı: %s\n", error->message);
- if (context) g_option_context_free (context);
- if (error) g_error_free (error);
- if (geometry_str) g_free (geometry_str);
- exit (1);
- }
- if (context) g_option_context_free (context);
- if (error) g_error_free (error);
- if (argc >= 2) {
- gmrun_text = argv[1];
- }
- // --
- if (!geometry_str)
- {
- // --geometry was not specified, see config file
- char * geomstr;
- if (config_get_string ("Geometry", &geomstr)) {
- geometry_str = g_strdup (geomstr);
- }
- }
- if (geometry_str)
- {
- // --geometry WxH+X+Y
- // width x height + posX + posY
- int width, height, posX, posY;
- char *Wstr, *Hstr, *Xstr, *Ystr;
- Wstr = Hstr = Xstr = Ystr = NULL;
- Xstr = strchr (geometry_str, '+');
- if (Xstr) { // +posX+posY
- *Xstr = 0;
- Xstr++; // posX+posY
- Ystr = strchr (Xstr, '+');
- if (Ystr) { // +posY
- *Ystr = 0;
- Ystr++; // posY
- }
- }
- if (Xstr && Ystr && *Xstr && *Ystr) {
- posX = strtoll (Xstr, NULL, 0);
- posY = strtoll (Ystr, NULL, 0);
- ///fprintf (stderr, "x: %" G_GINT64_FORMAT "\ny: %" G_GINT64_FORMAT "\n", posX, posY);
- window_geom.x = posX;
- window_geom.y = posY;
- }
- Hstr = strchr (geometry_str, 'x');
- if (Hstr) { // WxH
- *Hstr = 0;
- Hstr++; // H
- Wstr = geometry_str;
- width = strtoll (Wstr, NULL, 0);
- height = strtoll (Hstr, NULL, 0);
- ///fprintf (stderr, "w: %" G_GINT64_FORMAT "\nh: %" G_GINT64_FORMAT "\n", width, height);
- window_geom.width = width;
- window_geom.height = height;
- }
- g_free (geometry_str);
- }
- }
- // =============================================================
- // MAIN
- void gmrun_exit(void)
- {
- gtk_widget_destroy (compline);
- config_destroy ();
- g_application_quit (G_APPLICATION (gmrun_app));
- }
- int main(int argc, char **argv)
- {
- #ifdef MTRACE
- mtrace();
- #endif
- int status = 0;
- config_init ();
- parse_command_line (argc, argv);
- #if GTK_CHECK_VERSION(3, 4, 0)
- // Handling cmd line args with GApplication is a nightmare
- // follow this: https://developer.gnome.org/gtkmm-tutorial/stable/sec-multi-item-containers.html.en#boxes-command-line-options
- argc = 1; /* hide args from GApplication */
- gmrun_app = gtk_application_new ("org.gtk.gmrun", G_APPLICATION_NON_UNIQUE);
- g_signal_connect (gmrun_app, "activate", gmrun_activate, NULL);
- status = g_application_run (G_APPLICATION (gmrun_app), argc, argv);
- g_object_unref (gmrun_app);
- #else
- gtk_init (&argc, &argv);
- gmrun_activate ();
- gtk_main ();
- #endif
- #ifdef MTRACE
- muntrace();
- #endif
- return (status);
- }
|