Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebinding default tk keys does not work #62

Open
tastyminerals opened this issue Oct 12, 2020 · 9 comments
Open

Rebinding default tk keys does not work #62

tastyminerals opened this issue Oct 12, 2020 · 9 comments

Comments

@tastyminerals
Copy link
Contributor

tastyminerals commented Oct 12, 2020

I posted this issue on dlang forum first but since nobody seems to have an answer I created an issue here.

I want to rebind <Control-a> to select all text in the Entry widget, it doesn't work

private void selectText(CommandArgs args) {
    this._clientId.selectText;
}

this._loginFrame = new Frame(2, ReliefStyle.groove);
this._clientId = new Entry(this._loginFrame).grid(1, 0);
this._clientId.bind("<Control-a>", &selectText);

It works if I change <Control-a> to <Control-o> for example.

@nomad-software
Copy link
Owner

What about <Control-Key-a>?

@tastyminerals
Copy link
Contributor Author

tastyminerals commented Oct 12, 2020

Nope, doesn't work.
However, if I do the following:

private void selectText(CommandArgs args) {
    this._clientId.selectText;
    this._clientPass.selectText; // <-- added selectText for client password Entry
}

this._loginFrame = new Frame(2, ReliefStyle.groove);
this._clientId = new Entry(this._loginFrame).grid(0, 0);
this._clientId.bind("<Control-a>", &selectText);
this._clientPass = new Entry(this._loginFrame).grid(0, 1); // <-- added client password Entry

Somehow, when I hit <Control-a> while being in the client id Entry widget, the client password Entry widget gets its text selected and client id widget moves the cursor to the start of the Entry (default Tk behavior) 😮

Here is a screenshot:

2020-10-12-215753_252x106_scrot

@nomad-software
Copy link
Owner

Hmmm... strange. I might take a closer look at this tomorrow when I have more time. It looks like it should work, without seeing the rest of your program it's hard to tell though. Try creating a small standalone full program to test to rule out something else interfering with it.

@tastyminerals
Copy link
Contributor Author

tastyminerals commented Oct 12, 2020

I've only just started so there isn't much code, here is a test sample:

import std.stdio;
import std.format;
import tkd.tkdapplication;

class App : TkdApplication
{

	private Frame _loginFrame;
	private Entry _clientId;
	private Entry _clientPassword;
	private string[string] credentials;

	private void exitApplication(CommandArgs args)
	{
		this.exit();
	}

	private void youForgotMsg(string msg)
	{
		auto youForgot = new MessageDialog(this.mainWindow, "Error").setIcon(MessageDialogIcon.warning)
			.setMessage("Ooops!").setDetailMessage("You forgot %s!".format(msg)).show;
	}

	private void selectText(CommandArgs args)
	{
		this._clientId.selectText;
		this._clientPassword.selectText;
	}

	private void getClientCredentials(CommandArgs args)
	{

		if (!this._clientId.getValue)
		{
			this.youForgotMsg("client Id");
		}
		else if (!this._clientPassword.getValue)
		{
			this.youForgotMsg("client password");
		}
		else
		{
			this.credentials["client_id"] = this._clientId.getValue;
			this.credentials["client_password"] = this._clientPassword.getValue;
			this._loginFrame.destroy;
		}
	}

	private void createClientLoginWindow(int outerPadding)
	{
		// Create client login frame
		this._loginFrame = new Frame(2, ReliefStyle.groove);
		auto label1 = new Label(this._loginFrame, "Client ID").grid(0, 0);
		this._clientId = new Entry(this._loginFrame).grid(1, 0, 5);
		this._clientId.bind("<Return>", &getClientCredentials);
		this._clientId.bind("<Control-a>", &selectText);
		auto label2 = new Label(this._loginFrame, "Password").grid(0, 1);
		this._clientPassword = new Entry(this._loginFrame).grid(1, 1, 5);
		this._clientPassword.bind("<Return>", &getClientCredentials);
		//this._clientPassword.bind("<Control-a>", &selectText);
		this._loginFrame.grid(0, 0, outerPadding);
	}

	override protected void initInterface()
	{
		this.mainWindow.setTitle("Tester");
		this.mainWindow.setMinSize(300, 200);
		this.mainWindow.setProtocolCommand(WindowProtocol.deleteWindow, delegate(CommandArgs args) {
			this.exitApplication(args);
		});

         	this.createClientLoginWindow(10);
	}

}

void main()
{
	auto app = new App();
	app.run;
}

@nomad-software
Copy link
Owner

I've taken a look and i'm stumped. It looks like the callback is firing correctly but the selection is failing for some reason. There also looks to be another binding for <Control-a> on the Entry because it places the cursor at the start of the text when triggered. I'm out of ideas.

@tastyminerals
Copy link
Contributor Author

tastyminerals commented Oct 13, 2020

I've taken a look and i'm stumped. It looks like the callback is firing correctly but the selection is failing for some reason. There also looks to be another binding for <Control-a> on the Entry because it places the cursor at the start of the text when triggered. I'm out of ideas.

Yep. Tk has its own default bindings and <Control-a> puts cursor to the beginning while <Control-/> selects text.
The same behaviour in Python Tkinter and I don't remember if you can rebind there either.
I have found this so post.

@tastyminerals
Copy link
Contributor Author

tastyminerals commented Oct 13, 2020

I found my old Tkinter code that tackles this problem. I am going to try this with D tomorrow.

    def ctrl_a(self, callback=False):
        """
        Select all in entry or text widget.
        Overwrite tkinter default 'ctrl+/' keybind.
        """
        # checking which text widget has focus
        if self.Entry is self.focus_get():
            self.Entry.select_range(0, 'end')
        elif self.Text is self.focus_get():
            self.Text.tag_add('sel', '1.0', 'end')
        return 'break'
# (...)
self.Entry.bind('<Control-a>', self.ctrl_a)

@tastyminerals
Copy link
Contributor Author

Well, I was overly optimistic about it. It's not possible because .bind expects void function. I guess it's a bug then.

@nomad-software
Copy link
Owner

I'm going to archive this repository as it's not supported by me anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants